有没有办法逐列将列写入文件?例如,我想写:
write(1,*) 1
write(1,*) 2
然后写(可能在另一个子程序中)
write(1,*) 3
write(1,*) 4
以这种方式生成格式为
的输出文件 1 3
2 4
没有组合数组(例如)
write(1,*) 1,3
write(1,*) 2,4
我认为可能有一种方法可以移动"指针" (文件位置)回到开头并添加空格或东西,但我真的不知道这是否可行。非常感谢任何帮助!
到目前为止,这是我尝试制作一个子程序来完成这项工作:
subroutine writeArrayToNthColumn(arr,u,n)
implicit none
real(dpn),dimension(:),intent(in),target :: arr
real(dpn),dimension(:),pointer :: parr
integer,intent(in) :: u,n
integer :: i,s
s = size(arr)
allocate(parr(s))
parr = arr
rewind(u)
if (n.eq.1) then
do i=1,s
write(u,'(1F20.10)') parr(i)
enddo
else
do i=1,s
write(u,'(1F40.10)') parr(i)
enddo
endif
end subroutine
但是第二次调用子程序时,第一列被删除了。
答案 0 :(得分:2)
以上乔治和高绩效标志的评论是完全正确的。我发布这个作为答案,因为它有源代码,但它应该被视为扩展注释,其唯一目的是证明它们是正确的。
从某种意义上说,可以执行此操作,但在任何情况下都不应该这样做。在文件中移动 - 所谓的seek - 是一项非常昂贵的操作。在本地硬盘驱动器上,每次操作可能需要10-20毫秒左右(例如,在这种情况下,每个条目);如果你使用的是大型共享系统,那么它可能会大得多。
然而,在内存中移动物品要便宜得多。经过良好调整的transpose函数将在缓存中进行大部分移动,操作需要几纳秒;数据将以较少的操作进入和从主存储器进行批量处理,每次操作大约需要100ns左右。即使是对现代SSD的追求也需要几十微秒的时间。
换句话说,在文件I / O中进行转置的情况不会比在内存中进行转置少 数百倍。 (如果需要,然后回来)。你仍然必须在最后做文件/ IO,但是如果你在一批中写出来,这要快得多。
让我们在Fortran中尝试一些例子,因为这是这个问题的语言。理所当然,Fortran使得难以直接访问文件位置,甚至在回车中显式输出,这使得这更难一些。我在这里使用direct-access IO并以非便携的方式硬编码进行回车。
这是在你的I / O中进行转置:
program badiotxt
implicit none
integer, parameter :: asize = 200
integer, dimension(asize, asize) :: a
integer :: i, j
integer :: record
forall (i=1:asize, j=1:asize)
a(i,j) = (i-1)*asize+j
end forall
open(unit=7,file="bad.txt", status="new", access="direct", &
form="formatted", action="write", recl=10)
do j=1,asize
do i=1,asize-1
record=(j-1)*asize+i
write(7, rec=record, fmt="(2X,I7,1X)") a(i,j)
enddo
enddo
i = asize
do j=1,asize
record=(j-1)*asize+i
write(7, rec=record, fmt="(1X,I7,A1,A1)") a(i,j), char(13), char(10)
enddo
close(7)
end program badiotxt
这是通过转置数组完成的:
program goodiotxt
implicit none
integer, parameter :: asize = 200
integer, dimension(asize, asize) :: a
integer :: i, j
integer :: record
forall (i=1:asize, j=1:asize)
a(i,j) = (i-1)*asize+j
end forall
open(unit=7,file="good.txt", status="new", &
form="formatted", action="write")
a = transpose(a)
do i=1,asize
write(7,fmt="(1X,200(2X,I7))") (a(i,j), j=1,asize)
enddo
a = transpose(a)
close(7)
end program goodiotxt
请注意,好的版本是更干净的代码,并且这些不是任何延伸的大型数组。由此产生的时间是:
答案 1 :(得分:2)
我现在比我第一次评论这个问题的时间多一点。然而,这是一个扩展的评论,而不是一个完整的答案。
即使是IF(这是一个很大的问题)我必须逐列编写一个数据文件,我不会使用直接访问IO,因为@Jonathan Dursi的答案提议。 (直接访问IO)适用于在编写代码时难以预测写入文件的顺序的情况。在OP的情况下,写入的顺序似乎完全可以预测。
我会:
2.1打开第二个文件写入,第一个文件用于阅读。
2.2从第一个文件中读取第一行,将其写入第二个文件并附加下一列的第一个元素。
2.3重复2.2直到我到达列/文件的末尾。
2.4关闭第二个文件(现在包含第1列和第2列)和第一个文件。
3.1打开第二个文件进行阅读,并对第一个文件执行破坏性打开以进行写入。
......到现在为止你应该得到了照片。