文本大小与文件位置之间的关系

时间:2018-04-28 16:32:04

标签: matlab file

让我们假设我们有以下文本文件'badpoem.txt',其中包含以下句子

 whos
  Name        Size            Bytes  Class     Attributes

  ans         1x1                 8  double              
  fid         1x1                 8  double              
  tline1      1x19               38  char                
  tline2      1x19               38  char                
  tline3      1x23               46  char   

我确定每个句子的大小(以字节为单位)

fid = fopen('badpoem.txt');
ftell(fid)

ans = 0

其中tline1,tline2和tline3是对应的文本,现在当我打开文件并读取文本三次时,我检查了文件的当前位置,这是第一个的结果

tline1 = fgetl(fid)  % read the first line
ftell(fid)

tline1 =

    'Oranges and lemons,'


ans =

    21
 now lets read second file
tline2 = fgetl(fid)
ftell(fid)

tline2 =

    'Pineapples and tea.'


ans =

    42            

它正在打开,所以没关系,现在读取第一个文本

tline3 = fgetl(fid)
ftell(fid)

tline3 =

    'Orangutans and monkeys,'


ans =

    67

最后一个

{{1}}

文字大小和位置之间有什么关系吗?提前谢谢

2 个答案:

答案 0 :(得分:0)

对于文本文件,Windows在每行末尾添加两个字符,其他系统添加一个。 Matlab,当读取一行时会在返回的字符串中跳过这些,但由于Windows添加了两个而不是一个,因此Windows的位置值不同于Matlab示例中所示:

https://www.mathworks.com/help/matlab/ref/ftell.html

字符串保存在文件中,每个字符使用一个字节,但是作为16位字存储在Matlab的存储器中,或者每个字符存储2个字节,这使字符串的表观大小加倍。

答案 1 :(得分:0)

确实非常好的问题。实际上,我认为让你感到困惑的是你正在处理混合在一起的许多不同问题。让我们一个一个地分析它们。

1)Windows下的TXT文件格式

通常(亚洲语言环境和高级文本编辑器是常见的例外),Windows下的文本文件是ANSI编码的(其中ANSI是引用ISO/IEC 8859编码的通用方式)。在此编码框架内,从二进制的角度来看,每个字符由单个字节表示。如果您使用TXT打开此类Notepad个文件并在其中粘贴一些中文表意文字,这就是您在尝试保存更改时会看到的消息:

  

此文件包含Unicode格式的字符,如果将丢失   您将此文件保存为ANSI编码的文本文件。保持Unicode   信息,单击下面的取消,然后选择一个Unicode   “编码”下拉列表中的选项。继续?

2)Windows下的行分隔符

正如其他用户已经指出的那样,在Windows中,默认换行符由两个字符的组合表示:回车符(更好地称为\r0xD)和换行符(更好地称为\n0xA)。以下是基于您的文字的示例:

Oranges and lemons,\r\nPineapples and tea.\r\nOrangutans and monkeys,\r\nDragonflys or fleas.

Linux和MacOS等其他操作系统不会发生这种情况,只支持换行:

Oranges and lemons,\nPineapples and tea.\nOrangutans and monkeys,\nDragonflys or fleas.

3)在Matlab下存储字符串

Matlab将内存中的字符存储为Unicode 16位无符号整数,每个整数占用两个字节。这不依赖于当前的Matlab编码(可以检索执行命令feature('DefaultCharacterSet'),并且默认情况下对应于当前的操作系统编码)。

4)fgetl功能

根据official documentationfgetl函数从文件(信号,有效文件句柄)中读取一行,不包括换行符。这意味着Matlab会读取整行,包括所有换行符,但它们会从函数返回的输出字符串中删除。

fgetlfgets之间的区别在于前者修剪了换行符而后者没有。

所有这一切,让我们一步一步地分析代码中发生的事情。首先,打开文件,指针放在流的开头:

fid = fopen('data.txt','r');
ftell(fid) % 0

然后,你读了第一行:

tline1 = fgetl(fid)
ftell(fid) % 21

该行包含19字符(从whos表获得的大小),由于Unicode,使用38字节存储内存端。 ftell调用显示数字21,因为fgetl读取整行,其中包括已从输出中修剪的两个换行符(0 + 19 + 2 = 21)。

然后,你读了第二行:

tline2 = fgetl(fid)
ftell(fid) % 42

该行包含19个字符,内存端使用38个字节存储。 ftell调用显示数字42,因为fgetl读取整行,其中包括已从输出中修剪的两个换行符。从上一个偏移21 + 19 + 2 = 42

开始

最后,您阅读了第三行:

tline3 = fgetl(fid)
ftell(fid) % 67

该行包含23个字符,内存端使用46个字节存储。 ftell调用显示数字67,因为fgetl读取整行,其中包括已从输出中修剪的两个换行符。从上一个偏移42 + 23 + 2 = 67

开始