Haskell 使用惰性 mmap 读取最后一行

2023-12-19

我想读取文件的最后一行,并确保它的字段数与第一行相同——我不关心中间的任何内容。我使用 mmap 是因为它对大文件的随机访问速度很快,但遇到了不理解 Haskell 或懒惰的问题。

λ> import qualified Data.ByteString.Lazy.Char8 as LB
λ> import System.IO.MMap
λ> outh <- mmapFileByteStringLazy fname Nothing 
λ> LB.length outh
87094896
λ> LB.takeWhile (`notElem` "\n") outh
"\"Field1\",\"Field2\",

Great.

From here http://hackage.haskell.org/package/containers-0.5.9.1/docs/Data-Sequence.html#v:takeWhileR, 我知道

takeWhileR p xs 等价于reverse (takeWhileL p (reverse xs))。

那么让我们来做这个吧。也就是说,让我们通过反转我的惰性字节串来获取最后一行,像以前一样采用 while not "\n",然后取消反转它。懒惰让我认为编译器会让我轻松地做到这一点。

所以尝试一下这个:

LB.reverse (LB.takeWhile (`notElem` "\n") (LB.reverse outh))

我期望看到的是:

"\"val1\",\"val2\",

相反,这会导致我的会话崩溃。

Segmentation fault (core dumped)

问题:

  1. 我在懒惰、字节串、mmap 库或 Haskell 方面做错了什么?
  2. 我怎样才能正确且高效地获得这条线? (答案可能是使用外来指针而不是惰性字节串?)

对于其他读者,如果您想要获取最后一行,您可能会在此处的答案中找到一种非常快速且合适的方法:Haskell 中的 hSeek 和 SeekFromEnd https://stackoverflow.com/questions/41654849/hseek-and-seekfromend-in-haskell

在这个线程中,我正在专门寻找使用 mmap 的解决方案。


我更喜欢使用bytestring-mmap https://hackage.haskell.org/package/bytestring-mmap-0.2.2由同一作者制作bytestring。无论哪种情况,您所需要的只是

import System.IO.Posix.MMap (unsafeMMapFile)
import qualified Data.ByteString.Char8 as BS

main = do
   -- can be swapped out for `mmapFileByteString` from `mmap`
  bs <- unsafeMMapFile "file.txt"

  let (firstLine, _) = BS.break (== '\n') bs
      (_, lastLine) = BS.breakEnd (== '\n') bs

  putStrLn $ "First line: " ++ BS.unpack firstLine
  putStrLn $ "Last line: " ++ BS.unpack lastLine

这也可以立即运行,无需额外分配。和以前一样,需要注意的是许多文件以换行符结尾,因此可能需要BS.breakEnd (== '\n') (init bs)忽略最后一个\n特点。

另外,我不建议反转字节串——这至少需要一些分配,在这种情况下这是完全可以避免的。即使您使用惰性字节串,您仍然需要支付遍历字节串的所有块的成本(希望此时甚至不应该构造这些块)。也就是说,你的逆向代码should工作。我认为有什么问题mmap(可能这个包用严格的字节串做同样的事情就可以了)。

之前的答案,来自OP编辑之前

我不确定其中的功能有什么问题System.IO https://hackage.haskell.org/package/base-4.9.1.0/docs/System-IO.html。以下内容立即在我的笔记本电脑上运行,文件file.txt几乎是4GB。它并不优雅,但确实高效。

import System.IO

hGetLastLine :: Handle -> IO String
hGetLastLine hdl = go "" (negate 1)
  where
  go s i = do
    hSeek hdl SeekFromEnd i
    c <- hGetChar hdl
    if c == '\n'
      then pure s
      else go (c:s) (i-1)


main = do
  handle <- openFile "file.txt" ReadMode

  firstLine <- hGetLine handle
  putStrLn $ "First line: " ++ firstLine

  lastLine <- hGetLastLine handle
  putStrLn $ "Last line: " ++ lastLine
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Haskell 使用惰性 mmap 读取最后一行 的相关文章

