Java将多个HashMaps写入文件

时间:2017-03-10 16:19:56

标签: java

我基本上尝试将多个(12个,特别是)HashMap字典写入本地文件,然后检索它们。到目前为止,我设法做一个,但是当我尝试做多个时,我基本上无法使它工作。所以任何帮助做到这一点是值得赞赏的。到目前为止,这是我的代码:

private HashMap<String, List<String>> loadDict() {
    int month = Functions.getMonth();

    //load back in
    FileInputStream fis;
    try {
        fis = new FileInputStream(statsFile);
        ObjectInputStream ois = new ObjectInputStream(fis);
        for (int i = 0; i < 13; i++) {
            //itemsDict = (HashMap) ois.readObject();
            Object whatisThis = (Object) ois.readObject();
            dictionaries.add(whatisThis);
        }
        ois.close();
        fis.close();
    } catch (FileNotFoundException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    } catch (IOException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    } catch (ClassNotFoundException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }

    itemsDict = (HashMap) dictionaries.get(month);
    System.out.println(itemsDict.get("cake"));
    return itemsDict;
}

private void setupDictionaries() {
    HashMap<String, List<String>> dictionary = new HashMap<String,List<String>>();
    FileOutputStream fos;
    try {
        fos = new FileOutputStream(statsFile);
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        for (int i = 0; i < 13; i++) {
            oos.writeObject(dictionary);
        }
        oos.close();
        fos.close();
    } catch (FileNotFoundException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}
private void storeThis(String product, String price, String quantity, String date, List<List<String>> myContent) {//after set, replace dictionary in dictionaries array
    dictionaries.set(Functions.getMonth(), itemsDict);

    //save the dictionary to the overall statistics file
    FileOutputStream fos;
    try {
        fos = new FileOutputStream(statsFile);
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        for (int i = 0; i < 13; i++) {
            oos.writeObject(dictionaries.get(i));
        }
        //oos.writeObject(itemsDict);
        oos.close();
        fos.close();
    } catch (FileNotFoundException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

有点澄清:setupDictionaries仅在第一次运行时调用(设置文件),否则在运行时调用loadDict(),将所有字典加载到arraylist中。从arraylist中,应该选择正确的对象(hashmap),然后将itemsDict作为hashmap。 按下按钮时调用storeThis(),但是我将代码仅减少到相关位。

所以我试图实现你建议的JSON,到目前为止我已经有了:

private void setupDictionaries() {
    ObjectMapper mapper = new ObjectMapper();
    ArrayNode arrayNode = mapper.createArrayNode();
    JsonNode rootNode = mapper.createObjectNode();
    ArrayList<String> myThing = new ArrayList<String>();
    myThing.add("hi");
    myThing.add(".");

    itemsDict.put("cake", myThing);

    JsonNode childNode1 = mapper.valueToTree(itemsDict);
    ((ObjectNode) rootNode).set("Jan",  childNode1);
    JsonNode childNode2 = mapper.createObjectNode();
    ((ObjectNode) rootNode).set("obj2", childNode2);
    JsonNode childNode3 = mapper.createObjectNode();
    ((ObjectNode) rootNode).set("obj3", childNode3);
    String jsonString;
    try {
        jsonString = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(rootNode);
        System.out.println(jsonString);
        ObjectWriter writer = mapper.writer(new DefaultPrettyPrinter());
        writer.writeValue(new File(statsFile), jsonString);
    } catch (JsonProcessingException e2) {
        // TODO Auto-generated catch block
        e2.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

问题,我怎么能加载回来? (只有Jan下面的所有内容,例如,到一个hashmap)

private HashMap<String, List<String>> loadDict() {
    ObjectMapper mapper = new ObjectMapper();
    try {
        HashMap<String, ArrayList<String>> map = mapper.readValue(new File(statsFile), new TypeReference<HashMap<String, ArrayList<String>>>() {});
        System.out.println(map.get("Jan"));
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

使用此代码我可以加载它,但是我得到了这个异常(因为我在Json中有多个hashmaps):

JsonMappingException:无法构造java.util.HashMap的实例:no String-argument构造函数/工厂方法从String值反序列化

(我不知道如何在这里提出例外)

我的JSON:

  

&#34; {\ r \ n \&#34; Jan \&#34; :{\ r \ n \&#34; cake \&#34; :[\&#34; hi \&#34;,\&#34;。\&#34; ] \ r \ n},\ r \ n \&#34; obj2 \&#34; :{},\ r \ n \&#34; obj3 \&#34; :{} \ r \ n}&#34;

那么我怎样才能将特定月份加载到散列图中呢?

2 个答案:

答案 0 :(得分:1)

我肯定会使用Json格式,认为这种格式(纯文本)可让您自由地使用编辑器编辑文件。

我建议使用Jackson库。

您只需创建一个ObjectMapper并使用它来序列化和反序列化json。阅读documentation我看到你也可以读写json文件。

ObjectMapper objectMapper = new ObjectMapper();

例如,此行会将Json字符串转换为Map;

Map<String, Object> map = objectMapper.readValue(json, new TypeReference<Map<String, Object>>() {});

您可以更轻松地将地图转换为Json:

objectMapper.writeValueAsString(json)

问题的其余部分仍然是读取和写入文件。

答案 1 :(得分:0)

如果您有多个独立增长的列表或等价物,并且正在尝试处理单个文件中的存储,那么问题是您希望如何处理重叠。

您写的频率与读取数据的频率之间的关系也很重要。如果它主要是读取和长时间暂停都没问题,那么请使用json格式(每次编辑时都必须重新编写整个json,并且读取必须等到操作完成)。

但是,如果读取和写入的大小相等,那么我认为您需要考虑将数据拆分为连续的部分 - 类似于数据库可能执行的操作。

=============================================== ================================

例如:

meta-data + 1*1024 bytes of 01st map 
meta-data + 1*1024 bytes of 02nd map 
meta-data + 1*1024 bytes of 03rd map 
..
meta-data + 1*1024 bytes of 12th map 
meta-data + 2*1024 bytes of 01st map 
meta-data + 2*1024 bytes of 02nd map 
..
meta-data + 2*1024 bytes of 12th map 
meta-data + 3*1024 bytes of 01st map 
...
and so on..

元数据将告诉您是否继续使用任何给定地图数据的下一部分。

=============================================== ================================

您还必须考虑使用硬盘(顺序访问)还是SSD(随机访问),然后决定使用哪种方法。