Привет, я новичок в Джулии и пытаюсь с ней кое-что обработать. У меня много файлов в двоичном формате. Я использую F90 для обработки. Файл, который я пишу, выглядит так
open(11,file = "ring.grid",form = "unformatted")
write(11)nv
write(11)Nx,Ny,Nzt
write(11) xx
write(11) yy
write(11) zz
close(11)
где nv,nx,ny,nzt — целые числа, а xx,yy,zz — трехмерная матрица. В F90 я использую этот простой блок для чтения файла
open(11,file='ring.grid',form='unformatted')
read(11)nd
read(11)n1,n2,n3
read(11)xx
read(11)yy
read(11)zz
close(11)
Но мне трудно читать это с Юлей. Кто-нибудь может мне помочь с этим? Спасибо
Я попробовал использовать
io=read(NAMEFILE)
y=Array{UInt8,1}(undef,1)
read!(io,y)
Но я не знаю, как разделить nv,n1,n2,n3,xx,yy,zz в разных массивах.
Возможно, проще всего вызвать какой-нибудь Фортран из Джулии, если вам нужно прочитать стандартные неформатированные файлы Фортрана.
Или вы можете посмотреть FortranFiles.jl traktofon.github.io/FortranFiles.jl/stable
Или, в более общем смысле, если вы хотите выполнить обмен данными, используйте формат файла обмена данными.
Предположим, что полный код F90 для записи данных выглядит следующим образом:
program SaveGrid
implicit none
integer :: nv
integer :: Nx, Ny, Nzt
real, dimension(:), allocatable :: xx, yy, zz
integer :: i
nv = 3
Nx = 5
Ny = 7
Nzt = 10
allocate(xx(Nx), yy(Ny), zz(Nzt))
do i = 1, Nx
xx(i) = float(i)
end do
do i = 1, Ny
yy(i) = float(i) * 2.0
end do
do i = 1, Nzt
zz(i) = float(i) * 3.0
end do
open(unit=11, file = "ring.grid", form = "unformatted")
write(11) nv
write(11) Nx, Ny, Nzt
write(11) xx
write(11) yy
write(11) zz
close(11)
deallocate(xx, yy, zz)
end program SaveGrid
Чтобы прочитать это в Julia, вам нужно обработать способ записи неформатированных данных F90.
function read_fortran_binary(filename)
open(filename, "r") do file
# Read record marker.
record_size = read(file, Int32)
# Read data.
nv = read(file, Int32)
# Read record marker.
end_record_size = read(file, Int32)
# Read record marker.
read(file, Int32)
# Read data.
Nx = read(file, Int32)
Ny = read(file, Int32)
Nzt = read(file, Int32)
# Read record marker.
read(file, Int32)
return nv, Nx, Ny, Nzt
end
end
nv, Nx, Ny, Nzt = read_fortran_binary("ring.grid")
println("nv: ", nv)
println("Nx: ", Nx)
println("Ny: ", Ny)
println("Nzt: ", Nzt)
Маркеры записей имеются как до, так и после каждого фрагмента данных, записанного в файл. Вам тоже нужно прочитать это. Очевидно, вам не нужно игнорировать эти данные, и размеры записей можно использовать, чтобы сделать ваш код Julia более надежным и гибким за счет изменений в неформатированных данных F90.
nv: 3
Nx: 5
Ny: 7
Nzt: 10
Вы делаете предположения о формате неформатированного файла Фортрана - нет никакой гарантии, что формат такой, как у вас выше, стандарт Фортрана ничего не говорит о том, как его следует реализовать. Разные компиляторы могут различаться, и известно, что разные версии одного и того же компилятора различаются. Вот почему я думаю, что вызов Фортрана для чтения, вероятно, лучший способ.
Я согласен с заявлением @IanBush. Двоичные файлы, которые предполагается читать на других языках, должны быть записаны с модификатором access = "stream"
, который подавляет маркеры записи.
Также есть модификации для записей >2 Гб.
WRT access = "stream"
Я думаю, было бы полезно, если бы ОП разъяснил их вариант использования: нужно ли читать множество существующих файлов, которые невозможно легко восстановить, или файлы легко перезаписываются или восстанавливаются в другом формате?
Двоичные файлы доступа к Фортрану
sequential
имеют специальный формат, который может не распознаваться другими языками. Открытие файла и запись с доступомstream
может помочь устранить ошибку. Найдите «поток программирования на Фортране IO».