java - 序列化 HashMap 但输入文本文件会在每次程序运行时清除自身。 -- java

标签 java io hashmap fileinputstream

我已经研究过这些问题的其他问题,但我认为它们都不符合我的问题。 我的程序的要点是创建股票的 HashMap (键是股票,值是 Stock 对象),然后在程序结束时导出 hashMap 到文本文件中。下次运行该程序时,我将读取 hashMap 并继续该程序。到目前为止,我所有其他功能主义者都在工作,我可以在运行程序后查看文本文件,并在其中看到一些代码,但是当我再次运行时,文本文件被清除。

我怀疑,当我声明一个新的 FileInputStreamObjectInputStream 时,它们会以某种方式删除该文本文件中的信息并使其为空。

我的代码如下:

     stockInfo = new HashMap<String, Stock>(10000);
     Scanner in = new Scanner(System.in);
     File file = new File("mp4output.txt");
     fos = new FileOutputStream(file);
     oos = new ObjectOutputStream(fos);
     fis = new FileInputStream(file);
     ois = new ObjectInputStream(fis);

这是我如何声明要在 hashMap 中读取的 I/O 流。

接下来我尝试实际读取 hashMap

           try {
           while (fis.available() > 0)   {
                 Stock test = (Stock) ois.readObject(); 
                 System.out.println("Stock: " + test.getCompany());
                 System.out.println("High: " + test.getHigh());
                 System.out.println("Volume: " + test.getHigh());
                 System.out.println("Low: " + test.getLow());
                 System.out.println("Close: " + test.getClose());
                 System.out.println("Open: " + test.getOpen());
                 System.out.println("Range: " + test.getRange());
                 System.out.println("52 Week average: " + test.getFiftyAvg());
                 System.out.println("Current Price: " + test.getcurrentPrice());
                 }
           }
           catch (Exception ex) {
                 ex.printStackTrace();
           }

但是它永远不会运行这个,因为 fis.available() 总是返回 0 因为文件会清空自己。

我觉得我在某个地方犯了一个非常愚蠢的错误,但我找不到它。任何帮助将不胜感激!

最佳答案

默认情况下(或者每当 not created for appending 时),FileOutputStream 将截断输出文件。这种截断发生在 FOS 创建时、FIS 有机会读取数据之前。

在这种情况下(输入和输出位于同一个文件),一般解决方案是读取所有输入,关闭输入流,然后然后 打开输出流并写入新数据。在这种情况下,截断行为效果很好。

考虑到这一点,骨架可能看起来像这样:

Map<String, Stock> readStocks (ObjectInputStream ois) {
  // Read all
}

void writeStocks (ObjectOutputStream oos, Map<String, Stock> stocks) {
  // Write all
}

Map<String, Stock> stocks;
// Use try-with-resources (Java 7+) to make life easier;
// the OIS (and underlying FIS) are guaranteed to be closed
// after this block ends.
try (ObjectInputStream ois = new ObjectInputStream(
         new FileInputStream(file)) {
  stocks = readStocks(ois, stocks);
}

// Make changes to loaded data
// (i.e. in accordance with user-supplied input)
updateStockData(stocks);

try (ObjectOutputStream oos = new ObjectOutputStream(
         new FileOutputStream(file)) {
  writeStocks(oos, stocks);
}

对象输入/输出流只是底层 FIS/FOS 的包装器,但不负责较低级别的截断或 IO。

此外,虽然 OIS/OOS 可能足以完成此任务,但我建议使用 JSON因为使用 JSON 与 POJO 映射器“相对轻松”(例如,参见 Gson),而且 - 我推荐它的真正原因 - 输出是人类可使用的文本。


此外,对于同一源上的多个 FIS/FOS 对象如何工作,跨操作系统也没有明确定义。该文档留下了这个模糊的注释(但没有指定有关不抛出异常的 FIS/FOS 对象之间交互的任何信息)。

A file output stream is an output stream for writing data to a File or to a FileDescriptor. in particular, allow a file to be opened for writing by only one FileOutputStream (or other file-writing object) at a time. In such situations the constructors in this class will fail if the file involved is already open.

关于java - 序列化 HashMap 但输入文本文件会在每次程序运行时清除自身。 -- java ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22275592/

相关文章:

java - 从 PDf 到字符串

java - java中的哈希表给了我最后存储的值,但不是正确的值

java - 如何在 TABLE FORM 中显示来自不同表的列

java - 使用 parLapply 将数据帧写入 Oracle 数据库时出现 JVM 错误

bash - 具有文件描述符的重复 IO

java - 查找 HashMap 是否包含值并仅删除该值

java-无法将查询返回的对象映射到正确定义的类

java - 我在哪里向 SOLR 提交 XML

java - 使用 Spring 配置文件运行 gradle 任务(集成测试)

multithreading - 异步非阻塞循环与多线程的真实例子?