我是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。我非常感谢任何意见:)。
感谢。
答案 0 :(得分:1)
如果您的目标是减少I / O开销,那么如何将byte[][][]
对象放在一个包含脏标志概念的包装器对象中呢?
这样,您可以减少修改后写入文件的次数,只有在使用缓存完成后才将脏对象写入磁盘,或者在插入完整缓存时即将删除最旧的对象。 / p>
答案 1 :(得分:0)
我首先要创建一个新类 - 称之为ByteMatrix3D
- 来保存数据。而不是使用byte[][][]
,我使用具有计算偏移的单维数组(例如,在8x8x8数组中,[1][2][3]
的偏移量可以计算为1 * 64 + 2 * 8 + 3
。将消除相当多的对象管理开销,并且还允许您进行其他更改,而不会影响更高级别的代码。
我做的第一个更改是使用MappedByteBuffer
来访问文件。这将使操作系统管理实际数据,并使读取和写入对程序透明。