当前位置: 动力学知识库 > 问答 > 编程问答 >

Reading a large binary file with ifstream dosen't fill char buffer C++

问题描述:

I am trying to build a small opensource webserver and this bit of code works for big text files like http://norvig.com/big.txt but not for .mp3s / .flac / binary ( I tried sending "cat" )

 std::ifstream file;

file.open(filepath.c_str(), std::ifstream::binary | std::ios::in);

if(file.is_open() == true)

{

struct stat stat_buf;

int rc = stat(filepath.c_str(), &stat_buf);

long int a = stat_buf.st_size;

std::ostringstream tempLen;

tempLen << stat_buf.st_size;

setHeader("Content-Length", tempLen.str().c_str());

setHeader("Content-Type", getMimeType(filepath.c_str()));

long int chunkSize = 1024; // <1MB

do {

char *buffer = new char[chunkSize];

file.read(buffer, chunkSize - 1);

std::cout << "Chars in buffer: " std::string(buffer).length() << std::endl;

//send(buffer);

std::cout << "Chars read by ifstream: " << file.gcount() << "\n\n";

delete[] buffer;

} while(!file.eof());

file.close();

The output of this command is:

ACCESS [26/9/2014:0:14:44] Client requested using "GET" "/cat"

Chars in buffer: 7

Chars read by ifstream: 1023

Chars in buffer: 0

Chars read by ifstream: 1023

Chars in buffer: 1

Chars read by ifstream: 1023

Chars in buffer: 5

Chars read by ifstream: 1023

Chars in buffer: 12

Chars read by ifstream: 1023

Chars in buffer: 12

Chars read by ifstream: 1023

...

and so on.

网友答案:

std::string(buffer).length() doesn't make sense for a buffer of binary data. The string object will only copy the data up to the first zero byte (since it considers that the be the null terminator of character data). Consequently, calling length will only measure that portion of the data.

So your buffer has actually been filled with the amount of data indicated by gcount. You just need to work with it in ways that are not string-based.

网友答案:

And, in addition to what the first answer has said, even with text files, it looks like your program's behavior is undefined. You are allocating a 1024-byte char buffer, and reading 1023 chars into it.

You are not guaranteed that the last character in the buffer is going to be '\0'. As such, even with text files, occasionally your new[] operator might recycle some previously-used memory, have something else in the 1024th character, and std::string's constructor will happily continue scanning ahead, until it finds a '\0' character, interpreting everything up to that point as a part of the file you're trying to copy.

分享给朋友:
您可能感兴趣的文章:
随机阅读: