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

时间:2015-01-22 18:50:44

标签: c++ file-io

我实际上正在编写一个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();

但是当我读取文件时,让我们说它是一个plainttext文件,它总是在最后输出一些奇怪的字符,例如:

assdassaasd

sdaasddsa
sdadsa

传递给:

assdassaasd

sdaasddsa
sdadsaÍÍÍ

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

编辑:

我发现那些'Í'等于文件的结束行数,但这对我没什么帮助

2 个答案:

答案 0 :(得分:3)

这是由newline handling引起的。

您以文本模式打开文件(因为"r"使用"rb"代替fopen,因为您没有将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());
}

答案 1 :(得分:1)

这是一个二进制文件,所以你需要读取和写入二进制文件;否则它被视为文本,并假设有需要翻译的换行符。

在你对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);