4

我对 Java 编程非常陌生,所以请原谅我的新问题:)。

为了协助开发,我正在使用 LinkedHashMap 作为我正在修改的应用程序的文件缓存。我这样做是为了减少 I/O 开销,从而提高性能。这样做的问题是开销以许多其他方式引入。

相关来源看起来像这样。


// Retrieve Data From LinkedHashMap  
byte grid[][][] = null;  
if(file.exists())
{  
    if (!cache.containsKey(file))  
    {
        FileInputStream fis = new FileInputStream(file);
        BufferedInputStream bis = new BufferedInputStream(fis, 16384);
        ObjectInputStream ois = new ObjectInputStream(bis);
        cache.put(file, ois.readObject());
        ois.close();
    }
    grid = (byte[][][]) cache.get(file);
} else {
    grid = new byte[8][8][];
}

以下是我用来保存数据的。加载数据的方法正好相反。


ByteArrayOutputStream baos = new ByteArrayOutputStream();
GZIPOutputStream gos = new GZIPOutputStream(baos){{    def.setLevel(2);}};
BufferedOutputStream bos = new BufferedOutputStream(gos, 16384);
DataOutputStream dos = new DataOutputStream(bos);
// Some code writes to dos
dos.close();
byte[cx][cz] = baos.toByteArray();
baos.close();
cache.put(file, grid);

这是缓存的声明。


private static LinkedHashMap<File, Object> cache = new LinkedHashMap<File, Object>(64, 1.1f, true)
{protected boolean removeEldestEntry(Map.Entry<File, Object> eldest) 
    {
        return size() > 64;
    }
}

由于本人对Java流的礼仪很不熟悉,很可能上面的代码看起来很草率。我也确信有更有效的方法来完成上述操作,例如将缓冲区放在哪里。

无论如何,我的主要问题是:每当我需要对单个块做任何事情时,我必须将所有网格数据转换为一个对象,将其发送到缓存,然后写入文件。这是一种非常低效的做事方式。我想知道是否有更好的方法可以做到这一点,这样我就不必 get(); 当我只需要访问那个块时,整个 byte[8][8][] 数组。我很想做类似 chunk = cache.get[cx]cz 之类的事情,但我敢肯定它不是那么简单。

无论如何,正如我之前所说,如果答案很明显,请原谅这个问题,我只是一个卑微的新手:D。我非常感谢任何输入:)。

谢谢。

4

2 回答 2

1

如果您的目标是减少 I/O 开销,那么将byte[][][]对象放在添加脏标志概念的包装对象中怎么样?

这样,您可以减少文件在修改时写入的次数,仅当您完成使用缓存或在插入完整缓存时将删除最旧的对象时才将脏对象写入磁盘。

于 2010-12-21T21:17:51.153 回答
0

我将首先创建一个新类——称之为ByteMatrix3D——来保存数据。而不是使用byte[][][],我会使用具有计算偏移量的单维数组(例如,在 8x8x8 数组中,偏移量[1][2][3]可以计算为1 * 64 + 2 * 8 + 3。这种更改将消除相当多的对象管理开销,也让你在不影响更高级别代码的情况下进行其他更改。

我要做的第一个更改是使用 aMappedByteBuffer来访问文件。这将使操作系统管理实际数据,并使读取和写入对程序透明。

于 2010-12-21T21:18:23.593 回答