Как мне прочитать BufferedFile, используя read (ubyte [] buffer), когда длина буфера установлена ​​во время выполнения? - PullRequest
6 голосов
/ 01 января 2012

У меня есть двоичный файл, который на самом деле представляет собой стек файлов, формат:

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 ]

7 голосов
/ 01 января 2012

вместо

        ubyte[len] ogg;

запись

        ubyte[] ogg = new ubyte[len];
2 голосов
/ 01 января 2012

отрежьте то, что вы хотите заполнить

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, чем write (способ java), поскольку не создает бесполезных строк (а создание строки формата во время выполнения рано или поздно выдает ошибку в первом % Вы не учитываете)

1 голос
/ 01 января 2012

Вы можете использовать массив с динамической длиной или просто использовать new для создания нового массива ubyte:

new ubyte[len]
...