当在运行时设置缓冲区长度时,如何使用read(ubyte [] buffer)读取BufferedFile?

时间:2011-12-31 21:56:43

标签: d

我有一个二进制文件,它实际上是一堆文件,格式为:

lengh_of_subfile,subfile

length_of_subfile是一个64位整数。我可以读long没有问题但是当我尝试为子文件创建缓冲区时,我得到编译错误,说它在编译时无法读取。我错过了什么?我在erlang,PHP和C#中写了一个相同的提取工具...... D让我循环。

void main(string args[]) {
    Stream file = new BufferedFile(args[1], FileMode.In);
    int counter = 0;
    while(file.position < file.size) {
        ulong len;
        file.read(len);
        ubyte[len] ogg;
        file.read(ogg);
        string outname = getcwd() ~ "/" ~ to!string(counter) ~ ".ogg";
        Stream oggout = new BufferedFile(outname, FileMode.OutNew);
        oggout.write(ogg);
        writefln("Creating file " ~ to!string(counter) ~ ".ogg");
        counter++;
    }   
}

3 个答案:

答案 0 :(得分:7)

而不是

        ubyte[len] ogg;

        ubyte[] ogg = new ubyte[len];

答案 1 :(得分:2)

切掉你要填的内容

ubyte[1024*8] ogg;
ogg=ogg[0..len]
file.read(ogg);

或使用循环进行复制(因为2 ^ 64字节的数组不适合内存)

ubyte[1024*16] ogg;
while(len>0 && (int read=file.read(ogg[0..$>len?len:$]))!=0){
    oggout.write(ogg[0..read]);
    len-=read;//len is the amount still to be read
}

旁注writeln("Creating file ",counter, ".ogg");比concat然后写(java方式)更有效,因为它不会创建无用的字符串(并且在运行时创建格式字符串迟早要求第一个错误{ {1}}你没有考虑到)

答案 2 :(得分:1)

您可以使用具有动态长度的数组,或者只使用new来创建新的ubyte数组:

new ubyte[len]