fopen - can't write more than 16K?
I'm currently using fopen to write/read binary files. With small files all is fines. But in some cases, when "exactly" the content is > 16K the remainder of the file is invalid !!!
The code is simple, fopen ... fread/fwrite ... fflush ... fclose !
I have try with C++. But now I got a problem during the "read"
in BinaryDefaultRead it return -1 !!! But really don't know why ! I only write 4 bytes at a time !!!
It is under Win7 64 bits with MSVC 2008 compiler.
#include <fstream>
using namespace std;
size_t BinaryDefaultRead(ifstream& stream, void* buffer, unsigned int bufferSize)
{
//return fread(buffer, 1, (size_t) bufferSize, file);
stream.read((char*)buffer, bufferSize);
if (!stream)
return -1;
return bufferSize;
}
size_t BinaryDefaultWrite(ofstream& stream, const void* buffer, unsigned int bufferSize)
{
//return fwrite(buffer, 1, (size_t) bufferSize, file);
stream.write((char*)buffer, bufferSize);
if (!stream)
return -1;
return bufferSize;
}
// Read an unsigned integer from a stream in a machine endian independent manner (for portability).
size_t BinaryReadUINT(ifstream& stream, unsigned int* value)
{
unsigned char buf[4];
size_t result = BinaryDefaultRead(stream, (void *)buf, 4);
if (result < 0)
return result;
*value = ((unsigned int) buf[0]) |
(((unsigned int) buf[1]) << 8) |
(((unsigned int) buf[2]) << 16) |
(((unsigned int) buf[3]) << 24);
return result;
}
// Write an unsigned integer to a stream in a machine endian independent manner (for portability).
size_t BinaryWriteUINT(ofstream& stream, unsigned int aValue)
{
unsigned char buf[4];
buf[0] = aValue & 0x000000ff;
buf[1] = (aValue >> 8) & 0x000000ff;
buf[2] = (aValue >> 16) & 0x000000ff;
buf[3] = (aValue >> 24) & 0x000000ff;
return BinaryDefaultWrite(stream, (void*)buf, 4);
}
// Read a floating point value from a stream in a machine endian independent manner (for portability).
size_t BinaryReadFLOAT(ifstream& stream, float* value)
{
union {
float f;
unsigned int i;
} u;
size_t result = BinaryReadUINT(stream, &u.i);
if (result < 0)
return result;
*value = u.f;
return result;
}
// Write a floating point value to a stream in a machine endian independent manner (for portability).
size_t BinaryWriteFLOAT(ofstream& stream, float aValue)
{
union {
float f;
unsigned int i;
} u;
u.f = aValue;
return BinaryWriteUINT(stream, u.i);
}
size_t BinaryReadUINTArray(ifstream& stream, unsigned int* buffer, unsigned int count)
{
size_t result;
for(unsigned int i = 0; i < count; i++)
{
result = BinaryReadUINT(stream, buffer + i);
if (result < 0)
return result;
}
return result;
}
size_t BinaryWriteUINTArray(ofstream& stream, unsigned int* buffer, unsigned int count)
{
size_t res开发者_运维技巧ult;
for(unsigned int i = 0; i < count; i++)
{
result = BinaryWriteUINT(stream, buffer[i]);
if (result < 0)
return result;
}
return result;
}
size_t BinaryReadFLOATArray(ifstream& stream, float* buffer, unsigned int count)
{
size_t result;
for(unsigned int i = 0; i < count; i++)
{
result = BinaryReadFLOAT(stream, buffer + i);
if (result < 0)
return result;
}
return result;
}
size_t BinaryWriteFLOATArray(ofstream& stream, float* buffer, unsigned int count)
{
size_t result;
for(unsigned int i = 0; i < count; i++)
{
result = BinaryWriteFLOAT(stream, buffer[i]);
if (result < 0)
return result;
}
return result;
}
fopen
is only used to open a file stream, not to read or write. fread
and fwrite
are used to do that.
fwrite
and fread
don't ensure you to write all the elements you pass them: they return the number of elements written, which can be lesser than the number of elements you passed it.
Just check the returned value, and keep fwrite
-ing until you write out all of your elements or until there's an error with the stream: use ferror
to check for an error.
From fwrite
manual:
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).
fread() does not distinguish between end-of-file and error, and callers must use feof(3) and ferror(3) to determine which occurred.
精彩评论