图像文件的C++ ifstream
C++ ifstream of image file
我无法将图像文件读入缓冲区。当我读取普通的 ascii 文件时,一切都很好,但当涉及到图像文件时,我怀疑图像文件中有一个 \0 字符?
我需要接收图像文件,将其解析为 16KB 的块进行哈希处理,但是当我这样做时
std::ifstream ifs;
ifs.open(file_name, std::ifstream::binary | std::ifstream::in);
.
.
.
std::string block;
char buffer[BLOCK_SIZE];
.
.
.
memset(buffer, 0, BLOCK_SIZE);
ifs.read(buffer, BLOCK_SIZE);
block = buffer;
std::cout << i << " | block size: " << block.length()
<< " | buffer size: " << strlen(buffer) << std::endl;
hash = sha256(block); // string type required for openssl's function
我明白了
0 | block size: 4 | buffer size: 4
1 | block size: 16 | buffer size: 16
2 | block size: 88 | buffer size: 88
3 | block size: 57 | buffer size: 57
4 | block size: 109 | buffer size: 109
5 | block size: 26 | buffer size: 26
6 | block size: 65 | buffer size: 65
如何解决这个问题?我怀疑,例如
junkjunkjunk[=12=]junkjunkjunk
图片文件有随机\0
不能使用strlen()
获取二进制数据的长度,因为它是用来获取以null结尾的C风格字符串的长度。使用 =
运算符将二进制数据分配给 std::string
也是一个坏主意。
您可以使用函数 std::istream::gcount()
获取上次 read()
或其他未格式化输入操作读取的长度。
#include <iostream>
#include <fstream>
#include <cstring>
int main(){
const int BLOCK_SIZE = 16 * 1024;
const char* file_name = "test.dat";
int i = 0;
std::ifstream ifs;
ifs.open(file_name, std::ifstream::binary | std::ifstream::in);
char buffer[BLOCK_SIZE];
memset(buffer, 0, BLOCK_SIZE);
ifs.read(buffer, BLOCK_SIZE);
std::cout << i << " | buffer size: " << ifs.gcount() << std::endl;
return 0;
}
如果 block
是 std::string
尝试像这样使用返回的长度:
std::string block;
char buffer[BLOCK_SIZE];
ifs.read(buffer, BLOCK_SIZE);
// check for errors here
block.assign(buffer, ifs.gcount());
函数ifs.gcount()
returns读取的字符数。
使用block = buffer
强制字符串通过查找空字符来检测数据的结尾。这适用于空终止的 c 风格字符串,但不适用于一般的字符串(或数据)。
我无法将图像文件读入缓冲区。当我读取普通的 ascii 文件时,一切都很好,但当涉及到图像文件时,我怀疑图像文件中有一个 \0 字符?
我需要接收图像文件,将其解析为 16KB 的块进行哈希处理,但是当我这样做时
std::ifstream ifs;
ifs.open(file_name, std::ifstream::binary | std::ifstream::in);
.
.
.
std::string block;
char buffer[BLOCK_SIZE];
.
.
.
memset(buffer, 0, BLOCK_SIZE);
ifs.read(buffer, BLOCK_SIZE);
block = buffer;
std::cout << i << " | block size: " << block.length()
<< " | buffer size: " << strlen(buffer) << std::endl;
hash = sha256(block); // string type required for openssl's function
我明白了
0 | block size: 4 | buffer size: 4
1 | block size: 16 | buffer size: 16
2 | block size: 88 | buffer size: 88
3 | block size: 57 | buffer size: 57
4 | block size: 109 | buffer size: 109
5 | block size: 26 | buffer size: 26
6 | block size: 65 | buffer size: 65
如何解决这个问题?我怀疑,例如
junkjunkjunk[=12=]junkjunkjunk
图片文件有随机\0
不能使用strlen()
获取二进制数据的长度,因为它是用来获取以null结尾的C风格字符串的长度。使用 =
运算符将二进制数据分配给 std::string
也是一个坏主意。
您可以使用函数 std::istream::gcount()
获取上次 read()
或其他未格式化输入操作读取的长度。
#include <iostream>
#include <fstream>
#include <cstring>
int main(){
const int BLOCK_SIZE = 16 * 1024;
const char* file_name = "test.dat";
int i = 0;
std::ifstream ifs;
ifs.open(file_name, std::ifstream::binary | std::ifstream::in);
char buffer[BLOCK_SIZE];
memset(buffer, 0, BLOCK_SIZE);
ifs.read(buffer, BLOCK_SIZE);
std::cout << i << " | buffer size: " << ifs.gcount() << std::endl;
return 0;
}
如果 block
是 std::string
尝试像这样使用返回的长度:
std::string block;
char buffer[BLOCK_SIZE];
ifs.read(buffer, BLOCK_SIZE);
// check for errors here
block.assign(buffer, ifs.gcount());
函数ifs.gcount()
returns读取的字符数。
使用block = buffer
强制字符串通过查找空字符来检测数据的结尾。这适用于空终止的 c 风格字符串,但不适用于一般的字符串(或数据)。