путь к большому использованию распределяемых массивов.
Если данные помещаются в памяти, вы можете это сделать. Я проверил это, файл
header(1)
header(2)
header(3)
block(1).data1 block(1).data2 block(1).data3
block(1).data4 block(1).data5 block(1).data6
block(2).data1 block(2).data2 block(2).data3
block(2).data4 block(2).data5 block(2).data6
...
block(9999998).data1 block(9999998).data2 block(9999998).data3
block(9999998).data4 block(9999998).data5 block(9999998).data6
block(9999999).data1 block(9999999).data2 block(9999999).data3
block(9999999).data4 block(9999999).data5 block(9999999).data6
с размером файла 1,2 ГБ можно было бы изменить с помощью этого небольшого скрипта awk:
#!/usr/bin/awk
# if line contains word "header", print immediately, move on to next line.
/header/ {print; next}
# move every line to memory.
{
line[n++] = $0
}
# When finished, print them out in order n-1, n, n-3, n-2, n-5, n-4, ...
END {
for (i=n-2; i>=0; i-=2) {
print(line[i])
print(line[i+1])
}
}
менее чем за 2 минуты.
Если это действительно невозможно, вам нужно сделать то, что сказал @high-performance-mark, и прочитать его в управляемых блоках, перевернуть его в памяти, а затем объединить их вместе в конце. Вот моя версия:
program reverse_order
use iso_fortran_env, only: IOSTAT_END
implicit none
integer, parameter :: max_blocks_in_memory = 10000
integer, parameter :: max_line_length=100
character(len=max_line_length) :: line
character(len=max_line_length) :: data(2, max_blocks_in_memory)
character(len=*), parameter :: INFILE='data.txt'
character(len=*), parameter :: OUTFILE='reversed_data.txt'
character(len=*), parameter :: TMP_FILE_FORMAT='("/tmp/", I10.10,".txt")'
character(len=len("/tmp/XXXXXXXXXX.txt")) :: tmp_file_name
integer :: in_unit, out_unit, tmp_unit
integer :: num_headers, i, j, tmp_file_number
integer :: ios
! Open the input and output files
open(newunit=in_unit, file=INFILE, action="READ", status='OLD')
open(newunit=out_unit, file=OUTFILE, action='WRITE', status='REPLACE')
! Transfer the headers to the output file immediately.
num_headers = 0
do
read(in_unit, '(A)') line
if (index(line, 'header') == 0) exit
num_headers = num_headers + 1
write(out_unit, '(A)') trim(line)
end do
! We've already read the first data line, so let's rewind and start anew.
rewind(in_unit)
! move past the headers.
do i = 1, num_headers
read(in_unit, *)
end do
tmp_file_number = 0
! Read the data from the input line max_blocks_in_memory blocks at a time.
read_loop : do
do i = 1, max_blocks_in_memory
read(in_unit, '(A)', iostat=ios) data(1, i)
if (ios == IOSTAT_END) then ! Reached the end of the input file.
if (i > 1) then ! Still have final values in memory, write them
! to output immediately.
do j = i-1, 1, -1
write(out_unit, '(A)') trim(data(1, j))
write(out_unit, '(A)') trim(data(2, j))
end do
end if
exit read_loop
end if
read(in_unit, '(A)') data(2, i)
end do
! Reasd a block of data, write it in reverse order into a temporary file.
tmp_file_number = tmp_file_number + 1
write(tmp_file_name, TMP_FILE_FORMAT) tmp_file_number
open(newunit=tmp_unit, file=tmp_file_name, action="WRITE", status="NEW")
do j = max_blocks_in_memory, 1, -1
write(tmp_unit, '(A)') data(1, j)
write(tmp_unit, '(A)') data(2, j)
end do
close(tmp_unit)
end do read_loop
! Finished with input file, don't need it any more.
close(unit=in_unit)
! Concatenate all the temporary files in reverse order to the output file.
do j = tmp_file_number, 1, -1
write(tmp_file_name, TMP_FILE_FORMAT) j
open(newunit=tmp_unit, file=tmp_file_name, action="READ", status="OLD")
do
read(tmp_unit, '(A)', iostat=ios) line
if (ios == IOSTAT_END) exit
write(out_unit, '(A)') trim(line)
end do
close(tmp_unit, status="DELETE") ! Done with this file, delete it after closing.
end do
close(unit=out_unit)
end program reverse_order
person
chw21
schedule
16.07.2018
out-of-memory
? Насколько велик этот файл? - person Ross   schedule 13.07.20181..n
, гдеn
определяется размером вашей рабочей памяти. Запишите их в «обратном» порядке к временному файлу 1. Повторяйте, пока у вас не будет куча временных файлов, объедините их в правильном порядке. - person High Performance Mark   schedule 13.07.2018