大多数语言如C ++在写入文件时,即使我们错过编写如下语句,也会输入EOF字符:
filestream.close
但是有什么办法,我们可以根据我们的要求,在C ++中为一个实例放置EOF字符。 或者我们可以使用的任何其他方法,除了使用C ++中提供的函数。
如果您需要提供更多信息,请发表评论。
提前致谢。
编辑:感谢您的支持,但这里是对此问题的补充:
如果,我们想欺骗操作系统并在文件中放置EOF字符并在EOF之后写入一些数据,以便像我们的EOF字符后的notepad.exe这样的应用程序无法读取。 我已经阅读了与此主题相关的问题的答案,并且已经知道现在的操作系统通常不会看到EOF字符,而是检查文件的长度以获得正确的知道文件长度的想法但是,那里必须是操作系统中的一个过程,它将检查文件的长度,然后更新文件记录。
我很抱歉,如果我在估计的任何一点上都错了,但请帮助我,因为它可以带来很多新想法。
答案 0 :(得分:49)
没有EOF角色。根据定义,EOF“不等于任何有效的字符代码”。通常是-1。它不会在任何时候写入文件。
DOS中有一个历史EOF字符值(CTRL + Z),但它现在已经过时了。
回答Apoorv的后续问题:操作系统从不使用文件数据来确定文件长度(文件不以任何方式“空终止”)。所以你不能欺骗操作系统。也许旧的,愚蠢的程序在CTRL + Z字符后不会读取。我不认为任何Windows应用程序(甚至记事本)都会这样做。我的猜测是,使用null(\0
)字符来欺骗它们会更容易。
答案 1 :(得分:13)
好吧,EOF
只是C stdio.h
头文件中定义的函数返回的值。它实际上由操作系统返回到所有读取功能,因此它依赖于系统。当操作系统到达文件末尾时,它会将其发送到函数,该函数的返回值大于最常见的位置(-1
),但并非总是如此。因此,总而言之,EOF
不是字符,而是操作系统返回的常量。
编辑:嗯,您需要了解有关文件系统的更多信息,请查看this.
嗨,关于你的第二个问题:
再次,您应该更好地了解filesystems
。 FAT是一个很好的例子,因为你可以找到很多关于它的文章,它的原理与NTFS非常相似。无论如何,EOF再次NOT a character
。您不能直接将其放在文件中。如果你能这样做,想象一下后果,甚至系统都无法读取“哑”的图像文件。
为什么呢? Becouse OS就像非常复杂的层结构一样。其中一个层是文件系统驱动程序。它确保它从驱动程序已知的每个文件系统传输数据。它提供了应用程序和将文件存储到HDD中的实际系统之间的桥梁。
确切地说,FAT文件系统使用所谓的FAT表 - 它是一个靠近HDD(或分区)地址空间开头的表,它包含所有集群(小存储单元)的映射。好的,现在,当你想将一些文件保存到HDD时,OS(文件系统驱动程序)会查看FAT表,并搜索值“0x0”。这个“0x0”值告诉操作系统该群集哪个地址由FAT表中该值的位置描述可以自由写入。
因此它将文件的第一部分写入其中。然后,它在FAT中查找另一个“0x0”值,如果找到,它会将文件的第二部分写入它指向的簇中。然后,它将文件所在的第一个FAT表记录的值更改为文件第二部分中下一个的物理地址。
当您的文件全部存储在HDD上时,现在出现了最后一部分,它将所需的EOF值写入FAT表,而不是写入HDD的“数据部分”。因此,当下次读取文件时,它知道这是结束,不要再看了。
所以,现在你看,如果你想手动将EOF值写入它不属于的地方,你必须编写自己的驱动程序才能重写FAT记录,但这实际上是不可能的为初学者做的事。
答案 2 :(得分:12)
我在穿过Kernighan& amp; Ritchie C 练习。
Ctrl + D 从EOF
发送与stdio.h
常量匹配的字符。
(编辑:这是在Mac OS X上;感谢@markmnl指出Windows 10的等价物是 Ctrl + Z )
答案 3 :(得分:7)
实际上在C ++中,没有使用fprintf()或ostream机制将文件写入文件的物理EOF字符。 EOF是一个I / O条件,表示无法读取更多数据。
某些早期的磁盘操作系统(如CP / M)实际上确实使用了物理0x1A(ASCII SUB字符)来表示EOF,因为文件系统只保留了块中的文件大小,因此您永远不知道文件的确切时间(以字节为单位)。随着在目录中存储实际长度计数的出现,将“EOF”字符存储为“带内”文件数据的一部分不再典型。
答案 4 :(得分:5)
在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)。
答案 5 :(得分:4)
如果EOF字符的意思是Control-Z,那么现代操作系统不需要这样的东西,C ++运行时也不会为你写一个。你当然可以自己写一个:
filestream.put( 26 ); // write Ctrl-Z
但没有充分理由这样做。也没有必要这样做:
filesystem.close();
因为文件流在调用析构函数时会自动关闭,但这是(我认为)这样做的好习惯。
答案 6 :(得分:4)
没有&#34; EOF&#34;字符。关闭流本身的事实是&#34; EOF&#34;条件。
当你在unix shell中按 Ctrl + D 时,它只会关闭标准输入流,而后者又被shell识别为&#34; EOF& #34;它退出了。
所以,发送&#34;发送&#34; &#34; EOF&#34;,只需关闭&#34; EOF&#34;需要发送。
答案 7 :(得分:3)
还没有人提到[f]truncate
系统调用,这就是如何在不重新创建文件的情况下缩短文件的时间。
truncate()
和ftruncate()
函数会导致由path
命名或由fd
引用的常规文件被截断为精确length
字节的大小。如果之前的文件大于此大小,则额外数据将丢失。如果之前的文件较短,则会扩展,扩展部分将读取为空字节(
'\0'
)。
了解这是将任何类型的数据写入文件的独特操作。该文件是一个线性的字节数组,以某种方式放在磁盘上,元数据表示它有多长; truncate
更改了元数据。
答案 8 :(得分:2)
在现代文件系统上,EOF不是字符,因此在完成写入文件时不必发出它。您只需关闭文件或让操作系统在您的流程终止时为您执行此操作。
答案 9 :(得分:0)
是的,您可以手动将EOF添加到文件中。
1)在Mac总站中,创建一个新文件。 // Connection
U2ConnectionStringBuilder csb = new U2ConnectionStringBuilder();
csb.Server = "server";
csb.Database = "db";
csb.UserID = "user";
csb.Password = "pwd";
csb.ServerType = "UNIVERSE";
U2Connection con = new U2Connection(csb.ToString());
con.Open();
U2Command cmd = con.CreateCommand();
cmd.CommandText = "SELECT COL1,COL2,COL3,COL4 FROM SOME.FILE WHERE COL2= 'XYZ'";
// Code to get the data
var dr= cmd.ExecuteReader();
if (dr.HasRows)
{
while (dr.Read())
{
string col1 = dr.GetString(0);
string col2 = dr.GetString(1);
string col3 = dr.GetString(2);
string col4 = dr.GetString(3);
T obj = new T { col1, col2, col3, col4 };
list.Add(obj);
}
}
2)在VI中打开文件
touch filename.txt
3)在“插入”模式(按i键)中,键入Control + V,然后键入Control + D。在Mac上不要松开Control键。
或者,如果我想要其他^ NewLetter,例如^ N ^ M ^ O ^ P等,我可以执行Contorl + V,然后执行Control + NewLetter。因此,例如,执行^ O,按住Control键,然后键入V和O,然后放开Control。