바이너리 파일 읽기 및 쓰기


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 파일 처리를 사용하기로 결정해야합니다. 둘 다 사용하지 마십시오.
frast

답변:


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

8
@Mikhail 여기서 벤치마킹을 찾을 수 있습니다.
Paolo M

3
AFAIK, 바이너리 파일에는 때때로 읽을 수없는 문자가 포함되어 있습니다. 사실 그들은 전혀 문자가 아닙니다. 이 코드는 텍스트가 아닌 기본 파일을 읽는 데 안전합니까? 내 지식은이 범위에서 부족합니다. :)
Andiana

5
소위 charC / C ++에서 바이트를 저장하는 데 사용됩니다 (지난 40 년 동안 사용). 그것은 당신이 실제로 시도하지 않는 한, 그렇게하는 것이 안전 사용 문자 등의 데이터가 (나 strlen 사용하지 않는 () 거기에, 등, 콘솔에 그것을 인쇄하지 않음) 것을. C ++ 17 std::byte은이 목적을 위해 도입 되었습니다 (실제로 char는 변장 된 문자 임)
d.Candela

2
@DavidTran 더 이상 알지 못하고 말할 수 없습니다. 문제를 재현하는 최소한의 예제를 만든 다음 질문을 게시해야하는 것 같습니다.
Björn Pollex

15

다음은 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

@BarbaraKwarc : 요청에 따라 업데이트되었습니다.
Thomas Matthews

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

대신 길이를 사용하십시오.

또한 fopen" wb" 와 함께 사용 하는 것이 좋습니다 ....


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

이미 언급했듯이 char[]모든 크기의 파일에서도 작동 하므로 파일 크기가 버퍼 크기의 배수 여야한다는 조건이 없습니다.
iMajetyHK

작동한다고해서 작동한다는 의미는 아닙니다. 작동하지 않는다는 사실은 작동하지 않는다는 것을 의미합니다.
nunojpg
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.