Разница в размере изображения с помощью File.stream - PullRequest
0 голосов
/ 08 февраля 2020

Я отправляю файл изображения в ответ, используя send_resp(200,content)

Я использовал Stream для отложенной загрузки файла

File.stream!(fullpath)
|> Stream.map(fn e -> e end) 
|> Enum.reduce(<<>>, fn x,acc  -> acc <> x end)

Мой оригинальный размер файла на диске составляет 1615829 байт.

Если я сделаю File.read(fullpath) (полная загрузка), я получу точный файл размером 1615829.

Но при использовании File.stream полученный файл изображения будет иметь размер 1615792 (на 37 байт меньше).

Из-за этого изображение становится размытым.

Какие биты мне не хватает? Я правильно использую File.stream здесь?

1 Ответ

3 голосов
/ 09 февраля 2020

Трудно сказать, что не так, за пределами кода, который вы показали, но этот код, безусловно, а) хорошо и б) бессмысленно.

Enum.reduce/3 (как и все функции из Enum модуль) действительно завершает поток. Тем не менее, строки

fullpath
|> File.stream!()
|> Stream.map(& &1) 
|> Enum.reduce("", &2 <> &1)

по существу аналогичны File.read!/1 (может быть менее эффективно). Вы можете проверить, что они возвращают правильный ожидаемый результат, но они делают это немедленно .

with :ok <- File.write!("test.txt", "a\x00\n\x01b") do
  "test.txt"
  |> File.stream!()
  |> Stream.map(& &1)
  |> Enum.reduce("", & &2 <> &1)
end
#⇒ <<97, 0, 10, 1, 98>>

Тем не менее, вы можете лучше подписаться на делегирование работы существующим помощникам, таким как Plug.Conn.send_file/5. Если вы все еще хотите переопределить эту функциональность, вы должны использовать встроенный тип iodata, чтобы создать ваш объект, это быстрее, чем двоичные файлы (и Plug.Conn.send_resp/3 с радостью примет это).

Разделение и повторное объединение двоичных файлов не заставит его работать быстрее.

...