gpt4 book ai didi

fortran - 在 Fortran 中将原始二进制文件读入数组的 EOF 处理

转载 作者:行者123 更新时间:2023-12-05 04:36:30 24 4
gpt4 key购买 nike

我正在尝试编写 Fortran 代码,以 64 字节的 block 读取原始二进制文件 [例如 .png],对其执行一些操作,然后可能将其写入另一个文件。目前为止我写的代码如下,是借助this SO answer写的:

        integer(kind = int8), dimension(0:63) :: file_read_buffer
integer :: input_file_handle
integer :: io_error

open(newunit=input_file_handle, file=input_file_name, status="old", access="stream", action="read", iostat=io_error)
if(io_error /= 0) then
! file didn't open properly
end if

do
read(unit = input_file_handle, iostat = io_error) file_read_buffer
select case(io_error)
case(0)
! consume buffer normally
case(iostat_end)
! do EOF processing
case default
! error!
end select
end do

如果在数组完全填满之前就达到了 EOF,有没有办法知道在达到 EOF 之前填充了多少?此外,如果引发一次 EOF,对 read() 的进一步调用是否也会返回 EOF?

如果有帮助,我目前正在使用 gfortran。

最佳答案

如果文件结束条件是由该输入语句引起的,则您无法确定该输入语句读取了多少内容。

但是,由于您的意图是使用该输入大小来处理缓冲区中已填充的部分,所以这不是问题:您 cannot do that .也就是说,当触发文件结束条件时,您的整个缓冲区将变为未定义。

相反,您应该丢弃整个缓冲区并重新处理输入。您有两个选择:

  • 如果到达文件末尾,重新定位到文件末尾并读取更少的数据
  • 确定剩余的数据量,如果可用的数据较少,则减少读取(避免文件结束条件)

首先,如果您跟踪“成功”位置,则可以在失败时重新定位:

! Read full-sized chunks
do
read(unit, iostat=iostat) buffer
if (iostat==iostat_end) exit
inquire (unit, pos=file_pos)
end do

! reposition
read (unit, pos=pos)

! Read smaller chunks
do
read (unit, iostat=iostat) buffer(1)
if (iostat==isotat_end) exit
end

(处理在明显的地方进行。)这类似于 this other answer 中的想法。一个相关的问题。

对于第二个,使用文件位置及其大小我们可以查看是否有足够的“文件存储单元”来填充我们的缓冲区:

inquire (unit, size=file_size)
do
inquire (unit, pos=file_pos)
remaining = (file_size-file_pos+1)*FILE_STORAGE_SIZE/STORAGE_SIZE(buffer)
if (remaining<SIZE(buffer)) exit
read (unit) buffer
end do
read (unit) buffer(:remaining)

FILE_STORAGE_SIZE 告诉我们有多少位组成一个文件存储单元,以及 STORAGE_SIZE 有多少位要存储(在内存中)一个元素数组的。

第二个选项可能没问题,但一般来说并不安全:我们不能确定存储大小为 16 位的元素对应于 16 位文件存储单元。不过,这可能足以满足您的目的。并且您始终可以创建一个测试文件来查看您的缓冲区占用了多少个文件存储单元。

关于fortran - 在 Fortran 中将原始二进制文件读入数组的 EOF 处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70839162/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com