read () читает только несколько байтов из файла - PullRequest
2 голосов
/ 05 января 2012

Я хотел прочитать содержимое файла, используя функцию read (). Я попробовал следующее:

#define BUFFER_LENGTH (1024)

char buffer[BUFFER_LENGTH];

// The first version of the question had a typo:
// void read_file(const char filename)
// This would produce a compiler warning.
void read_file(const char *filename)
{
    ssize_t read_bytes = 0;

    // The first version had the mode in hex instead of octal.
    //
    //     int fd_in = open(filename, O_RDONLY, 0x00644);
    //
    // This does not cause problems here but it is wrong.
    // The mode is now octal (even if it is not needed).
    int fd_in = open(filename, O_RDONLY, 0644);
    if (fd_in == -1)
    {
        return;
    }

    do
    {
        read_bytes = read(fd_in, buffer, (size_t) BUFFER_LENGTH);
        printf("Read %d bytes\n", read_bytes);

        // End of file or error.
        if (read_bytes <= 0)
        {
            break;
        }
    } while (1);

    close(fd_in);
}

Я использую «gcc (GCC) 3.4.2 (mingw-special)» в системе Windows 7.

Странное поведение, которое я получаю, это то, что не весь контент читается. Например, у меня есть файл

05.01.2012  12:28            15.838 hello.exe

и когда я пытаюсь прочитать это, я получаю:

Read 216 bytes
Read 0 bytes

Насколько я знаю, read () должен продолжать чтение, пока не достигнет конца файла. Пока делает он сообщает об окончании файла (0) во второй раз, когда он вызывается?

Может быть, я упускаю что-то очевидное, но не вижу этого. Я прочитал этот документ и этот документ снова и снова, и я не могу найти, что я делаю неправильно. У кого-нибудь есть подсказка?

EDIT

Спасибо за подсказку! Это опечатка в вопросе (я исправил это). Правильно в источнике Код.

Ответы [ 4 ]

8 голосов
/ 05 января 2012

Я подозреваю, что байт 217 будет EOF (26, 0x1A) - в Windows файлы могут открываться в «текстовом» или «двоичном» режиме.В текстовом режиме 0x1A интерпретируется как EOF.

Вам нужно взглянуть на ваш открытый режим - O_BINARY.В PHP именно поэтому вы должны работать в режиме «rb» (READ BINARY), а не «R» («R», по умолчанию READ TEXT).

http://www.mingw.org/wiki/FAQ говорит, что флаг равен O_BINARY(в нижней части страницы), поэтому вам понадобится

int fd_in = open(filename, O_RDONLY | O_BINARY, 0644);

http://cygwin.com/faq.html В параграфе 5.3 рассказывается, как справиться с этим в cygwin

8 голосов
/ 05 января 2012

void read_file(const char filename)

и позже:

int fd_in = open(filename, O_RDONLY, 0x00644);

Не игнорируйте предупреждения компилятора. Я удивлен, что это не просто сбой.

1 голос
/ 05 января 2012

Вы можете попробовать использовать O_RDONLY | O_BINARY или O_RDONLY | O_NOTRANS в открытом вызове.Если не указать O_BINARY или O_NOTRANS, файл можно открыть в текстовом режиме, и чтение остановится при первом обращении к символу EOF.

0 голосов
/ 05 января 2012

Я попробовал ваш код на моей машине:

  • Windows 7,
  • Последняя версия Cygwin на сегодняшний день,
  • gcc (GCC) 3.4.4 (специальный cygming, gdc 0.12, используя dmd 0.125))

и он нормально работал для файла примера на моей машине. Файл, который я прочитал, был cmd.exe в C:\Windows\System32, и я сравнил общее количество байтов в вашей функции read_file с фактическим размером файла на диске, и они совпали.

Это предполагает одну из двух вещей:

  • В открываемом файле есть что-то особенное. Возможно, он находится в странном заблокированном состоянии, и вы получаете какую-то ошибку на полпути (хотя об этом никогда не слышали) или, возможно, файл поврежден на диске (могут ли другие программы получить к нему доступ? Попробуйте скопировать его в другую папку)
  • В вашем коде есть что-то, чего нет в вопросе, вызывающее проблему
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...