Matlab fwrite:跳过的字节会发生什么?

Matlab's fwrite: What happens to skipped bytes?

假设我有以下代码:

fid = fopen(my_filename,'w','ieee-le','ISO-8859-1');
fwrite(fid,1,'short',10,'ieee-le')

然后这将打开一个较早指定的文件,跳过前10个字节并将1写入后面的两个。

但是假设打开的文件之前不存在,前 10 个字节会发生什么?如果我要访问一个,我最终会得到什么,为什么?

在这类问题中,如果不是太复杂,最简单的方法通常是自己尝试一下。 现在您表示您正在使用 Linux,也许您可​​以在您的平台上重复测试并查看结果是否匹配。


对于Windows平台,skip值:

  • 实现之前要写入的第一个值
  • 似乎将每个跳过的字节保留为值 00(可能是 OS 为文件分配的新值)

示例:

此代码:

fid = fopen(my_filename,'w','ieee-le','ISO-8859-1');
fwrite(fid,1,'short',10,'ieee-le')
fclose(fid)

生成以下文件(在十六进制编辑器中看到):

如果您有多个值要写入:

fid = fopen(my_filename,'w','ieee-le','ISO-8859-1');
fwrite(fid,[1 2 3],'short',10,'ieee-le')
fclose(fid)

在您主动写入的每个 short 值之前,您仍然会得到 10x 00 个值:


新创建的文件就是这种情况。让我们看看现有文件发生了什么:

%% Let's create a file full of `FF`
FFarray = uint8(ones(36,1)*255) ;
fid = fopen(my_filename,'w','ieee-le','ISO-8859-1');
fwrite(fid,FFarray,'uint8')
fclose(fid)

给出:

现在使用与以前相同的代码(permission 设置为 w):

fid = fopen(my_filename,'w','ieee-le','ISO-8859-1');
fwrite(fid,[1 2 3],'short',10,'ieee-le')
fclose(fid)

是的,我们仍然得到同样的东西。现在这与您指定的权限的 MATLAB 文档一致:

w => 打开或创建新文件进行写入。 丢弃现有内容,如果有的话。

如果您只是将该权限更改为 r+打开文件进行读写。):

fid = fopen(my_filename,'r+','ieee-le','ISO-8859-1');
fwrite(fid,[1 2 3],'short',10,'ieee-le')
fclose(fid)

您只覆盖未跳过的值:

来自POSIX documentation

The fseek() function shall allow the file-position indicator to be set beyond the end of existing data in the file. If data is later written at this point, subsequent reads of data in the gap shall return bytes with the value 0 until data is actually written into the gap.

因此,假设 MATLAB 的 fwrite 使用 fseek 跳过 byes(这很有可能),那么超过文件末尾的跳过字节将在任何 POSIX 体系结构(Linux,MacOS)。 Windows就不一定了,POSIX就不一定了。

MacOS 上的快速测试证实了此行为:

fn = 'test.bin';
fid = fopen(fn,'wb');
fwrite(fid,1,'uchar',10);
fclose(fid);
fid = fopen(fn,'r');
fread(fid,Inf,'uchar')
fclose(fid);

输出:

ans =
     0
     0
     0
     0
     0
     0
     0
     0
     0
     0
     1