使用 File.stream 时图像大小的差异
Difference in image size using File.stream
我正在使用 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
正确吗?
很难说出您显示的代码之外有什么问题,但这段代码肯定 a) 很好 b) 毫无意义。
Enum.reduce/3
(因为 Enum
模块中的所有函数)确实终止了流。也就是说,行
fullpath
|> File.stream!()
|> Stream.map(& &1)
|> Enum.reduce("", &2 <> &1)
与 File.read!/1
基本相同(可能效率较低)。您可能会检查他们 return 正确的预期结果,但他们 立即。
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
. If you still want to reimplement this functionality, you should use iodata
built-in type to construct your object, it’s faster than binaries (and Plug.Conn.send_resp/3
欣然接受。)
拆分和重新连接二进制文件不会使其 运行 更快。
来自https://hexdocs.pm/elixir/File.html#stream!/3:
File.stream!(path, modes \ [], line_or_bytes \ :line)
The line_or_bytes argument configures how the file is read when streaming, by :line (default) or by a given number of bytes. When using the :line option, CRLF line breaks (" ") are normalized to LF (" ").
因此,默认情况下,它将文件视为文本并规范化换行符。这会使结果变小。
请尝试以下操作:
File.stream!(fullpath, [], 128 * 1024)
我正在使用 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
正确吗?
很难说出您显示的代码之外有什么问题,但这段代码肯定 a) 很好 b) 毫无意义。
Enum.reduce/3
(因为 Enum
模块中的所有函数)确实终止了流。也就是说,行
fullpath
|> File.stream!()
|> Stream.map(& &1)
|> Enum.reduce("", &2 <> &1)
与 File.read!/1
基本相同(可能效率较低)。您可能会检查他们 return 正确的预期结果,但他们 立即。
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
. If you still want to reimplement this functionality, you should use iodata
built-in type to construct your object, it’s faster than binaries (and Plug.Conn.send_resp/3
欣然接受。)
拆分和重新连接二进制文件不会使其 运行 更快。
来自https://hexdocs.pm/elixir/File.html#stream!/3:
File.stream!(path, modes \ [], line_or_bytes \ :line)
The line_or_bytes argument configures how the file is read when streaming, by :line (default) or by a given number of bytes. When using the :line option, CRLF line breaks (" ") are normalized to LF (" ").
因此,默认情况下,它将文件视为文本并规范化换行符。这会使结果变小。
请尝试以下操作:
File.stream!(fullpath, [], 128 * 1024)