有人对不同平台上文件 IO 的差异有任何经验吗?我编写了一个 LWJGL 程序来传输 100+ MB 的 TIFF 文件。在多台 Mac 和 Linux 计算机上,流传输速度相当快,但在我的 64 位 Windows 7 桌面上,加载 map 的每个图 block 似乎需要几秒钟的时间。
基本上,我创建了 Tile 类实例的二维数组。每个图 block 都是 TIFF 文件的 512x512 MB 区域,渲染方法检查内存中图 block 的区域是否已加载,如果没有,则加载将在 ThreadPoolExecutor 中排队,如果已排队,则不会发生任何情况,如果已加载,则加载画。对 TIFF 的访问由 TIFF 类处理,该类使用 RandomAccessFile 实例读取文件。这是我用来从 TIFF 读取图 block 的函数
public BufferedImage getRasterTile(Rectangle area) {
BufferedImage image = new BufferedImage(area.width, area.height,
BufferedImage.TYPE_INT_RGB);
try {
long[] bytesPerSample = new long[bitsPerSample.length];
for (int i = 0; i < bytesPerSample.length; i++) {
bytesPerSample[i] += bitsPerSample[i] / 8 + bitsPerSample[i]
% 8 == 0 ? 0 : 1;
}
long bytesPerPixel = 0;
for (long bits : bitsPerSample) {
bytesPerPixel += bits / 8 + bits % 8 == 0 ? 0 : 1;
}
long bytesPerRow = bytesPerPixel * imageWidth;
int strip, color;
byte red, green, blue;
for (int i = area.x; i < area.x + area.width; i++) {
for (int u = area.y; u < area.y + area.height; u++) {
if (i > 0 && u > 0 && i < imageWidth && u < imageLength) {
switch (planarConfiguration) {
case Chunky:
strip = (int) (u / rowsPerStrip);
seek(stripOffsets[strip]
+ (u - strip * rowsPerStrip)
* bytesPerRow + i * bytesPerPixel);
red = readByte();
green = readByte();
blue = readByte();
color = (red & 0x0ff) << 16 | (green & 0x0ff) << 8
| (blue & 0x0ff);
image.setRGB(i - area.x, u - area.y, color);
break;
case Planar:
strip = (u / (int) rowsPerStrip);
seek(stripOffsets[strip] + i);
red = readByte();
seek(stripOffsets[strip + (int) imageLength] + i);
green = readByte();
seek(stripOffsets[strip + 2 * (int) imageLength]
+ i);
blue = readByte();
color = (red & 0x0ff) << 16 | (green & 0x0ff) << 8
| (blue & 0x0ff);
image.setRGB(i - area.x, u - area.y, color);
break;
}
} else {
image.setRGB(i - area.x, u - area.y, 0);
}
}
}
} catch (IOException e) {
e.printStackTrace();
return null;
}
return image;
}
最佳答案
我怀疑这与您阅读文件的方式有关。我注意到您重复调用名为 readByte()
和 seek
的方法。如果这些方法在无缓冲流(或 RandomAccessFile
实例)上进行调用,那么您可能会进行大量系统调用,这将使您的方法非常慢。
如果这是原因,那么您可能应该将整个图像文件读入byte[]
,并使用数组索引来找出您需要的字节。如果图像文件太大而无法执行此操作,那么您需要重组代码以减少查找并一次读取多个字节。
关于Java 在 Windows 上读取文件非常慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10365174/