2012-02-11 25 views

Trả lời

13

Nếu tập tin của bạn là đủ nhỏ mà bạn có thể đọc tất cả vào bộ nhớ mà bạn có thể sử dụng phân chia:

for line in f.read().split('\0'): 
    print line 

Nếu không, bạn có thể muốn thử công thức này từ các cuộc thảo luận về vấn đề này feature request:

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 

Tôi cũng nhận thấy tệp của bạn có đuôi "csv". Có một mô-đun CSV được tích hợp vào Python (nhập csv). Có một thuộc tính gọi là Dialect.lineterminator tuy nhiên nó hiện chưa được thực hiện trong người đọc:

Dialect.lineterminator

Các chuỗi được sử dụng để chấm dứt dòng được sản xuất bởi nhà văn. Nó mặc định là '\ r \ n'.

Lưu ý Đầu đọc được mã hóa cứng để nhận dạng '\ r' hoặc '\ n' là cuối dòng, và bỏ qua trình điều khiển lớp. Hành vi này có thể thay đổi trong tương lai.

+0

Tệp của tôi sẽ có vài nghìn đến vài nghìn dòng. – user1129812

+0

@ user1129812: Đường dài bao lâu? 100 byte? 100 byte * 50000 dòng = xấp xỉ. 5MB –

+0

Mỗi dòng phải có khoảng 100 ký tự. Giả sử unicode, mỗi dòng sẽ có khoảng 200 byte và một tệp 50000 dòng sẽ có khoảng 200 x 50000 = 9,54 MB. – user1129812

0

Tôi đã sửa đổi đề xuất của Mark Byers để chúng tôi có thể tệp READLINE với các dòng phân tách NUL bằng Python. Cách tiếp cận này đọc một dòng tệp có khả năng lớn theo dòng và nên có nhiều bộ nhớ hiệu quả hơn. Đây là mã Python (có nhận xét):

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() 

Hy vọng điều đó sẽ hữu ích.

Các vấn đề liên quan