我在Window下阅读Linux文件时出现问题。以下是问题讨论:Using fstream::seekg under windows on a file created under Unix。
通过打开指定了std::ios_base::binary
的文本文件来解决该问题。
但这个模式的实际意义是什么?如果已指定,您仍然可以将文件用作文本文件(使用mystream << "Hello World" << std::endl
进行写入并使用std::getline
进行阅读。)
在Windows下,唯一的区别是,我注意到mystream << "Hello World" << std::endl
使用:
0x0D 0x0A
(EOL和回车),std::ios_base::binary
作为行分隔符0x0A
作为行分隔符,如果指定了std::ios_base::binary
(仅限EOL)打开使用std::ios_base::binary
生成的文件时,记事本不能巧妙地显示行。像vi或Wordpad这样的优秀编辑确实会展示它们。
使用和不使用std::ios_base::binary
生成的文件之间是否真的唯一不同?文档说Consider stream as binary rather than text.
,这到底是什么意思?
如果我不关心在记事本中打开文件并希望std::ios_base::binary
始终有效,那么始终设置fstream::seekg
是否安全?
答案 0 :(得分:7)
二进制和文本模式之间的区别在于实现
定义,但只涉及最低级别:他们不改变
<<
和>>
之类的含义(插入和提取文本
数据)。此外,正式地,输出除了少数不可打印的所有
如果文件是文本,则字符(如'\n'
)是未定义的行为
模式。
对于最常见的操作系统:在Unix下,没有区别;两者都是
相同。在Windows下,'\n'
内部将映射到两者
外部字符序列CR,LF(0x0D,0x0A),0x1A将是
在阅读时被解释为文件的结尾。更具异国情调(主要是
然而,操作系统,它们可以完全不同
操作系统级别的文件类型,可能无法读取文件
文本模式,如果它是以二进制模式写入,反之亦然。或者您
可以看到不同的东西:在行尾有额外的空白区域,或者
在二进制模式下没有'\n'
。
关于始终设置std::ios_base::binary
:我的政策
可移植文件是确切地决定我希望它们如何格式化,设置
二进制,并输出我想要的。这通常是CR,LF,而不仅仅是
LF,因为那是网络标准。另一方面,大多数
Windows程序只有LF没有问题,但我遇到过
不止一些Unix程序有CR,LF的问题;哪一个
主张系统地使用LF(这也更容易)。干
这样的事情意味着无论是否,我得到相同的结果
我在Unix或Windows下运行。
答案 1 :(得分:0)
文本流与二进制流的含义是特定于平台的,有些不可预测。
但就流行平台而言,它很简单:在Linux和MacOS X上,没有区别。在Windows上,唯一的区别是内部\n
已在外部流中转换为\r\n
。
答案 2 :(得分:0)
我发现(通过减少两个小时的工作以试图了解正在发生的事情),确实存在一种情况,即指定std::ios_base::binary
确实会带来很大的改变。
std::vector<char> data{ 0x01, 0x02, 0x0A, 0x0B };
{
std::fstream tfat;
tfat.open( "binary", std::ios_base::out | std::ios_base::binary );
tfat.write( &(data[0]), data.size() );
tfat.close();
}
{
std::fstream tfat;
tfat.open( "not_binary", std::ios_base::out );
tfat.write( &(data[0]), data.size() );
tfat.close();
}
然后,“二进制”文件包含4个字节:0x01, 0x02, 0x0A, 0x0B
但是“ not_binary”文件包含5个字节:0x01, 0x02, 0x0D, 0x0A, 0x0B
\r
)之前插入了 0x0D(\n
)。当我写4个字节时,我希望最后在文件中有4个字节。
因此,这使我意识到,即使不使用std::ios_base::binary
运算符,也必须在将数据写入文件时使用<<
。