Java在Windows上读取文件非常慢

时间:2012-04-28 15:59:00

标签: java io bufferedimage random-access

有没有人对不同平台上的文件IO差异有任何经验?我写了一个LWJGL程序,它可以传输100多MB的TIFF文件。在几台Mac和Linux计算机上流式传输相当快,但在我的64位Windows 7桌面上,地图的每个图块似乎需要几秒钟才能加载。

基本上,我创建了一个Tile类实例的2D数组。每个磁贴是TIFF文件的512x512 MB区域,渲染方法检查内存中的磁贴区域是否已加载,如果没有,加载在ThreadPoolExecutor中排队,如果排队没有任何反应,如果加载则是画。对TIFF的访问由TIFF类处理,该类使用RandomAccessFile实例读取文件。这是我用来从TIFF中读取切片的功能

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

1 个答案:

答案 0 :(得分:0)

我怀疑这与您阅读文件的方式有关。我注意到您反复调用名为readByte()seek的方法。如果这些方法正在对无缓冲的流(或RandomAccessFile实例)进行调用,那么您可能正在进行大量的系统调用,这会使您的方法非常慢。

如果这是原因,那么您应该将整个图像文件读入byte[],并使用数组索引来删除所需的字节。如果图像文件太大而无法做到这一点,那么您需要重新构建代码以减少搜索并一次读取多个字节。