【问题标题】:Java: Writing/Reading a Map from diskJava:从磁盘写入/读取地图
【发布时间】:2011-01-19 16:55:17
【问题描述】:

我有一个数据结构,我希望能够在关闭程序之前将其写入文件,然后在下次启动应用程序时从文件中读取以重新填充该结构。

我的结构是HashMap<String, Object>。对象非常简单;对于成员变量,它有一个字符串和两个布尔类型的小型原生数组。这是一个真正简单的应用程序,我预计一次不会超过 10-15 个 <key,value> 对。

我一直在尝试(不成功)对象输入/输出流。我需要使 Object 类可序列化吗?

你能给我任何关于最好的方法的建议吗?我只需要朝着正确的方向前进。谢谢!

编辑:嗯,我还是觉得很笨,我是从一张地图上写,然后读到另一张地图,然后比较它们来检查我的结果。显然我把它们比较错了。叹息。

【问题讨论】:

  • HashMap 已经是可序列化的。当您尝试将其写入 ObjectOutputStream 时出了什么问题?
  • 对象输入/输出流不是唯一的方法。您是否特别需要有关使用它们的建议?还是一般在 I/O 上?
  • @Raedwald - 真的只是在寻找一个简单应用程序的最佳方式。谷歌引导我对象流。
  • @finnw - 我从网上找到的示例中对其进行了编码,但它们都是 示例,我正在处理 。我的 Object 类是可序列化的,但我不确定我是否正确实现它。第一次!
  • 2017 年有一个有趣的库:mapdb.org

标签: java serialization collections file-io


【解决方案1】:

如果你不是特别关心对象,你只需要字符串,字符串的键值对,那么我建议你去java.util.Properties。否则你去吧

        Map map = new HashMap();
        map.put("1",new Integer(1));
        map.put("2",new Integer(2));
        map.put("3",new Integer(3));
        FileOutputStream fos = new FileOutputStream("map.ser");
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        oos.writeObject(map);
        oos.close();

        FileInputStream fis = new FileInputStream("map.ser");
        ObjectInputStream ois = new ObjectInputStream(fis);
        Map anotherMap = (Map) ois.readObject();
        ois.close();

        System.out.println(anotherMap);

【讨论】:

  • 我绝对没有使用 .ser 扩展名,我会试试的。谢谢
  • .ser 扩展名似乎解决了我的问题。现在我将不得不去阅读为什么会这样。你赢了。
  • .ser 不应该是核心问题,你可以在这里提供任何扩展,也没有扩展在这里也可以工作
  • 是的,.ser 扩展对 Java 毫无意义。
  • 我正在从一张地图写入并读取到另一张地图,然后比较它们以检查我的结果。显然我把它们比较错了。叹息。
【解决方案2】:
Map m = new HashMap();
// let's use untyped and autoboxing just for example
m.put("One",1);
m.put("Two",2);

ObjectOutputStream oos = new ObjectOutputStream(
        new FileOutputStream("foo.ser")
);
oos.writeObject(m);
oos.flush();
oos.close();

【讨论】:

    【解决方案3】:

    是的,您的对象需要实现 Serializable 才能被默认的 Java 机制序列化。 HashMapString已经实现了这个接口,可以序列化成功。

    看看 Sun 自己的Serialization tutorial - 它很短,我认为应该涵盖您的简单案例所需的一切。 (您应该能够将Map 对象序列化到流中,然后在后续运行中将其读回)。

    如果您确实遇到问题,请尝试使用一些虚拟值序列化一个简单的HashMap<String, String>。如果这成功了,您就会知道问题出在(不知何故)与您自己的类的可序列化性有关;或者,如果这不起作用,您可以先专注于基本结构,然后再将自己的类加入其中。

    如果您有任何无法自行解决的具体问题,请回复。

    【讨论】:

      【解决方案4】:

      是的,如果您想将一个对象写入文件系统,该对象必须实现SerializeableHere 是一个可以帮助你的教程。

      【讨论】:

      • 你不需要实现Serializeable。仅当您想将 Java 序列化格式作为您的文件格式时才如此。
      • 这不正是提问者想要的吗?他在玩对象输入/输出流...
      • 感谢您的教程。立即阅读!
      【解决方案5】:

      在您了解更多关于它的用途之前,不要费心使其可序列化。你想看看 FileWriter 和 google “java file io” 写这个数据的好方法是 CSV。

      例如。

      key1,key2,key3 值a1,值a2,值a3 值b1,值b2,值b3

      希望这会有所帮助。

      【讨论】:

      • 为什么 csv 比序列化更好?序列化不涉及额外代码,而您必须自己获取/编写 csv 格式化/解析代码。
      • 我们倾向于避免 Serializable 对象,除非我们绝对必须使用它们。他们比人们意识到的要多。和 Raedwald 一样,我也受到 Bloch 的“Effective Java”的影响。
      • csv 有其自身的缺陷。你如何逃避分隔符?你如何逃脱逃脱?等等......仍然不要购买它作为这种简单事物的更好选择。
      • 对于一些简单的选择可能是可以接受的。处理分隔符并不复杂。我只是说人们需要了解序列化的成本。
      • 我们对他的申请一无所知。虽然建议其他序列化方式是个好主意(CSV 也是序列化,只是不是二进制),但它不应该是一个答案,而是发生在 cmets 中。此外,这应该是对他申请中的一个好奇问题的跟进。
      【解决方案6】:

      序列化哈希图: 此代码运行良好,我已在我的应用程序中实现和使用。请制作相应的函数来保存地图和检索地图。

      重要的是,您需要确认您作为值放入 map 的对象必须是可序列化的,这意味着它们应该实现 serailizbele 接口。前任。 Map<.string> hashmap=new HashMap<.string>().. 在这一行中 ...map 和 string 都是隐式可序列化的,所以我们不需要为这些显式实现可序列化但是如果你把您自己的对象必须是可序列化的。


      public static void main(String arr[])
      {
        Map<String,String> hashmap=new HashMap<String,String>();
       hashmap.put("key1","value1");
          hashmap.put("key2","value2");
          hashmap.put("key3","value3");
          hashmap.put("key4","value4");
      
           FileOutputStream fos;
          try {
              fos = new FileOutputStream("c://list.ser");
      
          ObjectOutputStream oos = new ObjectOutputStream(fos);
           oos.writeObject(hashmap);
           oos.close();
      
           FileInputStream fis = new FileInputStream("c://list.ser");
           ObjectInputStream ois = new ObjectInputStream(fis);
          Map<String,String> anotherList = (Map<String,String>) ois.readObject();
      
           ois.close();
      
           System.out.println(anotherList);
      
       } catch (FileNotFoundException e) {e.printStackTrace();
       } catch (IOException e) {e.printStackTrace();
          } catch (ClassNotFoundException e) {e.printStackTrace();
          }
      
      }
      

      【讨论】:

        【解决方案7】:

        我建议不要使用Serializable;正确地做起来比最初看起来要难得多。似乎只需添加implements Serializable 即可。但实际上这对你的代码增加了许多在实际软件开发中(而不是在学校)中难以处理的限制。要了解这些限制有多可怕,请参阅 Bloch 的《Effective Java (second edition)》一书。

        【讨论】:

        • 我同意 Serializable 对于极其持久的数据无效,但对于不需要查询或数据管理的临时持久性,我认为它运作良好。
        猜你喜欢
        • 1970-01-01
        • 2014-01-05
        • 2013-05-13
        • 1970-01-01
        • 2016-12-09
        • 2023-04-02
        • 1970-01-01
        • 2023-03-13
        相关资源
        最近更新 更多