2013-07-30 41 views
0

我正在翻譯matlab腳本,它讀取一個二進制編碼的32位整數文件,並適當地解析它們。我寫了下面的方法旨在模仿MATLAB的FREAD()函數:文件意外地到達文件結尾

def readi(f,n):   
    x = zeros(n,int);  
    for i in range(0,n): 
     x[i] = struct.unpack('i',f.read(4))[0]; 
     print x[i]; 
    return x; 

我不同調用這個函數在我的腳本1和9之間的N作爲我分析出來的數據。我的問題是,該腳本只獲得一部分的方式進入文件之前,我得到這個錯誤:

x[i] = struct.unpack('i',f.read(4))[0]; 
struct.error: unpack requires a string argument of length 4 

看來,蟒蛇認爲我已經達到了文件的末尾。發生錯誤的執行點是循環中的一條線,已經迭代了好幾次。另外,已經解析過的文件的一小部分已經完全匹配我的matlab腳本從完全相同的文件(而不是副本)產生的內容。但是,Matlab能夠從文件中讀取更大的數據集。有沒有人有關於爲何發生此錯誤的想法?

+0

向我們展示打開文件對象的代碼。它是以文本模式而不是二進制模式打開的嗎? – agf

+0

這裏一個顯而易見的錯誤是您沒有定義輸入值的字節順序。另一件事是,結構模塊會告訴你需要多少字節,使用該信息來避免錯誤。 –

+0

您可以通過捕獲struct.error並打印f.tell()來進行完整性檢查。如果它打印的文件的大小,你知道這個問題不在這一點的代碼。 – tdelaney

回答

0

在我自己的測試中,無論文件是否以二進制模式打開(意外)都沒有關係。我可以建議的唯一的事情是確保您瞭解輸入文件的格式,正好是。因此,除了閱讀matlab腳本之外,查看文件的十六進制轉儲可能是一個好主意,您可以在其中查看原始數據的各個字節,並能夠驗證它是否符合您對其內容佈局的理解。

除了這一切,你可以試試你的readi()功能如下簡化/優化它不需要臨時x列表,並與讀取組中的所有整數的字節一個呼叫file.read()

def readi(f, n): 
    fmt = '%di' % n 
    return struct.unpack(fmt, f.read(struct.calcsize(fmt))) 

但是,我認爲它不會解決您的問題,因爲它應該等同於您已經在做的事情,無論如何都會返回價值(不會打印出與您一樣的任何內容)。

最後一個注意事項 - 你不需要用分號結束你的代碼行。 Python在這方面不像C和其他幾種語言。

+0

所有的好建議。我可以通過以二進制打開它來修復它。感謝您也簡化了我的readi功能。我確信有一個單線的方法,但我無法弄清楚。 – kjgregory

+0

是的,以二進制模式讀取文件是有道理的,這就是爲什麼我在我自己的(有限)測試中似乎並不重要時感到驚訝的原因。還要注意我對我的答案中的'readi()'函數所作的輕微修改/改進。 – martineau