【问题标题】:Read binary files without having them buffered in the volume block cache读取二进制文件而不将它们缓冲在卷块缓存中
【发布时间】:2020-09-01 11:26:21
【问题描述】:

较旧的、现已弃用的 macOS 文件系统 API 提供了用于读取无缓冲文件的标志。

我寻求一种现代方法来完成同样的任务,这样我就可以将文件的数据读入内存,而不会不必要地缓存在内存中的其他地方(例如卷缓存)。

例如,使用fread 阅读并首先调用setvbuf (fp, NULL, _IONBF, 0) 在我的测试中没有达到预期的效果。我正在寻找其他低级函数,可以让我读入准备好的内存缓冲区并避免缓冲整个数据。

背景

我正在编写一个文件搜索程序。它读取大量文件内容(许多 GB),否则用户不会使用这些内容。将所有这些数据缓存在卷缓存中将是一种浪费,因为无论如何它很快就会被进一步的读取清除。它还可能导致清除用户或系统实际使用的文件数据,从而导致更多的缓存未命中。

因此,我应该能够告诉系统我不需要缓存文件数据。集群边界所需的少量缓存不是问题。这是我短暂读入内存以搜索它的许多大块,不需要缓存。

【问题讨论】:

    标签: objective-c swift macos filesystems


    【解决方案1】:

    两个建议:

    • 使用read() 系统调用而不是stdio。
    • 使用F_NOCACHE 选项为fcntl() 禁用数据缓存。

    在 Swift 中,这类似于(为简洁起见,省略了错误检查):

    import Foundation
    
    let path = "/path/to/file"
    let fd = open(path, O_RDONLY)
    fcntl(fd, F_NOCACHE, 1)
    
    var buffer = Data(count: 1024 * 1024)
    buffer.withUnsafeMutableBytes { ptr in
        let amount = read(fd, ptr.baseAddress, ptr.count)
    }
    
    close(fd)
    

    【讨论】:

    • 你知道这样可以避免读取数据填充卷缓存吗?知道如何验证吗?即,是否有检查卷的块是否在缓存中的功能(我有办法找出文件占用的块号)?
    • @ThomasTempelmann:不幸的是我不知道如何验证它,我只能建议比较性能。苹果开发者论坛上的这个(旧)线程也讨论了它:developer.apple.com/forums/thread/25464
    猜你喜欢
    • 2010-11-21
    • 1970-01-01
    • 2013-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-05
    相关资源
    最近更新 更多