Недавно скопированный файл возвращает все 0 в виде байтового массива. - PullRequest
0 голосов
/ 01 апреля 2020

У меня есть файловый сервер go, который может принимать запросы файлов размером до 10 ГБ. Чтобы поддерживать низкое использование памяти, я считал данные многочастной формы в файл tmp. Я знаю, что за кулисами FormFile делает то же самое, но мне все еще нужно перенести его в обычный файл для некоторой обработки после загрузки.

    f, header, err := r.FormFile("file")
    if err != nil {
        return nil, fmt.Errorf("could not get file from request %w", err)
    }

    tmpFile, err := ioutil.TempFile("", "oriio-")
    if err != nil {
        return nil, err
    }

    if _, err := io.Copy(tmpFile, f); err != nil {
        return nil, fmt.Errorf("could not copy request body to file %w", err)
    }

После этого мне нужно получить первые 261 байт файла, чтобы определить его MIME-тип.

head := make([]byte, 261)

if _, err := tmpFile.Read(head); err != nil {
  return nil, err
}

Проблема, с которой я сталкиваюсь, заключается в том, что, если я пытаюсь читать напрямую из tmpFile, массив байтов возвращает 261 0, когда я печатаю fmt.Prinf("%x", head) или недействительные данные. Чтобы убедиться, что данные действительны, я сохранял их в обычный файл, открывая его в моей системе, и файл (в данном случае файл изображения) был в идеальном состоянии. Так что это не проблема поврежденного файла. Чтобы обойти проблему, я теперь закрываю файл tmp, а затем снова открываю его, и это, кажется, исправляет все.

    tmpFile, err := ioutil.TempFile("", "oriio-")
    if err != nil {
        return nil, err
    }

    if _, err := io.Copy(tmpFile, f); err != nil {
        return nil, fmt.Errorf("could not copy request body to file %w", err)
    }

    tmpFile.Close()

    tmpFile, err = os.Open(tmpFile.Name())
    if err != nil {
        panic(err)
    }

    head := make([]byte, 261)

    if _, err := tmpFile.Read(head); err != nil {
        return nil, err
    }

Теперь, когда я распечатываю массив байтов заголовка, печатается правильное содержимое. Почему это? Есть ли какой-то тип Syn c или Flu sh, который мне нужен для работы с оригинальным файлом tmp?

1 Ответ

2 голосов
/ 01 апреля 2020

Чтение / запись файла изменяет текущее местоположение в файле. После копирования tmpFile располагается в конце, поэтому чтение с него будет считывать 0 байтов. Вы должны искать сначала, если вы хотите прочитать с начала файла:

io.Copy(tmpFile, f)
tmpFile.Seek(0,0)
tmpFile.Read(head)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...