读取二进制文件 C++
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6162601/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Read binary file c++
提问by Emil
I'm trying to read an image into a char array. Here is my try:
我正在尝试将图像读入字符数组。这是我的尝试:
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;
}
And this is the output:
这是输出:
size: 1944
sizeof: 8
length: 8
random: ?
?PNG
Can anyone explain this to me? Is there an end-of-file char at position 8? This example was taken from cplusplus.com
任何人都可以向我解释这一点吗?位置 8 处是否有文件结尾字符?这个例子取自cplusplus.com
Running Mac OS X and compiling with XCode.
运行 Mac OS X 并使用 XCode 进行编译。
回答by Alok Save
Returns the size of the file. size of your
image.png
is1944 bytes
.cout << "size: " << fileSize << endl;
Returns the
sizeof(char*)
, which is8
on your environment. Note that size of any pointer is always the same on any environment.cout << "sizeof: " << sizeof(fileContents) << endl;
The file you are reading is a binary file so it might contain
0
as a valid data. When you usestrlen
, it returns the length until a0
is encountered, which in the case of your file is8
.cout << "length: " << strlen(fileContents) << endl;
Returns the character at the
56th location
(remember array indexing starts from 0) from start of file.cout << "random: " << fileContents[55] << endl;
返回文件的大小。你的尺寸
image.png
是1944 bytes
.cout << "size: " << fileSize << endl;
返回
sizeof(char*)
,8
位于您的环境中。请注意,任何指针的大小在任何环境中始终相同。cout << "sizeof: " << sizeof(fileContents) << endl;
您正在读取的文件是一个二进制文件,因此它可能包含
0
有效数据。当您使用 时strlen
,它会返回长度,直到0
遇到 a,就您的文件而言,它是8
.cout << "length: " << strlen(fileContents) << endl;
返回
56th location
文件开头(记住数组索引从 0 开始)处的字符。cout << "random: " << fileContents[55] << endl;
A suggestion:
一条建议:
Do remember to deallocate the dynamic memory allocation for fileContents
using:
请记住释放动态内存分配以fileContents
使用:
delete[] fileContents;
if you don't, you will end up creating a memory leak.
如果你不这样做,你最终会造成内存泄漏。
回答by Geoffrey Elliott
fileSize - the number of bytes in the file.
fileSize - 文件中的字节数。
sizeof( fileContents ) - returns the size of a char* pointer.
sizeof( fileContents ) - 返回 char* 指针的大小。
strlen( fileContents) - counts the number of characters until a character with a value of '0' is found. That is apparently after just 8 characters - since you are reading BINARY data this is not an unexpected result.
strlen( fileContents) - 计算字符数,直到找到值为“0”的字符。这显然是在 8 个字符之后 - 因为您正在读取 BINARY 数据,所以这不是意外的结果。
cout << fileContents - like strlen, cout writes out characters until one with a value of '0' is found. From the output it looks like some of the characters aren't printable.
cout << fileContents - 与 strlen 类似,cout 会写出字符,直到找到值为 '0' 的字符。从输出看来,有些字符是不可打印的。
Your example has some other issues - it doesn't free the memory used, for example. Here's a slightly more robust version:
您的示例还有其他一些问题 - 例如,它不会释放使用的内存。这是一个稍微更强大的版本:
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 ];
}
回答by Bj?rn Pollex
This answerof mine to another question should be exactly what you are looking for (especially the second part about reading it into a vector<char>
, which you should prefer to an array.
这个答案我的另外一个问题应该是你在寻找什么(尤其是第二部分关于阅读它变成一个vector<char>
,你应该更喜欢到一个数组。
As for your output:
至于你的输出:
sizeof(fileContents)
return the size of achar *
, which is 8 on your system (64 bit I guess)strlen
stops at the first'\0'
, just as the output operator does.
sizeof(fileContents)
返回 a 的大小,char *
在您的系统上为 8(我猜是 64 位)strlen
停在 first'\0'
,就像输出运算符一样。
回答by dragon135
What do you expect? png files are binary so they may contain '\0'
character (character having numeric value 0) somewhere.
你能指望什么?png 文件是二进制文件,因此它们可能'\0'
在某处包含字符(具有数值 0 的字符)。
If you treat the png file contents as string ('\0' terminated array of characters
) and print it as string then it will stop after encountering the first '\0'
character.
如果将 png 文件内容视为字符串 ( '\0' terminated array of characters
) 并将其打印为字符串,那么它会在遇到第一个'\0'
字符后停止。
So there is nothing wrong with the code, fileContents
is correctly contains the png file (with size 1944 bytes)
所以代码没有问题,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 '##代码##' (numeric 0)
random: ? // the 56th character in the png file
?PNG // the 5th-8th character is not printable, the 9th character is '##代码##' so cout stop here
回答by sarat
It's a good practice to use unsigned char to use with binary data. The character randomly selected might not be displayed properly in the console window due to the limitations in the fonts supported. Also you can verify the same thing by printing it in hexadecimal and open the same file in a hex editor to verify it. Please don't forget to delete the memory allocated after use.
使用 unsigned char 来处理二进制数据是一种很好的做法。由于支持字体的限制,随机选择的字符可能无法在控制台窗口中正确显示。您也可以通过以十六进制打印并在十六进制编辑器中打开相同的文件来验证它来验证相同的内容。请不要忘记删除使用后分配的内存。