[英]Read binary file c++
我正在尝试将图像读入 char 数组。 这是我的尝试:
ifstream file ("htdocs/image.png", ios::in | ios::binary | ios::ate);
ifstream::pos_type fileSize;
char* fileContents;
if(file.is_open())
{
fileSize = file.tellg();
fileContents = new char[fileSize];
file.seekg(0, ios::beg);
if(!file.read(fileContents, fileSize))
{
cout << "fail to read" << endl;
}
file.close();
cout << "size: " << fileSize << endl;
cout << "sizeof: " << sizeof(fileContents) << endl;
cout << "length: " << strlen(fileContents) << endl;
cout << "random: " << fileContents[55] << endl;
cout << fileContents << endl;
}
这是 output:
size: 1944
sizeof: 8
length: 8
random: ?
?PNG
谁能给我解释一下? position 8 是否有文件结尾字符? 这个例子取自cplusplus.com
运行 Mac OS X 并使用 XCode 进行编译。
返回文件的大小。 image.png
的大小为1944 bytes
。
cout << "size: " << fileSize << endl;
返回sizeof(char*)
,在您的环境中为8
。 请注意,任何指针的大小在任何环境中始终相同。
cout << "sizeof: " << sizeof(fileContents) << endl;
您正在读取的文件是二进制文件,因此它可能包含0
作为有效数据。 当您使用strlen
时,它会返回长度,直到遇到0
,在您的文件中为8
。
cout << "length: " << strlen(fileContents) << endl;
从文件开始返回56th location
的字符(记住数组索引从 0 开始)。
cout << "random: " << fileContents[55] << endl;
一条建议:
请记住使用以下方法取消分配fileContents
的动态 memory 分配:
delete[] fileContents;
如果不这样做,您最终将创建memory 泄漏。
我对另一个问题的回答应该正是您正在寻找的(尤其是关于将其读入vector<char>
的第二部分,您应该更喜欢数组。
至于你的 output:
sizeof(fileContents)
返回char *
的大小,在您的系统上为 8(我猜是 64 位)strlen
在第一个'\0'
处停止,就像 output 运算符一样。fileSize - 文件中的字节数。
sizeof( fileContents ) - 返回 char* 指针的大小。
strlen(fileContents) - 计算字符数,直到找到值为“0”的字符。 这显然是在 8 个字符之后 - 因为您正在读取 BINARY 数据,所以这不是一个意外的结果。
cout << fileContents - 与 strlen 类似,cout 会写出字符,直到找到值为 '0' 的字符。 从 output 看来,有些字符无法打印。
您的示例还有一些其他问题 - 例如,它不会释放使用的 memory。 这是一个更强大的版本:
vector< char > fileContents;
{
ifstream file("htdocs/image.png", ios::in | ios::binary | ios::ate);
if(!file.is_open())
throw runtime_error("couldn't open htdocs/image.png");
fileContents.resize(file.tellg());
file.seekg(0, ios::beg);
if(!file.read(&fileContents[ 0 ], fileContents.size()))
throw runtime_error("failed to read from htdocs/image.png");
}
cout << "size: " << fileContents.size() << endl;
cout << "data:" << endl;
for( unsigned i = 0; i != fileContents.size(); ++i )
{
if( i % 65 == 0 )
cout << L"\n';
cout << fileContents[ i ];
}
你能指望什么? png 文件是二进制文件,因此它们可能在某处包含'\0'
字符(数值为 0 的字符)。
如果您将 png 文件内容视为字符串( '\0' terminated array of characters
)并将其打印为字符串,那么它将在遇到第一个'\0'
字符后停止。
所以代码没有问题, fileContents
正确包含 png 文件(大小为 1944 字节)
size: 1944 // the png is 1944 bytes
sizeof: 8 // sizeof(fileContents) is the sizeof a pointer (fileContents type is char*) which is 8 bytes
length: 8 // the 9th character in the png file is '\0' (numeric 0)
random: ? // the 56th character in the png file
?PNG // the 5th-8th character is not printable, the 9th character is '\0' so cout stop here
使用 unsigned char 处理二进制数据是一个很好的做法。 由于受支持的 fonts 的限制,随机选择的字符可能无法在控制台 window 中正确显示。 您也可以通过以十六进制打印来验证相同的内容,并在十六进制编辑器中打开相同的文件来验证它。 请不要忘记删除使用后分配的 memory。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.