序列化HashMap但输入的文本文件是在每次程序运行时清除self。-JAVA

序列化HashMap但输入的文本文件是在每次程序运行时清除self。-JAVA,java,io,hashmap,fileinputstream,Java,Io,Hashmap,Fileinputstream,我已经研究过这些问题的其他方面,但我认为它们中没有一个和我的相匹配。 我的程序的要点是创建股票的HashMap(键是ticker,值是Stock对象),然后在程序结束时将HashMap导出到文本文件中。下次运行该程序时,我将读取hashMap并继续该程序。到目前为止,我所有的其他功能都在工作,我可以在运行程序后查看文本文件,并在其中看到一些代码,但当我再次运行时,文本文件被清除 我怀疑当我声明一个新的FileInputStream和ObjectInputStream时,他们不知何故删除了该文本文

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

我怀疑当我声明一个新的
FileInputStream
ObjectInputStream
时,他们不知何故删除了该文本文件中的信息,并将其置为空

我的代码如下:

     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);
但是它从不运行此操作,因为
fis.available()
总是返回
0
,因为文件本身会清空


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

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);
}
Map readStocks(ObjectInputStream ois){
//通读
}
无效写入存储(ObjectOutputStream oos、映射存储){
//写全部
}
地图库存;
//使用try-with-resources(Java7+)让生活更轻松;
//OIS(和基础金融机构)保证关闭
//这个街区结束后。
try(ObjectInputStream ois=newobjectinputstream(
新文件输入流(文件)){
存量=存量(ois,存量);
}
//对加载的数据进行更改
//(即根据用户提供的输入)
updateStockData(股票);
try(ObjectOutputStream oos=newobjectoutputstream(
新文件输出流(文件)){
资产负债表(oos、股票);
}
对象输入/输出流只是底层FIS/FOS上的包装器,但不负责较低级别的截断或IO

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


此外,对于同一源上的多个FIS/FOS对象如何工作,操作系统之间也没有很好的定义。文档中只留下了一个模糊的注释(但没有具体说明没有引发异常的FIS/FOS对象之间的交互)

文件输出流是用于将数据写入文件或文件描述符的输出流。特别是,一次只允许一个FileOutputStream(或其他文件写入对象)打开文件进行写入。在这种情况下,如果所涉及的文件已打开,则此类中的构造函数将失败


创建输入流。读取数据。关闭输入流。创建输出流。写入数据。我如何设置要追加的行为?我知道FileWriter追加的实现,但ObjectOutputStream有这样的功能吗?谢谢你的回答!OOS不会打开文件,FOS会打开。请参阅FOS文档。但是,我在这种情况下,对于同一个文件,您确实希望处理所有的输入,然后写入所有的输出(在对数据进行必要的更改之后),在这种情况下,截断行为可以正常工作。我遇到了一个新问题。由于调用fis.available()时出现了错误的文件描述符,程序给了我一个IOException。我以前从未遇到过这个问题,所以我该怎么办?因为我过早地关闭了输入流,所以它们无法访问该文件!
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);
}