2015-04-09 6 views
0

У меня есть файл с форматированными данными, который обычно составляет миллиарды строк длиной, с несколькими строками заголовков переменной длины. Файл данных имеет вид: Fortran: Как пропустить много строк файла данных эффективно

 
    # header 1 
    # header 2 
    # headers are of variable length. 
    # data begins from next line. 
    1.23 4.56 7.89 0.12 
    2.34 5.67 8.90 1.23 
    : 
    : 
    # billions of lines of data, each row the same length, same format. 
    -- end of file -- 

Я хотел бы, чтобы извлечь часть данных из этого файла, и мой текущий код выглядит следующим образом:

<pre> 
do j=1,jmax !Suppose I want to extract jmax lines of data from the file. 

    [algorithm to determine number of lines to skip, "N(j)"] 
    !This determines the number of lines to skip from the previous file 
    !position, when the data was read on j-1th iteration. 

    !Skip N-1 lines to go to the next data line to read off: 
    do i=1,N-1 
    read(unit=unit,fmt='(A)') 
    end do 
    !Now read off the line of data I want: 
    read(unit=unit,fmt='(data_format)'),data1,data2,etc. 
    !Data is stored in some arrays. 
end do 
</pre> 

Проблема в том, N (к) может быть где-то между 1 и несколькими миллиардами, поэтому для запуска кода требуется некоторое время.

Мой вопрос: есть ли более эффективный способ пропускать миллионы строк данных? Единственный способ, которым я могу придумать, придерживаясь Fortran, - открыть файл с прямым доступом и перейти к нужной строке при открытии файла.

+0

Вы также можете открыть как поток, прочитать заголовок, а затем рассчитать позицию начала вашей линии. –

+0

Что написало файл? Какие соглашения нужно обрабатывать в терминах разделителей записей/символов строки? Может ли файл рассматриваться как неформатированный поток символьных данных с ACHAR (10) для окончаний строк? – IanH

+0

Файл является результатом другого кода. Цифры - это целые числа и double precisionrs, и они были записаны в файл с чем-то вроде: «write (unit = unit, fmt = '(I5, I4, ES12.4, ES16.8)'))», зацикливается как много раз, поскольку есть части данных. – benetianfish

ответ

0

Как вы предлагаете, прямой доступ кажется лучшим вариантом. Но это требует, чтобы записи для всех имели одинаковую длину, которую нарушают ваши заголовки. Кроме того, почему используется форматированный вывод? С файлом этой длины трудно представить человека, читающего файл. Если вы используете unformatted IO, файл будет меньше, а IO будет быстрее. Возможно, создайте два файла, один с заголовками (метаданные) в форме читателя для человека, а другой - с данными в нативной форме. Родное/двоичное представление означает потерю переносимости, что необходимо учитывать, если вы хотите переместить файлы на разные компьютерные архитектуры или использовать их в течение десятилетий. В противном случае это, вероятно, стоит того. Другие варианты состоят в использовании более сложного формата файла, который объединяет метаданные и данные, такие как HDF5 или FITS, но для связи между двумя программами одного человека, это, вероятно, чрезмерно.

+0

Спасибо за совет. То, что файл отформатирован, немного устарел с того момента, когда я впервые разработал свой основной код, а выходные данные были намного меньше. Теперь, вероятно, настало время рассмотреть возможность изменения его на двоичный вывод. – benetianfish

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