バイナリファイルの読み取りと書き込み


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ファイル処理の使用を決定する必要があります。両方使用しないでください。
2013年

回答:


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バイトとしましょう。
14

8
@Mikhail ここでは、いくつかのベンチマークを見つけることができます。
Paolo M

3
申し訳ありませんが、バイナリファイルには読み取り不可能な文字が含まれていることがありますが、実際にはまったく文字ではありません。このコードは非テキストベースファイルを読み取るのに安全ですか?私の知識はこの範囲では不十分です:)
Andiana

5
いわゆるcharC / C ++ではバイトを格納するために使用されます(過去40年間使用されてきました)。実際にそのデータを文字として使用しない限り、安全です(strlen()を使用したり、コンソールに出力したりしないでください)。c ++ 17 std::byteはこの目的のために導入しています(実際charにはまだ変装しているcharです)
d.Candela 2018

2
@DavidTranこれ以上知らなければ語れない-これは問題を再現する最小限の例を作成してから質問を投稿する必要があるようです。
ビョルンPollex

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
移植性のない最善の方法は、OSにファイルをコピーさせることです。結局、それはそれが生活のために何をするかの一部です。ホイール再発明する必要はありません。
Thomas Matthews

16
<fstream.h>?<iostream.h>?名前空間はありませんか?それは何ですか、90年代?
BarbaraKwarc 2017年

@BarbaraKwarc:リクエストに応じて更新されます。
Thomas Matthews

14
 sizeof(buffer) == sizeof(char*) 

代わりに長さを使用してください。

また、fopenwb」と一緒に使用することをお勧めします。


buffer.length()バッファを使用できないため、内部にNULL値が含まれている可能性があるため、strlen / length()の目的が無効になります。
John Greene

使用する方が良いsizeof(buffer)
John Greene

8

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 2016年

前述のとおりchar[]、ファイルはどのようなサイズでも機能します。つまり、ファイルサイズがバッファサイズの倍数である必要がないという条件はありません。
iMajetyHK 2018

あなたがそれが機能すると言ったという事実はそれが機能することを意味しません。動かないということは動かないということです。
nunojpg
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.