我一直在互联网上搜索一种用c++读取二进制文件的方法,并且我发现了两个可以工作的代码片段:
1号
#include <iostream>
#include <fstream>
int main(int argc, const char *argv[])
{
if (argc < 2) {
::std::cerr << "Usage: " << argv[0] << "<filename>\n";
return 1;
}
::std::ifstream in(argv[1], ::std::ios::binary);
while (in) {
char c;
in.get(c);
if (in) {
// ::std::cout << "Read a " << int(c) << "\n";
printf("%X ", c);
}
}
return 0;
}
结果:
6C 1B 1 FFFFFFDC F FFFFFFE7 F 6B 1
2号
#include <stdio.h>
#include <iostream>
using namespace std;
// An unsigned char can store 1 Bytes (8bits) of data (0-255)
typedef unsigned char BYTE;
// Get the size of a file
long getFileSize(FILE *file)
{
long lCurPos, lEndPos;
lCurPos = ftell(file);
fseek(file, 0, 2);
lEndPos = ftell(file);
fseek(file, lCurPos, 0);
return lEndPos;
}
int main()
{
const char *filePath = "/tmp/test.bed";
BYTE *fileBuf; // Pointer to our buffered data
FILE *file = NULL; // File pointer
// Open the file in binary mode using the "rb" format string
// This also checks if the file exists and/or can be opened for reading correctly
if ((file = fopen(filePath, "rb")) == NULL)
cout << "Could not open specified file" << endl;
else
cout << "File opened successfully" << endl;
// Get the size of the file in bytes
long fileSize = getFileSize(file);
// Allocate space in the buffer for the whole file
fileBuf = new BYTE[fileSize];
// Read the file in to the buffer
fread(fileBuf, fileSize, 1, file);
// Now that we have the entire file buffered, we can take a look at some binary infomation
// Lets take a look in hexadecimal
for (int i = 0; i < 100; i++)
printf("%X ", fileBuf[i]);
cin.get();
delete[]fileBuf;
fclose(file); // Almost forgot this
return 0;
}
结果:
6C 1B 1 DC F E7 F 6B 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 A1 D 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
xxd /tmp/test.bed
的结果:0000000: 6c1b 01dc 0fe7 0f6b 01 l......k.
ls -l /tmp/test.bed
的结果-rw-rw-r-- 1 user user 9 Nov 3 16:37 test.bed
第二种方法是在开头提供正确的十六进制代码,但似乎文件大小错误,第一种方法是弄乱字节。
这些方法看起来很不一样,也许在c++中有很多方法可以做同样的事情?专业人士有习惯用法吗?
最佳答案
您当然要在将char
对象处理为整数值之前将其转换为unsigned char
!问题在于char
可能会被签名,在这种情况下,当您将它们转换为负值时,它们会转换为负int
。显示为十六进制的int
负数将具有两个以上的十六进制数字,前导数字可能全为“f”。
我没有立即发现为什么第二种方法会导致尺寸错误。但是,C++读取二进制文件的方法很简单:
#include <iostream>
#include <fstream>
#include <vector>
#include <iomanip>
std::vector<unsigned char> bytes;
{
std::ifstream in(name, std::ios_base::binary);
bytes.assign(std::istreambuf_iterator<char>(in >> std::noskipws),
std::istreambuf_iterator<char>());
}
std::cout << std::hex << std::setfill('0');
for (int v: bytes) {
std::cout << std::setw(2) << v << ' ';
}
关于c++ - 在C++中读取二进制文件的正确方法?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19758843/