私は通常、次の Python コードを使用してファイルから行を読み取ります。
f = open('./my.csv', 'r')
for line in f:
print line
しかし、ファイルが「\n」ではなく「\0」で区切られた行である場合はどうですか? これを処理できる Python モジュールはありますか?
アドバイスをありがとう。
ファイルが十分に小さく、すべてをメモリに読み込むことができる場合は、分割を使用できます。
for line in f.read().split('\0'):
print line
それ以外の場合は、この機能リクエストに関するディスカッションからこのレシピを試してください。
def fileLineIter(inputFile,
inputNewline="\n",
outputNewline=None,
readSize=8192):
"""Like the normal file iter but you can set what string indicates newline.
The newline string can be arbitrarily long; it need not be restricted to a
single character. You can also set the read size and control whether or not
the newline string is left on the end of the iterated lines. Setting
newline to '\0' is particularly good for use with an input file created with
something like "os.popen('find -print0')".
"""
if outputNewline is None: outputNewline = inputNewline
partialLine = ''
while True:
charsJustRead = inputFile.read(readSize)
if not charsJustRead: break
partialLine += charsJustRead
lines = partialLine.split(inputNewline)
partialLine = lines.pop()
for line in lines: yield line + outputNewline
if partialLine: yield partialLine
また、ファイルの拡張子が「csv」であることにも気付きました。Python に組み込まれた CSV モジュールがあります (インポート csv)。と呼ばれる属性がありますが、Dialect.lineterminator
現在リーダーには実装されていません。
Dialect.lineterminator
ライターによって生成された行を終了するために使用される文字列。デフォルトは '\r\n' です。
注 リーダーは、'\r' または '\n' のいずれかを行末として認識するようにハードコードされており、lineterminator を無視します。この動作は将来変更される可能性があります。
Mark Byers の提案を修正して、Python で NUL 区切りの行を含む READLINE ファイルを作成できるようにしました。この方法では、潜在的に大きなファイルを 1 行ずつ読み取るため、メモリ効率が向上します。これがPythonコードです(コメント付き):
import sys
# Variables for "fileReadLine()"
inputFile = sys.stdin # The input file. Use "stdin" as an example for receiving data from pipe.
lines = [] # Extracted complete lines (delimited with "inputNewline").
partialLine = '' # Extracted last non-complete partial line.
inputNewline="\0" # Newline character(s) in input file.
outputNewline="\n" # Newline character(s) in output lines.
readSize=8192 # Size of read buffer.
# End - Variables for "fileReadLine()"
# This function reads NUL delimited lines sequentially and is memory efficient.
def fileReadLine():
"""Like the normal file readline but you can set what string indicates newline.
The newline string can be arbitrarily long; it need not be restricted to a
single character. You can also set the read size and control whether or not
the newline string is left on the end of the read lines. Setting
newline to '\0' is particularly good for use with an input file created with
something like "os.popen('find -print0')".
"""
# Declare that we want to use these related global variables.
global inputFile, partialLine, lines, inputNewline, outputNewline, readSize
if lines:
# If there is already extracted complete lines, pop 1st llne from lines and return that line + outputNewline.
line = lines.pop(0)
return line + outputNewline
# If there is NO already extracted complete lines, try to read more from input file.
while True: # Here "lines" must be an empty list.
charsJustRead = inputFile.read(readSize) # The read buffer size, "readSize", could be changed as you like.
if not charsJustRead:
# Have reached EOF.
if partialLine:
# If partialLine is not empty here, treat it as a complete line and copy and return it.
popedPartialLine = partialLine
partialLine = "" # partialLine is now copied for return, reset it to an empty string to indicate that there is no more partialLine to return in later "fileReadLine" attempt.
return popedPartialLine # This should be the last line of input file.
else:
# If reached EOF and partialLine is empty, then all the lines in input file must have been read. Return None to indicate this.
return None
partialLine += charsJustRead # If read buffer is not empty, add it to partialLine.
lines = partialLine.split(inputNewline) # Split partialLine to get some complete lines.
partialLine = lines.pop() # The last item of lines may not be a complete line, move it to partialLine.
if not lines:
# Empty "lines" means that we must NOT have finished read any complete line. So continue.
continue
else:
# We must have finished read at least 1 complete llne. So pop 1st llne from lines and return that line + outputNewline (exit while loop).
line = lines.pop(0)
return line + outputNewline
# As an example, read NUL delimited lines from "stdin" and print them out (using "\n" to delimit output lines).
while True:
line = fileReadLine()
if line is None: break
sys.stdout.write(line) # "write" does not include "\n".
sys.stdout.flush()
それが役に立てば幸い。