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

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

我实际上正在编写一个 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 等执行此操作时,它会损坏它。 我不是要复制文件,我知道还有其他方法,我只是想每个字节读取一个完整的文件字节。谢谢

编辑:

我发现那些“Í”等于文件的结束行数,但这对我帮助不大

这是由newline handling造成的。

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

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

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

inFile.open(fileName, ios::binary);

outFile.open("out.jpg", ios::binary);

为了将来参考,您的复制例程可以改进。将 FILE* I/O 与 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 调用中,您需要添加 std::fstream::binary:

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