Самый быстрый способ чтения длинных [] из файла? - PullRequest
7 голосов
/ 29 сентября 2010

У меня есть файл, содержащий около 200 000 длинных значений, которые я хочу прочитать как можно быстрее в длинном [].Это для приложения Android;вызовы функций медленны (поэтому все, что связано с длинным чтением за раз с циклом «for», будет очень медленным), и мне нужна быстрая загрузка.Что я могу использовать?Все, на что я смотрю, похоже, быстро читает только байты.

Я уже использовал ByteBuffer и FileChannel из пакета NIO, и это кажется очень быстрым способом загрузки массивов значений из файлов.Тем не менее, я не могу понять, как использовать это для чтения данных в длинный [].Я пытался обернуть long [] как LongBuffer, но я не вижу способа передать данные из файла в LongBuffer.

Редактировать: Какой бы метод я ни использовал, мне нужно иметь возможность использовать Arrays.binarySearch в массиве long[] в конце.

Ответы [ 2 ]

3 голосов
/ 29 сентября 2010

Нет способа разыграть byte[] в long[]. Однако вы можете попытаться использовать FileChannel для считывания содержимого в ByteBuffer, а затем получить от LongBuffer до ByteBuffer.asLongBuffer, от которого вы можете получить long[] до LongBuffer.array().

Вы также можете попробовать FileChannel.map, чтобы получить MappedByteBuffer файла. Это может быть быстрее, чем пройти через FileChannel.read.

Если это не сработает, вы можете попробовать использовать FileChannel для чтения содержимого в ByteBuffer, а затем получить доступ к long s внутри него, используя ByteBuffer.getLong(index).


Альтернативное решение. (Нет вызовов методов в цикле: -)

byte[] byteArray = new byte[longCount * 8];
FileInputStream fis = new FileInputStream("lotsoflongs");
fis.read(byteArray);
fis.close();
for (int i = 0; i < longCount; i += 8)
    longArray[i >> 3] = ((long) byteArray[0+i]        << 56) +
                        ((long)(byteArray[1+i] & 255) << 48) +
                        ((long)(byteArray[2+i] & 255) << 40) +
                        ((long)(byteArray[3+i] & 255) << 32) +
                        ((long)(byteArray[4+i] & 255) << 24) +
                              ((byteArray[5+i] & 255) << 16) +
                              ((byteArray[6+i] & 255) <<  8) +
                              ((byteArray[7+i] & 255) <<  0);

Сейчас я протестировал несколько решений, и это, кажется, самый быстрый способ сделать это. Также обратите внимание, что фактические байты, считанные в fis.read(byteArray), могут быть меньше, чем фактический размер byteArray. Таким образом, если это должно быть сделано правильно, вам нужно поместить его в цикл, который повторяется до тех пор, пока не будут прочитаны все байты.

1 голос
/ 29 сентября 2010

Попробуйте использовать DataInputStream .Поскольку вы можете легко узнать длину файла, вы также знаете, сколько элементов в нем содержится (размер файла / 8 байт).

 DataInputStream dataStream = new DataInputStream(inputStream);

 long count = filesize/8;
 long[] longArray = new long[count];

 for(int i=0;i<count;i++) 
     longArray[i] = dataStream.getLong();

Думаю, этого должно быть достаточно, чтобы дать вам идею.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...