【问题标题】:Writing into a file in a streaming way and stop when we reach a given memory file size以流式方式写入文件并在达到给定内存文件大小时停止
【发布时间】:2020-04-10 09:54:40
【问题描述】:

假设我想将MyItem 的流保存到一个文件中(例如在 JSON 中)。当文件达到一定的字节大小限制时,我想停止。 我想在 Haskell 中做...流对我来说不是问题,更重要的是如何在将每个项目放入此文件后获取文件大小信息...

【问题讨论】:

  • 使用 hTell 有什么问题吗?还是来自同一个 System.IO 模块的 hFileSize
  • json 值可以分割并跨越多个文件吗?大小限制是硬限制,还是可以超过它以适应文件中的最后一个MyItem
  • @jpmarinier,我不知道 Nicolas 那时需要什么,但一个问题是 hTell 仅适用于可查找句柄(实际文件、块设备等)。如果需求发生变化并且“文件”有时最终成为管道(或某种其他类型的句柄),那么所有代码​​都需要重写。
  • @dfeuer - 真的,当时我没有考虑过这种可能性,因为 Nicolas 提到了一个文件。在 Linux 系统上,如果由于某些(实现)原因流没有保持适当的偏移量,则底层的 lseek 系统调用可能会返回 ESPIPE。在这种情况下,我会说最不坏的选择可能是让程序逻辑进行计数,可能使用一些围绕 OS 级别文件句柄的对象包装器。

标签: haskell haskell-pipes streamly


【解决方案1】:

我不认为 pipes 有任何开箱即用的功能,但编写自己的 toHandleBounded 很容易。

在每一步检查文件大小,如果小于循环限制,则将另一个块写入文件。

toHandleBounded :: MonadIO m => Integer -> Handle -> Consumer' ByteString m ()
toHandleBounded limit hd = do
  current <- liftIO $ hTell hd
  when (current < limit) $ do
    x <- await
    liftIO $ hPut hd x
    toHandleBounded limit hd

main :: IO ()
main =
  withFile "/dev/urandom" ReadMode $ \hIn ->
  withFile "out.txt" WriteMode $ \hOut ->
    runEffect $ P.fromHandle hIn >-> toHandleBounded (1024 * 500 ) hOut

【讨论】:

    猜你喜欢
    • 2021-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-18
    • 2013-01-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多