读取一个二进制文件,其中每个元素都是一个 2 字节整数
Read a binary file where every element is a 2 byte integer
我有一个扩展名为 .b16 的二进制文件,其中包含的信息为无符号整数(范围 0..65535,文件扩展名为 .b16,字节顺序:low-byte/high-byte)。
主要文件是otypes03.b08到otypes08.b08、otypes09.b16和
otypes10.b16。它们包含所有不等价的坐标
给定点数 n 的点集(订单类型)。
我已经成功读取了所有扩展名为 .b08 的文件,但是在读取 .b16 文件时,我没有得到预期的信息。
目前我所拥有的:(这是专门用于.b16格式的读取算法的修改版本)
int readPoints(int n, string file_name, vector<Point> & vPoints){
ifstream input(file_name, std::ios::binary);
if(input.fail()) return 1;
vector< unsigned char> buffer(std::istreambuf_iterator<char>(input), {});
//Copying each pair of binary points to a vector of Point objects
Point temp;
for( unsigned int i=0;i< buffer.size();i+=4){
temp.x = buffer[i] | buffer[i+1] ;
temp.y = buffer[i+2] | buffer[i+3] ;
vPoints.push_back(temp);
}
return 0;
}
文件的每一个元素都是平面上一点的坐标,不过我好像读错了,读到的坐标不是应该的。我不知道我做错了什么。
我使用的 .b08 格式:
//Reads a file of binary points and stores it on vector vPoints.
int readPoints(int n, string file_name, vector<Point> & vPoints){
ifstream input(file_name, std::ios::binary);
if(input.fail()) return 1;
// copies all data into buffer
//Stored as unsigned int. Arithmetic operations (+-*/) can be used! :)
//Can be treated as signed int or unsigned int.
vector< unsigned char> buffer(std::istreambuf_iterator<char>(input), {});
//Copying each pair of binary points to a vector of Point objects
Point temp;
cout << "Buffer size: " << buffer.size() << endl;
for( unsigned int i=0;i< buffer.size();i+=2){
temp.x = buffer[i];
temp.y = buffer[i+2];
vPoints.push_back(temp);
}
return 0;
}
有关我正在使用的数据库的更多信息,请参见此处:
http://www.ist.tugraz.at/aichholzer/research/rp/triangulations/ordertypes/
我正在尝试读取的文件是 otypes09.b16,大小为 5.7MB,以防您想尝试一下。
感谢您的宝贵时间。
for( unsigned int i=0;i< buffer.size();i+=4){
temp.x = buffer[i] | buffer[i+1] ;
temp.y = buffer[i+2] | buffer[i+3] ;
vPoints.push_back(temp);
}
以上内容不正确——您将高 8 位的位与低 8 位的位进行 OR 运算,这会损坏数据。您需要先移动位(需要移动哪些位将取决于文件是以大端格式还是小端格式存储其 16 位字)。
如果文件的数据是小端格式,这应该有效:
// read in little-endian 16-bit words
for( unsigned int i=0;i< buffer.size();i+=4){
temp.x = ((unsigned short)buffer[i+0]) | (((unsigned short)buffer[i+1])<<8);
temp.y = ((unsigned short)buffer[i+2]) | (((unsigned short)buffer[i+3])<<8);
vPoints.push_back(temp);
}
...或者如果文件的数据以big-endian格式存储,则更像是这样:
// read in big-endian 16-bit words
for( unsigned int i=0;i< buffer.size();i+=4){
temp.x = (((unsigned short)buffer[i+0])<<8) | ((unsigned short)buffer[i+1]);
temp.y = (((unsigned short)buffer[i+2])<<8) | ((unsigned short)buffer[i+3]);
vPoints.push_back(temp);
}
这是一种方法:
uint8_t lsb;
uint8_t msb;
uint16_t value;
std::vector<uint16_t> database;
//...
input.read((char *) &lsb, sizeof(lsb));
input.read((char *) &msb, sizeof(msb));
value = msb * 256 + lsb;
database.push_back(value);
由于这是一个二进制文件,所以使用了read
方法。
您可以将 value
赋值替换为:
value = msb << 8 | lsb;
虽然一个好的编译器应该将第一个 value
赋值转换为第二个
在这种情况下,根据数据的含义,并且具有绝对分辨率,我喜欢使用联合。您可以做的是拥有一个具有 int 成员的联合以及一个包含 2 个短裤的结构。每个 short 将保存 2 个 16 位整数的二进制结构。
话虽如此,以上答案可能适合您。做事的方式很多,所以设计适合你的api!
我有一个扩展名为 .b16 的二进制文件,其中包含的信息为无符号整数(范围 0..65535,文件扩展名为 .b16,字节顺序:low-byte/high-byte)。
主要文件是otypes03.b08到otypes08.b08、otypes09.b16和 otypes10.b16。它们包含所有不等价的坐标 给定点数 n 的点集(订单类型)。
我已经成功读取了所有扩展名为 .b08 的文件,但是在读取 .b16 文件时,我没有得到预期的信息。
目前我所拥有的:(这是专门用于.b16格式的读取算法的修改版本)
int readPoints(int n, string file_name, vector<Point> & vPoints){
ifstream input(file_name, std::ios::binary);
if(input.fail()) return 1;
vector< unsigned char> buffer(std::istreambuf_iterator<char>(input), {});
//Copying each pair of binary points to a vector of Point objects
Point temp;
for( unsigned int i=0;i< buffer.size();i+=4){
temp.x = buffer[i] | buffer[i+1] ;
temp.y = buffer[i+2] | buffer[i+3] ;
vPoints.push_back(temp);
}
return 0;
}
文件的每一个元素都是平面上一点的坐标,不过我好像读错了,读到的坐标不是应该的。我不知道我做错了什么。
我使用的 .b08 格式:
//Reads a file of binary points and stores it on vector vPoints.
int readPoints(int n, string file_name, vector<Point> & vPoints){
ifstream input(file_name, std::ios::binary);
if(input.fail()) return 1;
// copies all data into buffer
//Stored as unsigned int. Arithmetic operations (+-*/) can be used! :)
//Can be treated as signed int or unsigned int.
vector< unsigned char> buffer(std::istreambuf_iterator<char>(input), {});
//Copying each pair of binary points to a vector of Point objects
Point temp;
cout << "Buffer size: " << buffer.size() << endl;
for( unsigned int i=0;i< buffer.size();i+=2){
temp.x = buffer[i];
temp.y = buffer[i+2];
vPoints.push_back(temp);
}
return 0;
}
有关我正在使用的数据库的更多信息,请参见此处: http://www.ist.tugraz.at/aichholzer/research/rp/triangulations/ordertypes/
我正在尝试读取的文件是 otypes09.b16,大小为 5.7MB,以防您想尝试一下。
感谢您的宝贵时间。
for( unsigned int i=0;i< buffer.size();i+=4){
temp.x = buffer[i] | buffer[i+1] ;
temp.y = buffer[i+2] | buffer[i+3] ;
vPoints.push_back(temp);
}
以上内容不正确——您将高 8 位的位与低 8 位的位进行 OR 运算,这会损坏数据。您需要先移动位(需要移动哪些位将取决于文件是以大端格式还是小端格式存储其 16 位字)。
如果文件的数据是小端格式,这应该有效:
// read in little-endian 16-bit words
for( unsigned int i=0;i< buffer.size();i+=4){
temp.x = ((unsigned short)buffer[i+0]) | (((unsigned short)buffer[i+1])<<8);
temp.y = ((unsigned short)buffer[i+2]) | (((unsigned short)buffer[i+3])<<8);
vPoints.push_back(temp);
}
...或者如果文件的数据以big-endian格式存储,则更像是这样:
// read in big-endian 16-bit words
for( unsigned int i=0;i< buffer.size();i+=4){
temp.x = (((unsigned short)buffer[i+0])<<8) | ((unsigned short)buffer[i+1]);
temp.y = (((unsigned short)buffer[i+2])<<8) | ((unsigned short)buffer[i+3]);
vPoints.push_back(temp);
}
这是一种方法:
uint8_t lsb;
uint8_t msb;
uint16_t value;
std::vector<uint16_t> database;
//...
input.read((char *) &lsb, sizeof(lsb));
input.read((char *) &msb, sizeof(msb));
value = msb * 256 + lsb;
database.push_back(value);
由于这是一个二进制文件,所以使用了read
方法。
您可以将 value
赋值替换为:
value = msb << 8 | lsb;
虽然一个好的编译器应该将第一个 value
赋值转换为第二个
在这种情况下,根据数据的含义,并且具有绝对分辨率,我喜欢使用联合。您可以做的是拥有一个具有 int 成员的联合以及一个包含 2 个短裤的结构。每个 short 将保存 2 个 16 位整数的二进制结构。
话虽如此,以上答案可能适合您。做事的方式很多,所以设计适合你的api!