Reputation: 8172
My code
program v3
implicit none
real :: xmin,xmax,ymin,ymax,zmin,zmax,size
integer :: nx,ny,nz,i,j,nodestotal,sizeofinteger
real,dimension(:), allocatable :: v
integer,dimension(:), allocatable :: v1
integer,dimension(:,:), allocatable :: vel
sizeofinteger=2
open(unit=34, file='for.header', status='old')
read(34,115) xmin,xmax,ymin,ymax,zmin,zmax,size,nx,ny,nz
115 format(7f10.3,3i10)
nodestotal=nx*ny*nz
allocate (v(nodestotal))
allocate (v1(nodestotal))
allocate (vel(nx,nz))
open(unit=35, file='vel.txt', status='unknown')
read(35,*)v
v1=nint(v)
vel=reshape(v1,(/ nx, nz /) )
write(*,*)vel(:,25)
open(unit=36, file='vel.mod', form='unformatted', access='direct', recl=nx*nz*sizeofinteger)
do i=1,nx
write(36)vel(i,:)
end do
end program
How to specify the record length?I have not worked with FORTRAN binary files for a long time. What I really to write 601(nx) int 25(nz) times in binary file.I have changed sizeofinteger to 32.I want to write 2d array into binary file,should be simple. Following Vladimir F's advise I have changed to stream accesss,but this is what I got od -f vel.mod
1623500 8.688e-42 0 0 0
1623520 0 0 0 0
*
1625140 8.688e-42 0 0 0
1625160 0 0 0 0
*
1626600 8.688e-42 0 0 0
1626620 0 0 0 0
*
1630240 8.688e-42 0 0 0
1630260 0 0 0 0
*
1631700 8.688e-42 0 0 0
1631720 0 0 0 0
*
1633340 8.688e-42 0 0 0
1633360 0 0 0 0
*
1635000 8.688e-42 0 0 0
1635020 0 0 0 0
*
1636440 8.688e-42 0 0 0
1636460 0 0 0 0
*
1640100 8.688e-42 0 0 0
1640120 0 0 0 0
*
1641540 8.688e-42 0 0 0
1641560 0 0 0 0
*
1643200 8.688e-42 0 0 0
1643220 0 0 0 0
*
1644640 8.688e-42 0 0 0
1644660 0 0 0 0
*
1646300 8.688e-42 0 0 0
1646320 0 0 0 0
*
1647740 8.688e-42 0 0 0
1647760 0 0 0 0
*
1651400 8.688e-42 0 0 0
1651420 0 0 0 0
*
1653040
It should be 6200.Why?
Upvotes: 1
Views: 3024
Reputation: 854
You have already specified the record length in your open
statement (the recl
argument). The error is actually complaining about the write
statement. In your write
statement you need to specify which record you're writing, so you could use
do i=1,nx
write(36,rec=i)vel(i,:)
end do
Aside
Note, as you are using unformatted
the recl
argument specifies the number of bytes per record.
The number of bytes per integer can be found using
sizeofinteger = storage_size(i)/8
and your record length would then be recl=sizeofinteger*nz
.
Update
As has been pointed out in the comments by @IanH the recl
argument is not always the number of bytes, it is in fact compiler dependent. As noted in the answer by @VladimirF one may determine the correct recl
length an runtime using inquire
to get the iolength
.
Upvotes: 0
Reputation: 60018
Very recently I said in an answer that people should not specify recl directly, but still so many do it... https://stackoverflow.com/a/37784431/721644
Use inquire(iolength=myrecl)
as in that link and you will be much more portable.
Anyway, your code would be much simpler with stream access (resulting file is the same):
open(unit=36, file='vel.mod', form='unformatted', access='stream')
do i=1,nx
write(36) vel(i,:)
end do
close(36)
Upvotes: 4