【问题标题】:Byte InputRange from file来自文件的字节 InputRange
【发布时间】:2015-05-16 10:30:33
【问题描述】:

如何从文件中轻松构造原始的逐字节 InputRange/ForwardRange/RandomAccessRange?

【问题讨论】:

    标签: file-io d phobos


    【解决方案1】:
    file.byChunk(4096).joiner
    

    这会以 4096 字节的块读取文件,然后将这些块懒惰地连接到单个 ubyte 输入范围中。

    joiner 来自std.algorithm,所以你必须先导入它。

    【讨论】:

    • 我希望我可以投票五次,这非常有用,我不知道!
    • @AdamD.Ruppe 听起来像是本周 D 中本周的好话题!
    • 想象一下这个包装成未来,当数据加载时你会得到一个事件......好东西。
    【解决方案2】:

    从文件中生成原始字节范围的最简单方法是将其全部读入内存:

    import std.file;
    auto data = cast(ubyte[]) read("filename");
    // data is a full-featured random access range of the contents
    

    如果文件太大而不合理,您可以尝试使用内存映射文件http://dlang.org/phobos/std_mmfile.html 并使用 opSlice 从中获取一个数组。由于它是一个数组,因此您可以获得全方位的功能,但由于它是由操作系统映射的内存,因此您在触摸文件时会变得懒惰。

    对于一个简单的 InputRange,Phobos 中有 LockingTextReader(未记录),或者您可以自己在 C 函数 byChunk 甚至 fgetc 上构建一个。 fgetc 是最容易写的:

    struct FileByByte {
        ubyte front;
        void popFront() { front = cast(ubyte) fgetc(fp); }
        bool empty() { return feof(fp); }
        FILE* fp;
        this(FILE* fp) { this.fp = fp; popFront(); /* prime it */ }
    }
    

    我还没有实际测试过,但我很确定它会起作用。 (顺便说一句,文件打开和关闭与此分开,因为范围应该只是对数据的视图,而不是托管容器。您不会因为将此范围传递给函数而关闭文件。)

    不是虽然是前向或随机访问范围。在没有大量缓冲代码的情况下在流上执行这些操作会比较棘手,我认为尝试编写这是一个错误 - 通常,范围应该很便宜,而不是模拟底层容器本身不支持的功能。

    编辑:另一个答案是非缓冲方式! https://stackoverflow.com/a/30278933/1457000 太棒了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-07
      • 2016-03-04
      相关资源
      最近更新 更多