fopen - не может написать больше 16К? - PullRequest
0 голосов
/ 17 января 2011

В настоящее время я использую fopen для записи / чтения двоичных файлов. С небольшими файлами все в порядке. Но в некоторых случаях, когда «точно» содержимое> 16 КБ, оставшаяся часть файла недействительна !!!

Код прост, fopen ... fread / fwrite ... fflush ... fclose!

Я пробовал с C ++. Но теперь у меня возникла проблема во время «чтения»

в BinaryDefaultЧитать, возвращать -1 !!! Но на самом деле не знаю почему! Я пишу только 4 байта за раз !!!

Это под Win7 64 бит с компилятором MSVC 2008.

#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 result;
    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;
}

1 Ответ

6 голосов
/ 17 января 2011

fopen используется только для открытия файлового потока, а не для чтения или записи. fread и fwrite используются для этого.

fwrite и fread не гарантируют, что вы записали все элементы, которые вы им передали: они возвращают количество записанных элементов, которое может быть меньше, чем количество элементов, которые вы передали ему.

Просто проверьте возвращаемое значение и сохраняйте fwrite -ing до тех пор, пока вы не напишите все свои элементы или пока не возникнет ошибка с потоком: используйте ferror для проверки на наличие ошибки.


Из fwrite руководство:

fread () и fwrite () возвращают количество успешно прочитанных или записанных элементов (т. Е. Не количество символов). Если произошла ошибка или достигнут конец файла, возвращаемое значение - это короткий счетчик элементов (или ноль).

fread () не различает конец файла и ошибку, и вызывающие стороны должны использовать feof (3) и ferror (3), чтобы определить, что произошло.

...