การอ่านและเขียนไฟล์ไบนารี


108

ฉันกำลังพยายามเขียนโค้ดเพื่ออ่านไฟล์ไบนารีลงในบัฟเฟอร์จากนั้นเขียนบัฟเฟอร์ไปยังไฟล์อื่น ฉันมีรหัสต่อไปนี้ แต่บัฟเฟอร์เก็บอักขระ 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

คำตอบ:


176

หากคุณต้องการทำสิ่งนี้ด้วยวิธี 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
ที่เรียกว่าcharใช้ใน C / C ++ เพื่อจัดเก็บไบต์ (และมีมานานกว่า 40 ปีแล้ว) ทำได้อย่างปลอดภัยตราบใดที่คุณไม่พยายามใช้ข้อมูลนั้นเป็นอักขระจริงๆ (อย่าใช้ strlen () บนข้อมูลนั้นอย่าพิมพ์ลงในคอนโซล ฯลฯ ) c ++ 17 แนะนำstd::byteเพื่อจุดประสงค์นี้ (ซึ่งยังคงเป็นถ่านcharปลอมตัวจริง)
d.Candela

2
@DavidTran ไม่สามารถพูดได้โดยไม่ต้องรู้อะไรมากขึ้นดูเหมือนว่าคุณควรสร้างตัวอย่างเล็ก ๆ น้อย ๆ ที่ทำให้เกิดปัญหาขึ้นแล้วโพสต์คำถาม
Björn Pollex

16

นี่เป็นตัวอย่างสั้น ๆ 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

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

ใช้ความยาวแทน

ยังดีกว่าใช้fopenกับ " wb" ....


ไม่สามารถใช้buffer.length()สำหรับบัฟเฟอร์ได้อาจมีค่า NULL อยู่ภายในจึงเอาชนะจุดประสงค์ของ strlen / length ()
John Greene

ใช้ดีกว่าsizeof(buffer).
John Greene

8

sizeof (บัฟเฟอร์) คือขนาดของตัวชี้ในบรรทัดสุดท้ายของคุณไม่ใช่ขนาดจริงของบัฟเฟอร์ คุณต้องใช้ "ความยาว" ที่คุณกำหนดไว้แล้วแทน



-2

มีวิธีที่ง่ายกว่านั้นมาก โดยไม่สนใจว่าจะเป็นไฟล์ไบนารีหรือไฟล์ข้อความ

ใช้ 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];

คุณอาจต้องการลงรายละเอียดเกี่ยวกับเรื่องนี้เพื่อให้เข้าใจมากขึ้น
jvh

-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;
}

การมีขนาดบัฟเฟอร์ที่เล็กลงจะช่วยในการคัดลอกไฟล์ขนาดเล็ก แม้แต่ "ถ่านบัฟเฟอร์ [2]" ก็สามารถทำงานได้


8
แล้วจะเกิดอะไรขึ้นถ้าขนาดไฟล์ไม่ใช่ขนาดบัฟเฟอร์หลายขนาด? ยิ่งไปกว่านั้นทำไมคุณต้องประกาศบัฟเฟอร์ของคุณint[]แทนchar[]?
firegurafiku

ฉันได้กล่าวไปแล้วว่ามันใช้งานได้char[]เช่นกันและไฟล์ทุกขนาดซึ่งหมายความว่าไม่มีเงื่อนไขว่าขนาดไฟล์ควรเป็นขนาดบัฟเฟอร์หลายขนาด
iMajetyHK

การที่คุณบอกว่ามันได้ผลไม่ได้หมายความว่ามันใช้ได้ ความจริงที่ว่ามันไม่ทำงานหมายความว่ามันไม่ทำงาน
nunojpg
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.