2013-07-30 3 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 в моем сценарии я разобрать данные. Моя проблема заключается в том, что сценарий получает только часть пути в файл, прежде чем я получаю эту ошибку:

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

Вероятно, питон думает, что достиг конца файла. Точка, в которой происходит ошибка, представляет собой строку в цикле, которая уже была повторена несколько раз. Кроме того, небольшая часть файла, который был разобран, уже соответствует точно тому, что мой скрипт matlab создает из того же самого файла (а не копии). Однако Matlab способен читать гораздо больший набор данных из файла. Кто-нибудь есть идеи о том, почему эта ошибка происходит?

+0

Покажите нам код, в котором вы открываете файл. Открывается ли он в текстовом режиме, а не в двоичном режиме? – agf

+0

Одна вопиющая ошибка здесь заключается в том, что вы не определяете endianess входного значения. Другое дело, что модуль struct расскажет вам, сколько байтов вам нужно, используйте эту информацию, чтобы избежать ошибок. –

+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

Смежные вопросы