使用LinkedHashMap的多维字节数组...有更好的方法吗?

时间:2010-12-21 19:55:46

标签: java multidimensional-array linkedhashmap

我是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流礼仪非常不熟悉,因此上述代码很可能看起来很草率。我也确信有更有效的方法来完成上述操作,例如放置缓冲区的位置。

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

无论如何,正如我先前所说,请原谅问题,如果答案是显而易见的,我只是一个不起眼的新词:D。我非常感谢任何意见:)。

感谢。

2 个答案:

答案 0 :(得分:1)

如果您的目标是减少I / O开销,那么如何将byte[][][]对象放在一个包含脏标志概念的包装器对象中呢?

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

答案 1 :(得分:0)

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

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