读取文件并保存完全相同的文件 c++

Reading a file and saving the same exact file c++

本文关键字:文件 c++ 保存 读取      更新时间:2023-10-16

我实际上正在编写一个 c++ 程序,该程序可以读取任何类型的文件并将其保存为 bmp 文件,但首先我需要读取该文件,这就是问题所在

char fileName[] = "test.jpg";
FILE * inFileForGettingSize;//This is for getting the file size
fopen_s(&inFileForGettingSize, fileName, "r");
fseek(inFileForGettingSize, 0L, SEEK_END);
int fileSize = ftell(inFileForGettingSize);
fclose(inFileForGettingSize);

ifstream inFile;//This is for reading the file
inFile.open(fileName);
if (inFile.fail()) {
    cerr << "Error Opening File" << endl;
}
char * data = new char[fileSize];
inFile.read(data, fileSize);

ofstream outFile;//Writing the file back again
outFile.open("out.jpg");
outFile.write(data, fileSize);
outFile.close();
cin.get();

但是当我阅读该文件时,假设它是一个纯文本文件,它最后会输出一些奇怪的字符,例如:

assdassaasd
sdaasddsa
sdadsa

传球至:

assdassaasd
sdaasddsa
sdadsaÍÍÍ

因此,当我使用 jpg、exe 等执行此操作时。它破坏了它。我不是在尝试复制文件,我知道还有其他方法,我只是尝试每字节读取一个完整的文件字节。谢谢。

编辑:

我发现那些"Í"等于文件的结束行数,但这对我没有多大帮助

这是

由换行符处理引起的。

在文本模式下打开文件(因为fopen使用 "r" 而不是 "rb",并且不会将ios::binary传递给fstream open调用),而在 Windows 上,文本模式将"rn"对转换为读取时"n",写入时转换回"rn"。 结果是内存中的大小将短于磁盘上的大小,因此当您尝试使用磁盘大小进行写入时,您会越过数组的末尾并写入内存中碰巧存在的任何随机内容。

处理二进制数据时,您需要以二进制模式打开文件:

fopen_s(&inFileForGettingSize, fileName, "rb");
inFile.open(fileName, ios::binary);
outFile.open("out.jpg", ios::binary);

为了将来参考,可以改进您的复制例程。 将 I/O FILE*iostream I/O 混合在一起感觉很尴尬,打开和关闭文件两次是额外的工作,而且(最重要的是),如果您的例程在足够大的文件上运行,它将耗尽内存尝试将整个文件加载到 RAM 中。 一次复制一个块会更好:

const int BUFFER_SIZE = 65536;
char buffer[BUFFER_SIZE];
while (source.good()) {
  source.read(buffer, BUFFER_SIZE);
  dest.write(buffer, source.gcount());
}

它是一个二进制文件,因此您需要以二进制形式读取和写入文件;否则,它将被视为文本,并假定具有需要翻译的换行符。

在对 fopen() 的调用中,您需要添加 "b" 指示符:

fopen_s(&inFileForGettingSize, fileName, "rb");

在你的fstream::open calls中,你需要添加std::fstream::binary:

inFile.open(fileName, std::fstream::binary);
// ...
outFile.open("out.jpg", std::fstream::binary);