1

I am trying to read an entire jpg file in binary mode using visual c++. The code is as follows:

FILE *fd = fopen("c:\\Temp\\img.jpg", "rb");
if(fd == NULL) {
    cerr << "Error opening file\n";
    return;
}

fseek(fd, 0, SEEK_END);
long fileSize = ftell(fd);
int *stream = (int *)malloc(fileSize);
cout << fileSize << '\n';
fseek(fd, 0, SEEK_SET);
int bytes_read = fread(stream, fileSize, 1, fd);
printf("%i\n", bytes_read);
fclose(fd);

The problem is that the bytes_read is always 1. The fileSize variable contains the correct size of the file. So I am not sure why the bytes_read is always 1 and not equal to fileSize..?

Jan Carlo Viray
  • 11,856
  • 11
  • 42
  • 63
pokiman
  • 956
  • 2
  • 12
  • 20
  • See also: http://stackoverflow.com/questions/116038/what-is-the-best-way-to-slurp-a-file-into-a-stdstring-in-c – Robᵩ Feb 09 '12 at 18:02

6 Answers6

2
int n_read = fread(stream, fileSize, 1, fd);

returns the number of chunks of size fileSize you got. In this case 1.

Look at section 7.21.8.1 of the C standard: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1548.pdf (page 334)

So you need to multiply n_read with fileSize to get the number of bytes read.

Johan Lundberg
  • 26,184
  • 12
  • 71
  • 97
2

If you want the number of bytes read you need to switch the arguments like so:

int bytes_read = fread(stream, 1, fileSize, fd);
frast
  • 2,700
  • 1
  • 25
  • 34
1
RETURN VALUE
       fread() and fwrite() return the number of items  successfully  read  or
       written  (i.e.,  not the number of characters).  If an error occurs, or
       the end-of-file is reached, the return value is a short item count  (or
       zero).

You told it to read 1 item of size fileSize, and it did.

Useless
  • 64,155
  • 6
  • 88
  • 132
1

From man 3p fread:

fread() and fwrite() return the number of items successfully read or written (i.e., not the number of characters). If an error occurs, or the end-of-file is reached, the return value is a short item count (or zero).

You told it to read 1 file-length, and that's what it read.

Chris Eberle
  • 47,994
  • 12
  • 82
  • 119
0

In C++, you can use std::ifstream which comes with idiomatic reading style as:

std::ifstream file("file.bin", std::ifstream::binary); //binary mode!
std::istream_iterator<char> begin(file), end);  //setup iterators!
std::vector<char> v(begin,end);  //read all data into a vector!
//v contains the binary data, which you can use from now on

//you can get the pointer to the data as
char *buffer = &v[0];
size_t sizeOfBuffer = v.size();
//you can use buffer and sizeOfBuffer instead of v.

//just remember that the lifetime of buffer is tied with the lifetime of v
//which means, if v goes out scope, the pointer `buffer` will become invalid

Hope you read the comments in the above snippet. :-)

Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • Except that `istream_iterator` reads formatted input, skipping whitespace. `istreambuf_iterator`, perhaps? – Robᵩ Feb 09 '12 at 17:59
  • @Rob: I think, no. `istream_iterator` doesn't *read* the data; it just *iterates* the data which is read by the stream object itself, which in this case, will read whitespace also, as it is opened with `std::ifstream::binary` mode. – Nawaz Feb 09 '12 at 18:01
0

In your call to fread you are telling it to read 1 byte...

It should be: fread(stream, 1, filesize, fd);

CHollman82
  • 576
  • 1
  • 8
  • 28