我们可以自己写一个EOFangular色吗?

大多数像C ++这样的语言写入文件时,即使我们错过写下如下语句,也会放置一个EOF字符:

filestream.close

然而,有没有什么办法,我们可以根据我们的要求把EOF字符放在C ++中。 或者除了使用C ++提供的function外,我们还可以使用其他方法。

如果你需要更多的信息,那么请发表评论。

提前致谢。

编辑:感谢您的支持,但这里是一个除了这个问题:

如果我们想欺骗操作系统并在文件中放置一个EOF字符,并在EOF之后写入一些数据,那么象notepad.exe这样的应用程序就不能在我们的EOF字符之后读取。 我已经阅读了与这个主题有关的问题的答案,并且已经知道现在的操作系统通常不会看到EOF字符,而是检查文件的长度以获得正确的了解文件长度的想法,但是,在那里必须是OS中的一个过程,它将检查文件的长度,然后更新文件logging。

我很抱歉,如果我在我的估计任何一点错误,但请帮助我,因为它可以导致许多新的想法。

没有EOF字符。 根据定义EOF“不等于任何有效的字符代码”。 通常是-1。 在任何时候都不会写入文件。

在DOS中有一个历史的EOF字符值(CTRL + Z),但是这些日子已经过时了。

要回答Apoorv的后续问题:操作系统从不使用文件数据来确定文件长度(文件不以任何方式“空终止”)。 所以你不能欺骗操作系统。 也许旧的,愚蠢的程序不会阅读后CTRL + Z字符。 我不会认为任何Windows应用程序(甚至记事本)都可以做到这一点。 我的猜测是用一个空( \0 )字符来欺骗它们会更容易一些。

那么, EOF只是C stdio.h头文件中定义的函数返回的值。 它实际上是由操作系统返回到所有的读取function,所以它的系统依赖。 当操作系统到达文件末尾时,它将它发送给函数,它的返回值比最常用的( -1 ),但并不总是。 所以,总结一下, EOF不是字符,而是操作系统返回的常量。 编辑:好吧,你需要更多地了解文件系统,看看这个。

嗨,对你的第二个问题:

再次,你应该更好地进入filesystems 。 FAT是非常好的例子,因为你可以find很多关于它的文章,它的原理和NTFS非常相似。 无论如何,EOF NOT a character 。 你不能直接放在文件中。 如果可以这样做,想象一下后果,即使是“哑”的图像文件也无法被系统读取。

为什么? Becouse OS的工作原理非常复杂。 其中一层是文件系统驱动程序。 它确保它从驱动程序已知的每个文件系统传输数据。 它提供了将应用程序和将文件存储到HDD的实际系统之间的桥梁。

确切地说,FAT文件系统使用所谓的FAT表 – 它是一个靠近HDD(或分区)地址空间开始的表,它包含所有簇(小存储单元)的映射。 OK,那么现在,当你想把一些文件保存到硬盘时,OS(文件系统驱动程序)查看FAT表,并search值“0x0”。 这个“0x0”值对操作系统说,群集哪个地址由FAT表中那个值的位置描述是可以自由写入的。

所以它写入文件的第一部分。 比起来,它在FAT中寻找另一个“0x0”值,如果find了,它将把文件的第二部分写入它指向的簇。 相比之下,它会将文件所在的第一个FAT表logging的值更改为文件第二部分中下一个的物理地址。

当您的文件全部存储在硬盘上时,现在出现最后一部分,它将所需的EOF值写入FAT表,而不是写入硬盘的“数据部分”。 所以当下一次读取文件时,它知道这是结束,不要再看了。

所以,现在你看,如果你想手动写入EOF值到它不属于的地方,你必须编写自己的驱动程序,这将能够重写FATlogging,但是这实际上是不可能的begginers。

在进行Kernighan&Ritchie C练习时,我来到了这里。

Ctrl + Dstdio.h发送与EOF常量相匹配的字符。

(编辑:这是在Mac OS X上;感谢@markmnl指出,Windows 10的等价物是Ctrl + Z

实际上在C ++中,没有使用fprintf()或ostream机制写入文件的物理EOF字符。 EOF是指示没有更多数据要读取的I / O条件。

一些像CP / M这样的早期的磁盘操作系统实际上使用物理的0x1A(ASCII字符)来表示EOF,因为文件系统只保持块的文件大小,所以你永远不知道文件的字节长度。 随着在目录中存储实际长度计数的出现,将“EOF”字符存储为“带内”文件数据的一部分不再是典型的。

没有像“EOF”字符那样的东西。 closuresstream本身的事实是“EOF”条件。

当你在unix shell中按下Ctrl + D时,只需closures标准inputstream,而后者又被shell识别为“EOF”,然后退出。

因此,要“发送”一个“EOF”,只需closures“EOF”需要发送的stream。

如果通过EOF字符表示Control-Z之类的东西,那么现代操作系统不需要这样的东西,而C ++运行时不会为你写。 你当然可以自己写一个:

  filestream.put( 26 ); // write Ctrl-Z 

但没有理由这样做。 也没有必要这样做:

  filesystem.close(); 

因为当它的析构函数被调用时,文件stream将自动closures,但是我认为这样做是很好的做法。

在Windows下,如果你在stdin中遇到一个ASCII 26(EOF),它将停止读取其余的数据。 我相信写这个字符也将终止输出发送到标准输出,但我还没有证实这一点。 您可以将stream切换到二进制模式, 就像这个问题一样 :

 #include <io.h> #include <fcntl.h> ... _setmode(0, _O_BINARY) 

而且不仅会停止将0x0A转换为0x0D 0x0A,而且还将读取/写入0x1A。 请注意,您可能必须同时切换stdin(0)和stdout(1)。

在现代文件系统上,EOF不是一个字符,所以当完成写入文件时,你不必发出它。 您只需closures该文件或让操作系统在您的进程终止时为您执行。

还没有人提到[f]truncate系统调用,这是你如何缩短文件而不从头开始重新创build文件。

truncate()ftruncate()函数ftruncate()path指定的常规文件或由fd引用的常规文件截断为length精确的字节。

如果以前的文件大于此大小,额外的数据将丢失。 如果以前的文件较短,则扩展,扩展部分读取为空字节( '\0' )。

理解这是将任何types的数据写入文件的独特操作。 该文件是一个线性字节数组,以某种方式放在磁盘上,元数据表明它有多长; truncate更改元数据。