随机推荐

  • 是否可以让 GC 管理本机对象的生命周期?

    凭借 C 和 C 经验以及一些 Java 知识 我现在正在启动一个 Java JNI C 项目 Android 如果这很重要的话 我有一个本机方法 它创建一些 C 类并返回一个指向它的指针作为 Java 长值 例如句柄 然后从 Java 代
  • Semantic-UI:为什么 Body 的视口大小不同?

    请看一下我的Hello World 式的应用程序 https verumdesigns com 使用 Semantic UI 构建 我经常使用 Semantic UI 我比 Bootstrap 更喜欢它 但我注意到边缘存在这个一致的问题 视
  • 加入具有多个匹配项的 data.table

    我之前发布了一个关于在 data table 中加入列的问题 其中一列 dep 具有一个entry的依赖信息 因此条目 3 依赖于标签为 40 的记录 然后 匹配 列被分配条目所依赖的标签的 id 值 问题发布在这里 比较列直到R中的某个索
  • “AxesSubplot”对象没有属性“get_axis_bgcolor”

    我正在尝试运行底图示例here https matplotlib org basemap users geography html我遇到错误 AxesSubplot 对象没有属性 get axis bgcolor 当我尝试该网站的第一个示例
  • 应用商店连接拒绝构建,因为缺少 NSBluetoothAlwaysUsageDescription 密钥

    我使用 Xcode 10 3 来分发我的应用程序 然后 App store connect 总是拒绝构建 我收到一封电子邮件 内容是 应用程序的 info plist 文件应包含一个 NSBluetoothAlwaysUsageDescri
  • 在客户端按多个条件过滤jqGrid

    我有一个包含一些记录的 jqGrid 想要根据多个条件过滤记录 例如 如果有三列 姓名 年龄和城市 我想按以下条件过滤网格 Name Mark and Age 25 and City NY 下面的代码工作正常 var grid jQuery
  • extjs 使用 up 和 down 方法

    我正在尝试使用up and down打电话而不是Ext getCmp但我不太明白 我有这个代码 listeners change function field selectedValue Ext getCmp wildAnimal setV
  • 关于带有圆角的 UIImageView

    我试图制作一个带有圆角的 UIImageView 所以我使用了 imageView layer setCornerRadius 5 0f 它有效 但并不完美 如果你仔细观察 你可以看到图像的角落 我上传了一张照片 不知道你是否能看清楚 角落
  • Vaadin 10 基于内容的网格样式单独行

    我正在使用 Vaadin 网格来显示传入信息并实时更新 我已经能够通过访问 DOM 来设置所有行的样式 如下所示
  • Visual Studio 2010 中的 ASP.Net MVC 1.0

    Visual Studio 2010 是否与 MVC 1 0 兼容 大家好 感谢您提前阅读 我正在使用 MVC 1 0 项目和 VS2008 我很高兴升级到 VS2010 但我怀疑它与 MVC 1 0 的兼容性 你做完了吗 结果如何 一切似
  • 在私有子网中运行时 AWS EKS 上的 DNS 问题

    我在 VPC 中设置了 EKS 集群 工作节点在私有子网中启动 我可以成功部署 Pod 和服务 但是 我无法从 Pod 内执行 DNS 解析 它在容器外部的工作节点上运行良好 使用故障排除https kubernetes io docs t
  • 如何识别分区的名称

    从下面的分区中如何知道哪些分区是引导分区 哪些分区是系统分区 我需要执行任何不同的命令来读取分区名称吗 cat proc partitions major minor blocks name 253 0 409600 zram0 179 0
  • 在直方图中绘制 x 刻度 matplotlib

    我想绘制给定名称对应的 x 我的意思是 对于foo它必须绘制 10 20 30 以直方图的形式并且所有 foo bar baz 需要位于相同的位置graph http upload wikimedia org wikipedia commo
  • web.config 单用户基本身份验证

    在 nginx 中 我可以创建一个发送的身份验证响应 WWW Authenticate 基本领域 专用网络 导致弹出单个用户 密码的登录信息而不创建 login aspx 这是我的配置设置
  • Java 设计问题:强制方法调用顺序

    最近在采访中有人问我一个问题 Problem 有一个类旨在分析代码的执行时间 类是这样的 Class StopWatch long startTime long stopTime void start set startTime void
  • jQuery如何在不检查扩展名的情况下检查上传的文件是否是图像?

    这里是新手 问题是我目前已经编写了一种方法来检查上传的文件大小和扩展名以验证它 然而 检查扩展并不是一个解决方案 因为这种验证可能会导致很多问题 我想做的是检查实际的文件类型并验证它而不使用扩展方法 我尝试过使用jQuery 文件验证器 h
  • 转码视频文件之前需要检查视频分辨率

    我正在使用弹性转码器转换视频文件 AWS Lambda函数从s3存储桶获取视频文件并根据PresetId进行转换 但是 我需要将视频文件分辨率与 PresetId 进行比较 如果视频文件分辨率高于PresetId视频分辨率 则转换该视频文件
  • 文件不以“%PDF-”开头

    昨天我遇到了一个特殊的问题 一位客户将我的一个 Delphi 应用程序安装在一些东芝笔记本电脑上 一切都很好 直到生成一些 Acrobat 文件作为 Rave 7 报告时 才产生了主题错误 这些笔记本电脑安装了 Acrobat 7 Stan
  • 找不到“Flutter/Flutter.h”文件 webview_flutter-1.0.7

    请帮我 我不知道是什么问题 但我认为是因为我更新到了最新版本的 flutter 我尝试过 flutter clean rm podfile 等等 但我无法解决这个问题 是颤振的问题吗 我花了两天时间尝试修复它 但没有成功 我更新了我所有的
  • Haskell 使用惰性 mmap 读取最后一行

    我想读取文件的最后一行 并确保它的字段数与第一行相同 我不关心中间的任何内容 我使用 mmap 是因为它对大文件的随机访问速度很快 但遇到了不理解 Haskell 或懒惰的问题 gt import qualified Data ByteSt