读写二进制文件


103

我正在尝试编写代码以将二进制文件读取到缓冲区中,然后将缓冲区写入另一个文件中。我有以下代码,但是缓冲区仅存储文件第一行中的几个ASCII字符,除此之外没有其他内容。

int length;
char * buffer;

ifstream is;
is.open ("C:\\Final.gif", ios::binary );
// get length of file:
is.seekg (0, ios::end);
length = is.tellg();
is.seekg (0, ios::beg);
// allocate memory:
buffer = new char [length];
// read data as a block:
is.read (buffer,length);
is.close();

FILE *pFile;
pFile = fopen ("C:\\myfile.gif", "w");
fwrite (buffer , 1 , sizeof(buffer) , pFile );

28
您应该决定使用iostream或C文件处理。请不要同时使用两者。
2011年

Answers:


172

如果要使用C ++方式执行此操作,请按以下方式进行操作:

#include <fstream>
#include <iterator>
#include <algorithm>

int main()
{
    std::ifstream input( "C:\\Final.gif", std::ios::binary );
    std::ofstream output( "C:\\myfile.gif", std::ios::binary );

    std::copy( 
        std::istreambuf_iterator<char>(input), 
        std::istreambuf_iterator<char>( ),
        std::ostreambuf_iterator<char>(output));
}

如果您需要缓冲区中的数据来修改它或进行其他操作,请执行以下操作:

#include <fstream>
#include <iterator>
#include <vector>

int main()
{
    std::ifstream input( "C:\\Final.gif", std::ios::binary );

    // copies all data into buffer
    std::vector<unsigned char> buffer(std::istreambuf_iterator<char>(input), {});

}

4
如果我只想复制一部分数据来缓冲该怎么办。我该怎么办?假设1024个字节。
likern 2014年

8
@Mikhail 在这里您可以找到一些基准测试。
Paolo M

3
AFAIK,二进制文件有时包含不可读的char,实际上它们根本不是char。此代码对于读取非文本基本文件是否安全?我的知识在这个范围内很短:)
Andiana '16

5
char在C / C ++中使用所谓的存储字节(已经使用了40年)。它是安全的这样做,只要你不尝试实际用途,作为字符数据(不使用strlen()就可以了,不要打印到控制台,等等)。c ++ 17 std::byte为此目的引入了(实际上仍然是char伪装的char )
d.Candela

2
@DavidTran不能不说就不多说-似乎您应该创建一个再现问题的最小示例,然后发布问题。
比约恩·波莱克斯(BjörnPollex)

15

这是一个简短的示例,使用的C ++方式rdbuf。我是从网上得到的。我找不到关于此的原始来源:

#include <fstream>
#include <iostream>

int main () 
{
  std::ifstream f1 ("C:\\me.txt",std::fstream::binary);

  std::ofstream f2 ("C:\\me2.doc",std::fstream::trunc|std::fstream::binary);

  f2<<f1.rdbuf();

  return 0;
}

8
最好的,非便携式的方法是让操作系统复制文件。毕竟,这是谋生手段的一部分;无需重新发明轮子
Thomas Matthews

16
<fstream.h>?<iostream.h>?没有名称空间?是什么,九十年代?
BarbaraKwarc

@BarbaraKwarc:根据您的请求进行了更新。
Thomas Matthews


8

sizeof(buffer)是最后一行指针的大小,而不是缓冲区的实际大小。您需要使用已经建立的“长度”


4

您应该将length传递给fwrite而不是sizeof(buffer)。


-1

有一种更简单的方法。这不在乎它是二进制文件还是文本文件。

使用noskipws。

char buf[SZ];
ifstream f("file");
int i;
for(i=0; f >> noskipws >> buffer[i]; i++);
ofstream f2("writeto");
for(int j=0; j < i; j++) f2 << noskipws << buffer[j];

-2

可以使用以下代码段中的简单命令来完成。

复制任何大小的整个文件。没有大小限制!

只是使用这个。测试和工作!

#include<iostream>
#include<fstream>
using namespace std;
int main()
{
  ifstream infile;
  infile.open("source.pdf",ios::binary|ios::in);

  ofstream outfile;
  outfile.open("temppdf.pdf",ios::binary|ios::out);

  int buffer[2];
  while(infile.read((char *)&buffer,sizeof(buffer)))
  {
      outfile.write((char *)&buffer,sizeof(buffer));
  }

  infile.close();
  outfile.close();
  return 0;
}

具有较小的缓冲区大小将有助于复制微小文件。即使是“ char buffer [2]”也可以做到。


8
如果文件大小不是缓冲区大小的倍数,该怎么办?此外,为什么必须将缓冲区声明为int[]而不是char[]
firegurafiku '16

我已经提到char[]过,它也适用于任何大小的文件,这意味着没有条件文件大小应该是缓冲区大小的倍数。
iMajetyHK

您说的有效并不意味着它有效。它不起作用的事实意味着它不起作用。
nunojpg
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.