2016-06-14 10 views
0

Mein CodeFortran Schreiben in binär: Fortran-Laufzeitfehler: Direkter Zugang Datenübertragung erfordert Rekordzahl

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 

Wie die Satzlänge angeben, ich habe nicht mit Fortran-Binärdateien für eine lange Zeit gearbeitet?. Was ich wirklich zu schreiben 601 (nx) int 25 (nz) mal in Binärdatei.Ich habe SizeOnnteger auf 32 geändert. Ich möchte 2D Array in Binärdatei schreiben, sollte einfach sein. Nach Vladimir Fs advise Ich habe mich verändert accesss zu streamen, aber das ist, was ich bekam 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 

Es 6200.Why sein sollte?

Antwort

0

Sie haben die Satzlänge bereits in Ihrer open-Anweisung angegeben (das recl Argument). Der Fehler beschwert sich tatsächlich über die write Anweisung. In Ihrer write Anweisung müssen Sie angeben, welcher Datensatz Sie schreiben, so dass Sie

do i=1,nx 
    write(36,rec=i)vel(i,:) 
end do 

Neben

Hinweis nutzen könnten, wie Sie unformatted das recl Argument gibt die Anzahl der Bytes pro Datensatz verwenden .

Die Anzahl der Bytes pro integer kann

sizeofinteger = storage_size(i)/8 

und Ihre Satzlänge dann recl=sizeofinteger*nz wäre unter Verwendung finden.

aktualisieren

Da das recl Argument ist nicht immer die Anzahl der Bytes in den Kommentaren von @IanH darauf hingewiesen wurde, ist es in der Tat Compiler abhängig. Wie in der Antwort von @VladimirF bemerkt, kann man die richtige recl Länge eine Laufzeit mit inquire ermitteln, um die iolength zu erhalten.

+0

ich mit Ihren Vorschlägen und sizeof integer 32 zusammenstellen können, aber Werte fremd sind in vel.mod, etwas ist falsch. Bearbeite meine Frage. –

+0

@RichardRublev Speichergröße ist die Anzahl der Bits. Sie wären wahrscheinlich besser mit Stream-Zugriff statt direkt sowieso. –

+0

@VladimirF Dank Ich habe die Teilung um 8 verpasst. Wie du sagst Stream ist wahrscheinlich der Weg zu gehen. –

2

Erst vor kurzem sagte ich in einer Antwort, dass die Menschen es nicht ausw direkt, aber immer noch so viele tun ... https://stackoverflow.com/a/37784431/721644

Verwenden inquire(iolength=myrecl) wie in diesem Link, und Sie werden viel mehr tragbar angeben sollen.

Wie dem auch sei, würde der Code viel einfacher mit Strom Zugang (resultierende Datei ist die gleiche):

open(unit=36, file='vel.mod', form='unformatted', access='stream') 
do i=1,nx 
    write(36) vel(i,:) 
end do 
close(36) 
+0

Ich habe Code mit Stream-Zugriff kompiliert, funktioniert immer noch nicht gut.Will erneut bearbeiten. –

+0

Ohne den Code zu sehen, kann niemand sagen, was falsch ist.Sie sollten sagen, was Ihr Datei-Dump bedeutet und warum Sie den erwarteten Wert erwarten. –