什么是存储这些数据的最佳方式?

问题描述:

我正在创建一个桌面Java应用程序,它需要存储(可能会变成)合理大量的数据。我最初想到了我自己的格式:什么是存储这些数据的最佳方式?

id;name;value,value,value... 
id;name;value,value,value... 

要作为纯文本存储和随机读取/写入。我最初的想法是使用RandomAccessFile;但是,当我插入任意位置时,我遇到了数据被覆盖的问题。

使用现有的数据转移,临时存储,恢复等方法似乎是一个不好的解决方案,特别是因为我打算经常读/写,所以它会变得昂贵。我已经读过,这是底层操作系统的限制,而不是Java本身。

对于频繁访问和写入,整齐存储这些数据的最佳方法是什么?使用SQLite跨越了我的想法。我也想过为每个ID /名称创建一个文件,因为数据值只会被添加到每个文件的末尾,因此不会覆盖任何内容。

+1

这是数据库是为制作。试图处理文件读取/写入会非常缓慢,如果您需要搜索文件,您将获得巨大的性能提升。如果将这些数据存储在数据库中,则可以通过id/name访问,而不必担心文件访问。 – jzworkman 2012-03-16 17:55:55

+0

定义“相当经常”。不知道更多关于数据的信息(它是关系型的吗?平坦的?只有和永远的关键/价值?多少数据?你需要怎么搜索?等等)很难提供有意义的建议。在这一点上看起来更像是一个关键/值数据库而不是文件。 – 2012-03-16 17:57:33

很容易使用数据库来解决这个问题。你不需要一个完整的数据库。最好使用嵌入式数据库。

使用JVM嵌入式数据库如apache derbyberkely-db

+0

这是我想到的想法,这就是为什么我认为SQLite,所以它是独立的。我会看看,谢谢:) – c24w 2012-03-16 18:13:39

+1

@ c24w,imho,apache derby或HSQL db更适合java。另请参阅[本讨论](http://*.com/questions/41233/java-and-sqlite) – 2012-03-19 00:52:14

我会尝试使用数据库。数据库被创建用于存储数据。它们非常易于使用,而且非常简单。我喜欢使用MySQL。这对数据库非常有用。

+0

根据原始问题,他已经在考虑一个数据库(SQLite)。在桌面环境中,独立的MySQL几乎可以肯定对于像这样的相对简单的模式来说太重了(建议使用像嵌入数据库一样的嵌入数据库)。 – mjk 2012-12-31 16:10:28

使用数据库将是最建议的方法。我会告诉你一个可选的方式,让你或未来的读者想要轻松存储中等大小的数据以便快速访问。根据需要调整异常处理。

public class PersistentMap extends HashMap<String, Object> implements Serializable { 
    private static final long serialVersionUID = 0x42424242; 
    private File file; 
    protected PersistentMap(File file) throws Exception { 
     this.file = file; 
     if (file==null || file.isDirectory()) { 
      throw new RuntimeException("ProgramCheck: "+file); 
     } 
     if (!file.exists()) { 
      if (file.getParent()!=null) { 
       new File(file.getParent()).mkdirs(); 
      } 
      save(); 
     } 
     restore(); 
    } 
    public void save() throws Exception { 
     FileOutputStream fos = new FileOutputStream(file); 
     ObjectOutputStream oos = new ObjectOutputStream(fos); 
     oos.writeObject(this); 
     oos.close(); 
     fos.close(); 
    } 
    public void restore() throws Exception { 
     FileInputStream fis = new FileInputStream(file); 
     ObjectInputStream ois = new ObjectInputStream(fis); 
     super.putAll((Map<String,Object>)ois.readObject()); 
     ois.close(); 
     fis.close(); 
    } 
} 

用法:

PersistentMap map = new PersistentMap(new File("myData\\data")); 
System.out.println(" "+map); 
map.put("yoyo","mama"); 
map.save(); 
System.out.println(" "+map); 

输出第1趟:

{} 
{yoyo=mama} 

输出第N运行:

{yoyo=mama} 
{yoyo=mama} 
+0

感谢您的贡献。之前我做过类似的事情,但对于不需要频繁读取/写入的数据 - 在添加很多小数据(为了防止数据丢失)之后调用save会不太昂贵? – c24w 2012-03-16 19:00:18

+1

就CPU%或文件I/O而言,我认为命中率很低。真正的命中是所有数据都在内存中(这就是为什么它如此之快)。添加一个JVM关闭钩子来做最后的保存,你将需要更少的检查点保存。 – Java42 2012-03-16 19:07:52