fortran open使用

1)--------------------------------------------------------------------------------------
FOR的輸出分 有格式form = 'formatted'、無格式form = 'unformatted'兩種,前者是默認輸出格式,即如果open語句裏不聲明form的話,那就是formatted。
無格式又分 直接存取access = 'direct'、間接存取access = 'seuqential' 兩種,後者是無格式文件的默認格式。
幾個open示例:
有格式文件:
    open( 1, file = '...', status = 'new', form = 'formatted' )
    或者
    open( 1, file = '...', status = 'old')
無格式/順序文件:
    open( 1, file = '...', status = 'new', form = 'unformatted', access = 'sequential' )
    或者
    open( 1, file = '...', status = 'new', form = 'unformatted' )
無格式/直接文件:
    open( 1, file = '...', status = 'new', form = 'unformatted', access = 'direct', recl = ... )


2)--------------------------------------------------------------------------------------
如果是向 有格式文件 輸出,則write語句可以寫成:表控格式,如write( 1,* ) var; 或者顯式說明格式,如write( 1,'(5i2)' ) var
如果是向 無格式/順序文件 輸出,則write語句應寫成: write( 1 ) var
如果是向 無格式/直接文件 輸出,則write語句應寫成: write( 1, rec = k ) var


3)--------------------------------------------------------------------------------------
對於 無格式/直接文件 , open中的recl指明瞭一個輸出記錄的長度。它具體等於多少要看輸出write語句如何寫,同時write語句中的記錄號rec也要寫正確。
比如有一個m(20,30)的二維數組,可以有如下幾種寫法(注意recl, rec, m的變化):
a) 把整個數組看作一個記錄(1個記錄,1個記錄長度20*30):
open ( 1, file = '...', status = 'new', form = 'unformatted', access = 'direct', recl = 20*30 )
write( 1, rec = 1 ) m
b) 把一行看作一個記錄(20個記錄,1個記錄長度30):
open ( 1, file = '...', status = 'new', form = 'unformatted', access = 'direct', recl = 30 )
do k = 1, 20
  write( 1, rec = k ) ( m( k, p ), p = 1, 30 )
end do
c) 把一個數組元素看作一個記錄(20*30個記錄,1個記錄長度1):
open ( 1, file = '...', status = 'new', form = 'unformatted', access = 'direct', recl = 1 )
k = 0
do i = 1, 20
   do j = 1, 30
      k = k + 1
      write( 1, rec = k ) m( i, j )
或者
      write( 1, rec = (i-1)*30+j ) m( i, j )
   end do
end do

順說一句,二維數組是先存列再存行的,所以上述a)打印m元素的順序與c)不同,而與下述d)相同
d) 把一個數組元素看作一個記錄:
open ( 1, file = '...', status = 'new', form = 'unformatted', access = 'direct', recl = 1 )
k = 0
do j = 1, 30
   do i = 1, 20
      k = k + 1
      write( 1, rec = k ) m( i, j )
或者
      write( 1, rec = (j-1)*20+i ) m( i, j )
   end do
end do

在一些舊的FOR編譯器中(比如Fortran PowerStation 4.0),對recl解釋成字長而非字節,因此還需要將recl乘以4才能正確讀取。現在常用的CVF編譯器已不需要這樣做。
PS:你的33個數據可能並沒有分放在3行半上。可能只是記事本查看的原因,當一屏顯示不下時自動換行顯示,但數據可能還是在一行上。所以要讀取的話可試試直接寫成:
write( 1, * ) ( m( k ), k = 1, 33 )
如果m一開始就聲明成一個只有33個元素的數組,則也可寫成
write( 1, * ) m

4)--------------------------------------------------------------------------------------
二進制存放的數據還有一個反位的問題。一般在UNIX機上是二進制數是高位結束,在WIN和LINUX中是低位結束(沒記錯的話)。如果讀數時出現很大的怪數,比如1.e+35之類,或者執行時顯示讀取文件到末尾,或者是記錄不夠長,並且你又確定程序沒錯,那麼多半是反位問題的原因。
這時如果你用的編譯器有反位選項,可以加上,比如ifort編譯器可以寫:
ifort -convert big_endian xxx.f90  或
ifort -convert little_endian xxx.f90
也可以直接在FOR程序的OPEN語句中說明,比如:
open( 1, file='...', form='unformatted', access='direct', recl=..., convert='big_endian' )

open( 1, file='...', form='unformatted', access='direct', recl=..., convert='little_endian' )
big_endian 適用於在本地PC讀取UNIX服務器上生成的二進制數據。
little_endian適用於在UNIX服務器讀取本地PC生成的二進制數據。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章