Java 在 Windows 上读取文件非常慢

标签 java io bufferedimage random-access

有人对不同平台上文件 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/

相关文章:

java - 哪个结果验证签名的 XML - 核心验证、签名验证和引用验证

java - 将查询参数添加到 GetMethod(使用 Java commons-httpclient)?

java - BufferedImage 和具有透明度的像素操作

java - BufferedImage,转换为字节数组并返回后相同的图像,但灰度转换后不同

c++ - While 循环检查中的赋值

JavaFX:将像素写入 PixelWriter 的最快方法

java - 构建选定的模块 Maven

java - 如何向该白板添加清晰选项?

c - C语言将二进制文件读入HashTable

java - 你如何在 Java 中 "empty"一个 StringWriter?