바이너리 파일 읽기 및 쓰기


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.