附加到 ObjectOutputStream 不会改变任何东西
Appending to ObjectOutputStream does not change anything
这是我的问题。在我的 DetailActivity 中,我检查文件是否为空。如果是,我创建一个新文件并将对象写入该文件没问题。如果不是,这意味着该文件有一个写入数据对象的列表,如下所示:
try{
val file = File(filesDir, "Example Shelf")
val outputStream = openFileOutput(file.name, Context.MODE_APPEND)
if(file.length() != 0.toLong()){
val inputStream = openFileInput(file.name)
gameDetailViewModel.addGameToExistingShelf(outputStream, inputStream, data)
} else {
file.createNewFile()
gameDetailViewModel.addGameToNewShelf(outputStream, data)
} catch(...)
如果文件中写入了一个对象,我基本上想将一个新的数据对象附加到该列表中。为此,我读取了文件,将从文件中读取的列表分配给一个新变量,然后将其重新写入文件。
fun addGameToExistingShelf(fos: FileOutputStream, fis: FileInputStream, data: GameData){
val previousList = ObjectInputStream(fis).readObject() as MutableList<GameData>
val newList = previousList
newList.add(data)
ObjectOutputStream(fos).writeObject(newList)
fos.close()
fis.close()
}
问题:一旦文件被写入,我想从另一个Activity读取它,这样我就可以在 RecyclerView 中显示它。但是当我读取文件时,它不包括添加到我最近写入文件的 newList
的任何数据对象。它仅包括 previousList
中的数据对象,这是此时的陈旧数据。
val file = File(filesDir, "Example Shelf")
if(file.isFile && file.length() != 0.toLong()){
val inputStream = openFileInput(file.name)
shelfViewModel.fetchShelfData(inputStream)
}
ShelfViewModel.fetchShelfData
fun fetchShelfData(fis: FileInputStream){
val objis = ObjectInputStream(fis)
//MutableLiveData<List<GameData>>
shelfData.value = objis.readObject() as List<GameData>
objis.close()
}
这里发生了什么?我花了几个小时试图调试它无济于事。
任何帮助将不胜感激。提前谢谢你:)
进一步阅读后,我发现无法将数据附加到已存在的文件中,因为 ObjectOutputStream
将 header 添加到它对文件的所有写入操作。
对同一文件多次调用 ObjectOutputStream.writeObject(data)
将导致文件损坏,因为存在多个 header。当 ObjectInputStream
随后读取文件时,它不够聪明,无法解析出写入文件的所有额外内容(例如 header)。请参阅 here 文档。
为了解决这个问题,我只是使用 file.createNewFile()
重新创建了一个新文件并将新数据写入其中。因为文件本质上是“重新创建的”,所以以前写入的所有 header 信息都不再存在 - 它是一个同名的空白文件。
if(file.length() != 0.toLong()){
val fileInput = openFileInput(file.name)
val newData = gameDetailViewModel.fetchDataFromExistingShelf(fileInput, data)
file.createNewFile() //File is recreated
val fileOutput = openFileOutput(file.name, Context.MODE_PRIVATE)
gameDetailViewModel.writeObjectToFile(fileOutput, newData) //Object is written to new, recreated file
考虑到我花了几个小时尝试调试它,我希望它能帮助后来的人!
这是我的问题。在我的 DetailActivity 中,我检查文件是否为空。如果是,我创建一个新文件并将对象写入该文件没问题。如果不是,这意味着该文件有一个写入数据对象的列表,如下所示:
try{
val file = File(filesDir, "Example Shelf")
val outputStream = openFileOutput(file.name, Context.MODE_APPEND)
if(file.length() != 0.toLong()){
val inputStream = openFileInput(file.name)
gameDetailViewModel.addGameToExistingShelf(outputStream, inputStream, data)
} else {
file.createNewFile()
gameDetailViewModel.addGameToNewShelf(outputStream, data)
} catch(...)
如果文件中写入了一个对象,我基本上想将一个新的数据对象附加到该列表中。为此,我读取了文件,将从文件中读取的列表分配给一个新变量,然后将其重新写入文件。
fun addGameToExistingShelf(fos: FileOutputStream, fis: FileInputStream, data: GameData){
val previousList = ObjectInputStream(fis).readObject() as MutableList<GameData>
val newList = previousList
newList.add(data)
ObjectOutputStream(fos).writeObject(newList)
fos.close()
fis.close()
}
问题:一旦文件被写入,我想从另一个Activity读取它,这样我就可以在 RecyclerView 中显示它。但是当我读取文件时,它不包括添加到我最近写入文件的 newList
的任何数据对象。它仅包括 previousList
中的数据对象,这是此时的陈旧数据。
val file = File(filesDir, "Example Shelf")
if(file.isFile && file.length() != 0.toLong()){
val inputStream = openFileInput(file.name)
shelfViewModel.fetchShelfData(inputStream)
}
ShelfViewModel.fetchShelfData
fun fetchShelfData(fis: FileInputStream){
val objis = ObjectInputStream(fis)
//MutableLiveData<List<GameData>>
shelfData.value = objis.readObject() as List<GameData>
objis.close()
}
这里发生了什么?我花了几个小时试图调试它无济于事。 任何帮助将不胜感激。提前谢谢你:)
进一步阅读后,我发现无法将数据附加到已存在的文件中,因为 ObjectOutputStream
将 header 添加到它对文件的所有写入操作。
对同一文件多次调用 ObjectOutputStream.writeObject(data)
将导致文件损坏,因为存在多个 header。当 ObjectInputStream
随后读取文件时,它不够聪明,无法解析出写入文件的所有额外内容(例如 header)。请参阅 here 文档。
为了解决这个问题,我只是使用 file.createNewFile()
重新创建了一个新文件并将新数据写入其中。因为文件本质上是“重新创建的”,所以以前写入的所有 header 信息都不再存在 - 它是一个同名的空白文件。
if(file.length() != 0.toLong()){
val fileInput = openFileInput(file.name)
val newData = gameDetailViewModel.fetchDataFromExistingShelf(fileInput, data)
file.createNewFile() //File is recreated
val fileOutput = openFileOutput(file.name, Context.MODE_PRIVATE)
gameDetailViewModel.writeObjectToFile(fileOutput, newData) //Object is written to new, recreated file
考虑到我花了几个小时尝试调试它,我希望它能帮助后来的人!