window下文本文件和二进制文件的理解

来源:互联网 发布:知乎 北京 皮肤科 编辑:程序博客网 时间:2024/06/05 17:19

继续使用之前的复制测试程序,来对一个aaa.bmp图片进行复制

#include <fstream>

using namespace std;


int main(){
fstream in("aaa.bmp",ios::in);
fstream out("bbb.bmp",ios::out);
if(!in)//判断打开是否成功.
return 0;
char ch;
int i=0;
do{
if(i==1)
out.put(ch);
else
i++;
ch=in.get();
}
while(!in.eof());
return 0;

}


复制之后,看到bbb.bmp生成了。

但是两者的大小不一样:aaa.bmp3512个字节。bbb.bmp538个字节。

显然复制过程中已经通过get()得到了一定的信息,但是在中间的操作过程中因为不知名的原因,信息没能正常输出。

是什么原因呢?

将aaa.bmp与bbb.bmp分别以二进制文件的形式打开。

通过对比,发现aaa和bbb前面部分都是相同的,但是到中间的某个位置,aaa中的一个十六进制数OA在bbb中被解析成了0D 0A,到bbb末尾的位置从1A开始之后就没有成功输出。

原因:

在输入输出形式检测中,若有iso::binary,则以二进制文件形式输入输出,若缺省则默认为文本文件。

从我的程序来看,显然是以文本文件输入输出了。

那么问题就来了。若用文本文件打开之后,程序自动会将一些串转换为符合文本文件形式的串。

如之前讨论过的,window自动将\n转换为\r\n,即此处的0A自动转换为0D 0A。

1A对于文本文件来说被解释成EOF,则显然无法完成该图片的完全复制。


解决方法:采用二进制复制。以二进制形式读取的话,所有的读入数据都是按数字对待,不会想文本文件一样需要ASCII码解释。

将代码改为:

#include <fstream>
using namespace std;


int main(){
fstream in("aaa.bmp",ios::in|ios::binary);
fstream out("bbb.bmp",ios::out|ios::binary);
if(!in)//判断打开是否成功
return 0;
char ch;
int i=0;
do{
if(i==1)
out.put(ch);
else
i++;
ch=in.get();
}
while(!in.eof());
return 0;
}

呵呵,果断复制成功!

原创粉丝点击