2010-12-13 24 views
10

docs Các Python trên file.read() trạng thái đó An empty string is returned when EOF is encountered immediately. Các tài liệu quốc gia hơn nữa:Python EOF cho các yêu cầu đa byte của file.read()

Lưu ý rằng phương pháp này có thể gọi cơ bản chức năng C fread() hơn hơn một lần trong nỗ lực thu được dưới dạng gần kích thước byte nhất có thể. Ngoài ra lưu ý rằng khi ở chế độ không chặn, ít dữ liệu hơn được yêu cầu có thể được trả về , ngay cả khi không có tham số kích thước được cung cấp.

Tôi tin rằng Guido đã đưa ra quan điểm của mình về việc không thêm f.eof() PERFECTLY CLEAR vì vậy cần sử dụng cách Python!

Điều không rõ ràng với ME, tuy nhiên, nếu đó là thử nghiệm cuối cùng bạn đã đạt EOF nếu bạn nhận được ít hơn byte được yêu cầu từ một lần đọc, nhưng bạn đã nhận được một số.

ví dụ:

with open(filename,'rb') as f: 
    while True: 
     s=f.read(size) 
     l=len(s) 
     if l==0: 
      break  # it is clear that this is EOF... 
     if l<size: 
      break  # ? Is receiving less than the request EOF??? 

Có một lỗi tiềm năng để break nếu bạn đã nhận được ít hơn các byte được yêu cầu trong một cuộc gọi đến file.read(size)?

Trả lời

21

Bạn chưa suy nghĩ với da rắn của bạn trên ... Python không phải là C.

Thứ nhất, bình luận:

  • st = f.read() đọc để EOF, hoặc nếu mở dưới dạng nhị phân, đến byte cuối cùng;
  • st = f.read (n) cố gắng để đọc n byte và trong mọi trường hợp không quá n byte;
  • st = f.readline() đọc một dòng tại một thời điểm, dòng kết thúc bằng '\ n' hoặc EOF;
  • st = f.readlines() sử dụng readline() để đọc tất cả các dòng trong một tệp và trả về danh sách các dòng.

Nếu phương pháp đọc tệp ở EOF, nó trả về ''. Cùng một loại kiểm tra EOF được sử dụng trong các phương pháp "tệp như" khác như StringIO, socket.makefile, v.v. Trả về ít hơn n byte từ f.read(n) là chắc chắn nhất KHÔNG phải là một thử nghiệm dispositive cho EOF! Trong khi mã đó có thể hoạt động 99 .99% thời gian, đó là thời gian nó không hoạt động mà sẽ rất bực bội để tìm. Ngoài ra, nó là hình thức Python xấu. Việc sử dụng duy nhất cho n trong trường hợp này là để đặt một giới hạn trên về kích thước của sự trở lại.

Một số lý do khiến các phương thức giống như tệp Python trả về ít hơn hơn n byte?

  1. EOF chắc chắn là một lý do phổ biến;
  2. Ổ cắm mạng có thể hết giờ khi đọc nhưng vẫn mở;
  3. Chính xác n byte có thể gây gián đoạn giữa các ký tự nhiều byte logic (chẳng hạn như \r\n ở chế độ văn bản và, tôi nghĩ, một ký tự nhiều byte trong Unicode) hoặc một số cấu trúc dữ liệu cơ bản không được bạn biết;
  4. Tệp ở chế độ không chặn và quá trình khác bắt đầu truy cập tệp;
  5. Tạm thời không truy cập vào tệp;
  6. Điều kiện lỗi cơ bản, có khả năng tạm thời, trên tệp, đĩa, mạng, v.v.
  7. Chương trình nhận được tín hiệu, nhưng trình xử lý tín hiệu đã bỏ qua nó.

tôi sẽ viết lại mã của bạn theo cách này:

with open(filename,'rb') as f: 
    while True: 
     s=f.read(max_size) 
     if not s: break 

     # process the data in s... 

Hoặc, viết một generator:

def blocks(infile, bufsize=1024): 
    while True: 
     try: 
      data=infile.read(bufsize) 
      if data: 
       yield data 
      else: 
       break 
     except IOError as (errno, strerror): 
      print "I/O error({0}): {1}".format(errno, strerror) 
      break 

f=open('somefile','rb') 

for block in blocks(f,2**16): 
    # process a block that COULD be up to 65,536 bytes long 
+1

"chẳng hạn như \ r \ n ở chế độ nhị phân" <- điều này có nói "chế độ văn bản" thay vì "chế độ nhị phân" không? Ở chế độ nhị phân, nó sẽ chỉ là một cặp byte giống như bất kỳ byte nào khác, đúng không? –

1

Đây là những gì tài liệu trình biên dịch C của tôi nói cho fread() chức năng:

size_t fread( 
    void *buffer, 
    size_t size, 
    size_t count, 
    FILE *stream 
); 

fread trả về số các mặt hàng đầy đủ thực sự đọc, mà có thể ít hơn đếm nếu một lỗi xảy ra hoặc nếu kết thúc số của tệp trước khi số được tính.

Vì vậy, nó trông giống như nhận được ít hơn size phương tiện hoặc là một lỗi đã xảy ra hoặc EOF đã đạt được - vì vậy break ing ra khỏi vòng lặp sẽ là điều đúng để làm.

+0

Đây không phải là chính xác, một tín hiệu có thể gây ra một đọc ngắn gây byte ít được trả lại ... mà không chính xác là một EOF. – Lekensteyn

+0

@Lekensteyn: Tôi cho rằng nếu đọc ngắn xảy ra vì chương trình nhận được tín hiệu, nhưng trình xử lý tín hiệu bỏ qua nó, vòng lặp vẫn phải bị chấm dứt vì tín hiệu thường chỉ ra lỗi nghiêm trọng hoặc người dùng muốn ngắt quá trình - - Vì vậy, bất kể cho dù đó là một EOF chính xác hay không, phá vỡ ra khỏi vòng lặp là rất có thể là điều đúng để làm. – martineau

+0

Tôi đồng ý rằng nó là sane cho một xử lý tín hiệu để gây ra một đọc ngắn, nhưng tôi không đồng ý rằng nó là một điều kiện lỗi. Một trong các tập lệnh của tôi tiếp tục xử lý dữ liệu từ stdin cho đến EOF. 'SIGUSR1' được cấu hình để tuôn ra dữ liệu ngay lập tức, điều này gây ra một đọc ngắn được mong đợi và * không * một lỗi. – Lekensteyn

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