Преобразование массива байтов в массив с плавающей точкой - PullRequest
5 голосов
/ 20 февраля 2009

В настоящее время я конвертирую метод Delphi, используемый для произвольного доступа к двоичным файлам, в Java Процедура Delphi использует:

TSingleArray  = Array[0..MAXSIZE] of Single
...
procedure GetLinkValues(const LinkVar: Integer;  const TimePeriod: Integer; var Value: PSingleArray);
...
BlockRead(Fout, Value^, Nlinks*SizeOf(Single));

Чтобы прочитать массив байтов в массив Single. Есть ли эквивалентный способ сделать это в Java без перебора массива?

Я сейчас использую

List<Float> l = new ArrayList<Float>();
…
for (int i = 0 ; i < nLinks ; i++ )
l.add( resultsFile.readFloat());

Но я беспокоюсь о скорости. Порядковый номер не проблема.

Ответы [ 3 ]

9 голосов
/ 20 февраля 2009

Вы профилировали код и фактически обнаружили, что это проблема? Что-то должно быть зациклено ... вы действительно уверены, что это узкое место в вашем коде?

Сказав все это, вы сможете использовать FloatBuffer, который, как я подозреваю, делает то, что вы хотите. К сожалению, JavaDoc у Sun не работает, поэтому я не могу легко ссылаться или просматривать документацию в данный момент.

Чтобы использовать FloatBuffer, вы, вероятно, захотите:

  • Создать FileChannel, связанный с файлом (например, с FileInputStream.getChannel)
  • Создать ByteBuffer
  • Создание FloatBuffer, оборачивающего ByteBuffer, с помощью ByteBuffer.asFloatBuffer
  • Чтение в ByteBuffer с FileChannel.read (byteBuffer)
  • Чтение из буфера Float

Я не очень знаком / не знаком с java.nio, поэтому я надеюсь все это правильно - но, скорее всего, это будет довольно неудобно. Ваш текущий цикл почти наверняка проще, поэтому я настоятельно рекомендую вам сначала проверить его производительность! Возможно, вы захотите обернуть ваш текущий FileInputStream в BufferedInputStream, кстати.

3 голосов
/ 23 февраля 2009

На основании помощи, предоставленной Джоном, окончательный код выглядит следующим образом:

byte[] bt = new byte[nLinks * 4];
List<Float> l = new ArrayList<Float>();
if (linkVar != 0 && timePeriod < nPeriods) {
    long p1 = RECORDSIZE * (nNodes * NODEVARS + nLinks * LINKVARS);
    long p2 = RECORDSIZE * (nNodes * NODEVARS + nLinks * (linkVar - 1));
    long p3 = offset2 + (timePeriod * p1) + p2;
    resultsFile.seek(p3);

    resultsFile.read(bt, 0, nLinks * 4);
    ByteBuffer bb = ByteBuffer.wrap(bt);
    bb.rewind();
    bb.asFloatBuffer().get(values);
}
0 голосов
/ 11 января 2011

Всегда будет где-нибудь цикл - будь то ваш собственный или внутри метода / операции копирования буфера. Единственный способ ускорить процесс - найти оборудование и компилятор, который поддерживает векторные операции.

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