将字节数组转换为浮点数组

时间:2009-02-20 16:52:47

标签: java delphi arrays

我目前正在将用于随机二进制文件访问的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 个答案:

答案 0 :(得分:9)

您是否对代码进行了分析并确实发现它有问题? Something 将不得不循环...你真的确定这是你代码中的瓶颈吗?

说了这么多,你应该能够使用FloatBuffer,我怀疑它可以做你想要的。不幸的是,Sun的JavaDoc已关闭,因此我无法在一分钟内轻松链接或查看文档。

要使用FloatBuffer,您可能希望:

  • 创建与文件关联的FileChannel(例如,使用FileInputStream.getChannel)
  • 创建一个ByteBuffer
  • 使用ByteBuffer.asFloatBuffer创建一个包装ByteBuffer的FloatBuffer
  • 使用FileChannel.read(byteBuffer)
  • 读入ByteBuffer
  • 从FloatBuffer中读取

我对java.nio并不是特别熟悉/熟悉,所以我希望这一切都是正确的 - 但它可能非常繁琐。你当前的循环几乎肯定更简单,所以我强烈建议你先检查一下它的性能!您可能希望将当前的FileInputStream包装在BufferedInputStream中,顺便说一句。

答案 1 :(得分:3)

根据Jon提供的帮助,最终代码如下所示:

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);
}

答案 2 :(得分:0)

总会有一个循环 - 无论是你自己的,还是内部的缓冲区复制方法/操作。加快速度的唯一方法是找到支持向量运算的硬件和编译器。