代码之家  ›  专栏  ›  技术社区  ›  Apoorv Saxena

我们能自己写一个eof字符吗?

  •  36
  • Apoorv Saxena  · 技术社区  · 16 年前

    大多数的语言,比如C++,当写入文件时,即使我们没有写出类似的语句,也可以放置EOF字符:

    文件流.close

    然而,有任何方式,我们可以根据我们的要求,在C++中,将EOF字符放在一个实例中。 或者除了使用C++中提供的函数之外,我们可以使用任何其他方法。

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

    事先谢谢。

    编辑:感谢您的支持,但以下是对这个问题的补充:

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

    如果我的估计有任何错误,我很抱歉,但是请一定帮助我,因为这会带来很多新的想法。

    9 回复  |  直到 9 年前
        1
  •  49
  •   ypnos    16 年前

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

    DOS中有一个历史EOF字符值(ctrl+z),但现在已经过时了。

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

        2
  •  13
  •   B.Gen.Jack.O.Neill    16 年前

    好, EOF 只是C中定义的函数返回的值 stdio.h 头文件。它实际上由操作系统返回到所有的读取函数,因此它依赖于系统。当操作系统到达文件结尾时,它将它发送到函数,该函数的返回值比最常见的( -1 ,但并非总是如此。总之, EOF 不是字符,而是操作系统返回的常量。 编辑:嗯,您需要了解更多关于文件系统的信息,请看 this.

    你好,第二个问题:

    再一次,你应该仔细观察 filesystems . Fat是一个很好的例子,因为你可以找到很多关于它的文章,它的原理与NTFS非常相似。无论如何,再一次,EOF是 NOT a character . 不能直接将其放入文件中。如果你能这样做,想象一下后果,即使是“愚蠢”的图像文件也不能被系统读取。

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

    确切地说,FAT文件系统使用所谓的FAT表——它是一个位于HDD(或分区)地址空间开头附近的表,它包含所有集群(小存储单元)的映射。好的,那么现在,当您想将一些文件保存到HDD时,OS(文件系统驱动程序)将查找FAT表,并搜索值“0x0”。这个“0x0”值告诉操作系统,集群地址由FAT表中该值的位置描述,可以自由写入。

    所以它将文件的第一部分写入其中。然后,它在fat中查找另一个“0x0”值,如果找到该值,它会将文件的第二部分写入指向的集群中。然后,它将文件所在的第一个FAT表记录的值更改为下一个FAT表记录的物理地址,在本例中是文件的第二部分。

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

    所以,现在你看到,如果你想手动将EOF值写入它不属于的位置,你必须编写自己的驱动程序,它可以重写FAT记录,但对于乞丐来说,这几乎是不可能的。

        3
  •  12
  •   chbrown    10 年前

    我是在经过克尼根和里奇的时候来到这里的 C 练习。

    Ctrl键 + D 发送与匹配的字符 EOF 常数从 stdio.h .

    (编辑:这是在Mac OS X上;感谢@markmnl指出Windows 10相当于 Ctrl键 + Z )

        4
  •  7
  •   Amardeep AC9MF    16 年前

    实际上,在C++中,没有物理EOF字符使用fPrftf()或oSokes机制写入文件。EOF是一种I/O条件,表示不再需要读取数据。

    一些早期的磁盘操作系统(如cp/m)实际上使用物理的0x1A(ASCII子字符)来表示eof,因为文件系统只以块为单位维护文件大小,所以您永远不知道文件以字节为单位的确切长度。随着在目录中存储实际长度计数的出现,通常不再将“eof”字符存储为“带内”文件数据的一部分。

        5
  •  5
  •   Community Mohan Dere    9 年前

    在Windows下,如果在stdin中遇到一个ascii 26(eof),它将停止读取其余的数据。我相信写这个字符也会终止发送到stdout的输出,但我还没有确认这一点。您可以将流切换到二进制模式 as in this SO question :

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

    不仅可以停止将0x0A转换为0x0D 0x0A,而且还可以获得读/写0x1A的能力。注意,您可能需要同时切换stdin(0)和stdout(1)。

        6
  •  4
  •   anon    16 年前

    如果EOF字符是指像控制Z一样的东西,那么现代操作系统就不需要这样的东西了,C++运行时不会为你写一个。当然,你可以自己写一篇:

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

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

     filesystem.close();
    

    因为当调用文件流的析构函数时,它将自动为您关闭,但是这样做(我认为)是一个好的实践。

        7
  •  4
  •   rustyx    13 年前

    没有“eof”这个字。关闭流本身的事实是“eof”条件。

    当你按下 Ctrl键 + D 在unix shell中,只关闭标准输入流,而标准输入流又被shell识别为“eof”,然后退出。

    因此,要“发送”一个“eof”,只需关闭需要发送“eof”的流。

        8
  •  3
  •   zwol    12 年前

    还没有人提到 [f]truncate 系统调用,这就是如何在不从头重新创建文件的情况下缩短文件的长度。

    这个 truncate() ftruncate() 函数导致常规文件 path 或由引用 fd 截短到精确的尺寸 length 字节。

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

    理解这是一个不同于向文件写入任何类型数据的操作。文件是一个线性字节数组,以某种方式放在磁盘上,其中的元数据表示它的长度; truncate 更改元数据。

        9
  •  2
  •   mouviciel    16 年前

    在现代的文件系统上,eof不是一个字符,所以在完成对文件的写入时,不必发出它。当您的进程终止时,您只需要关闭文件或让操作系统为您完成它。