在Fortran中,如何通过从下到上的行块将文件从一个文件写回另一个文件 [英] In Fortran, how to write backward from a file to another file by blocks of line from bottom to top
问题描述
我有一个ASCII文件,看起来像:
I have an ASCII file that looks like:
____________________________________________
Header1 ...
Header2 ...
Header3 ...
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(n)data1 block(n)data2 block(n)data3
block(n)data4 block(n)data5 block(n)data6
____________________________________________
我想将其转换为如下所示的ASCII文件:
I would like to convert it into an ASCII file that looks like:
____________________________________________
HeaderA ...
HeaderB ...
block(n)data1 block(n)data2 block(n)data3
block(n)data4 block(n)data5 block(n)data6
block(n-1)data1 block(n-1)data2 block(n-1)data3
block(n-1)data4 block(n-1)data5 block(n-1)data6
....
block(1)data1 block(1)data2 block(1)data3
block(1)data4 block(1)data5 block(1)data6
____________________________________________
数据主要是实数,并且数据集的大小太大而无法使用可分配的数组.因此,我可以通过某种方式即时读写.
Data are mainly real numbers, and size of the data set is way too big to use allocatable arrays. So I have somehow to read and write on the fly.
我找不到在文件中向后读或写的方法.
I could not find a way to read-or-write backward in a file.
推荐答案
好吧,我有一个答案,但这没用,可能是由于编译器错误或我对Fortran中文件定位的基本了解.我的尝试是使用access = 'stream'
和form = 'formatted'
打开输入文件.这样,我可以将行位置推入堆栈,然后弹出它们,以便它们以相反的顺序出现.然后,以相反的顺序遍历这些行,我可以将它们写到ourput文件中.
Well, I sort of have an answer, but it didn't work, perhaps due to compiler bugs or my rudimentary understanding of file positioning in Fortran. My attempt was to open the input file with access = 'stream'
and form = 'formatted'
. This way I could push the line positions onto a stack and pop them off so they come out in reverse order. Then, walking through the lines in reverse order I could write them into the ourput file.
program readblk
implicit none
integer iunit, junit
integer i, size
character(20) line
type LLnode
integer POS
type(LLnode), pointer :: next => NULL()
end type LLnode
type(LLNODE), pointer :: list => NULL(), current => NULL()
integer POS, temp(2)
open(newunit=iunit,file='readblk.txt',status='old',access='stream',form='formatted')
open(newunit=junit,file='writeblk.txt',status='replace')
do i = 1, 3
do
read(iunit,'(a)',advance='no',EOR=10,size=size) line
write(junit,'(a)',advance='no') line
end do
10 continue
write(junit,'(a)') line(1:size)
end do
do
inquire(iunit,POS=POS)
allocate(current)
current%POS = POS
current%next => list
list => current
read(iunit,'()',end=20)
end do
20 continue
current => list
list => current%next
deallocate(current)
do while(associated(list))
temp(2) = list%POS
current => list%next
deallocate(list)
temp(1) = current%POS
list => current%next
deallocate(current)
do i = 1, 2
write(*,*) temp(i)
read(iunit,'(a)',advance='no',EOR=30,size=size,POS=temp(i)) line
write(junit,'(a)',advance='no') line
do
read(iunit,'(a)',advance='no',EOR=30,size=size) line
write(junit,'(a)',advance='no') line
end do
30 continue
write(junit,'(a)') line(1:size)
end do
end do
end program readblk
这是我的输入文件:
Header line 1
Header line 2
Header line 3
1a34567890123456789012345678901234567890
1b34567890123456789012345678901234567890
2a34567890123456789012345678901234567890
2b34567890123456789012345678901234567890
3a34567890123456789012345678901234567890
3b34567890123456789012345678901234567890
现在使用ifort
,我的文件位置被打印为
Now with ifort
my file positions were printed out as
214
256
130
172
44
88
请注意,第一行位于记录3的末尾,而不是记录4的开始.输出文件为
Note that the first line is at the end of record 3 instead of the beginning of record 4. The output file was
Header line 1
Header line 2
Header line 3
3a34567890123456789012345678901234567890
3b34567890123456789012345678901234567890
2a34567890123456789012345678901234567890
2b34567890123456789012345678901234567890
1a34567890123456789012345678901234567890
使用gfortran,文件位置打印为
With gfortran, the file positions printed out as
214
256
130
172
46
88
这一次,正如我所期望的,第一行位于记录4的开头.但是,输出文件中包含不幸的内容
This time the first line is at the beginning of record 4 as I would expect. However, the output file had unfortunate contents
Header line 1
Header line 2
Header line 3
3a34567890123456789012345678901234567890
3b34567890123456789012345678901234567890
2a34567890123456789012345678901234567890
2b34567890123456789012345678901234567890
3a34567890123456789012345678901234567890
3b345678901234567890123456789012341a34567890123456789012345678901234567890
我希望有一个更积极的结果.我无法确定结果是否是由于不良的编程或编译器错误所致,但我发布了消息,以防其他人可能使用我的纯Fortran解决方案.
I had hoped for a more positive result. I can't tell whether my results are due to poor programming or compiler bugs, but I posted in case someone else could possibly get my pure Fortran solution to work.
这篇关于在Fortran中,如何通过从下到上的行块将文件从一个文件写回另一个文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!