如此种种,看起来是如此的复杂,难怪很多刚接触编程的网友都不相信(或者不想相信):
是啊,一个小小的换行符值得如此大动干戈么?
文本 vs 二进制哎,等等... 你前面提的C中的"b",C++中的"fstream::binary",Qt的"QFile::Text",我都知道啊:不是区分文本和二进制操作的么?和换行符有什么关系?! 那么我们有必须要看看: 什么是文本文件(Text File)?
换句话说:本来就不存在 文本文件 这个独立类别,文本文件属于二进制文件。 如果这样,为何C、C++等等打开文件是都提供文本和二进制两种模式么?(暂不解释^_^) 考虑一个例子:打开文件(不管后缀名等等),分别写入:
而后者由于全部是可打印字符,你可能就会称其为文本文件。 文件 vs 模式
任何一个文件,你都可以用文本或二进制模式打开。但是对于 *.png 等这些东西,你用文本模式打开读进来的往往不是你期望的结果。 考虑这样一个文件 hello.txt,其内容: line1/r/nline2/r/n 如果在windows下:你用文本模式打开,读进来多少个字符?用二进制模式打开,又是多少个字符?为何同一个文件,读进来的不一样? 换个角度考虑考虑我们前面提到(C、C++、Python、还有不该和语言并列Qt)的文件操作,都是需要通过系统调用对文件进行操作的。具体一点:
HANDLE WINAPI CreateFile( __in LPCTSTR lpFileName, __in DWORD dwDesiredAccess, __in DWORD dwShareMode, __in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes, __in DWORD dwCreationDisposition, __in DWORD dwFlagsAndAttributes, __in_opt HANDLE hTemplateFile ); 参数很多,每一个参数又有很多标记位组成(具体看MSDN)。但是你可以发现:对它来说,不存在文本文件和二进制文件的区别,你也无法设置text或binary等标记位!!
int open(const char *pathname, int flags); int open(const char *pathname, int flags, mode_t mode); int creat(const char *pathname, mode_t mode); 同样,这儿可以设置flags和mode,可以设置的标记很多。但是就是没有提供text和binary相关的东西!! 是不是很有意思?
换行符是时候谈
想象一下,一个文本编辑器打开一个"文本文件",遇到哪个字符开始换行呢?
应用程序和操作系统通常用1到2个字符代表换行:
这些之中,其实我们也只对 CR+LF 与 LF 这两种换行符感兴趣。 有什么问题么?本来一切很正常的: 在Windows下:
在Posix系统下
各个平台相安无事,windows下你想换行就用'/r/n',posix下想换行就用'/n' 如何就出问题了呢?各个平台的换行符不一致,一旦涉及跨平台问题就出来了。 考虑一下,如果使用C语言的binary模式的话,我们想生成一个像前面一样包含两行代码的文件,该怎么办?
应该就是为了这个吧,引入了一个"文本模式"
正是为了这个换行符,所以C、C++、Python等语言提供的文件操作函数才都有了Text、Binary两种模式: C、C++、QtC语言的文件操作#include <stdio.h> FILE *fopen(const char * restrict filename, const char * restrict mode); 除了文件名之外,还要传递一个 mode 的字符串作为标记。而这些标记分为带b和不带b两类:
C++的文件操作时explicit fstream ( const char * filename,ios_base::openmode mode = ios_base::in | ios_base::out ); 除了文件名之外,我们需要传递一个 mode:
这样看似乎没神马意思哈?一般都是组合使用的:
Qt的文件操作bool QFile::open ( OpenMode mode ) 这儿是mode又是什么东西?
其他现在国内用linux的似乎越来越多了,很多人有这个问题: linux下创建了一个包含中文的文件,拷贝到windows下面。 用记事本打开看 ==> 汉字正确,换行的地方出现了黑方块 用写字板打开看 ==> 换行正确,汉字乱码 很有意思?可是如何解决?
如果就用windows系统自带的记事本
参考
|
|
来自: ruiruiruiruic... > 《开发》