【问题标题】:Writing an serialized object to a file将序列化对象写入文件
【发布时间】:2018-02-16 12:35:20
【问题描述】:

将 Java 对象保存到文件时遇到问题。我正在使用 Android Studio 编写应用程序。

Outgoing 是我要保存的对象,它包含两个Strings,和一个int

private FileOutputStream fileOutputStream;
private ObjectOutputStream objectOutputStream;

public void save(String name, String category, int price){

    // Open file
    try {
        fileOutputStream = new FileOutputStream("outgoings.tmp");
        objectOutputStream = new ObjectOutputStream(fileOutputStream);
    } catch (IOException ioException) {
        System.err.println(ioException.getMessage());
    }

    // Saving
    Outgoing record;
    Scanner input = new Scanner(System.in);

    while (input.hasNext()) {
        try{
            if(name != null){
                record = new Outgoing(name, category, price);
                objectOutputStream.writeObject(record);
            }
        }
        catch(IOException ioException){
            System.err.println(ioException.getMessage());
        }
    }

    // Close file
    try{
        objectOutputStream.close();
    }
    catch (IOException ioException) {
        System.err.println(ioException.getMessage());
    }
}

当我启动应用程序时,执行方法save(),应用程序崩溃。

// Open file
try {
    fileOutputStream = new FileOutputStream("outgoings.tmp");
    objectOutputStream = new ObjectOutputStream(fileOutputStream);
} catch (IOException ioException) {
    System.err.println(ioException.getMessage());
}

--> IOException 被抛出,Logcat 显示:

什么是合适的文件路径和我应该使用哪种数据类型?

感谢您的帮助

【问题讨论】:

  • 它无法打开文件....?确保当前工作目录是可写的。
  • 您的问题的明显答案是由于某些问题无法打开文件。
  • 我怀疑这与您正在序列化一个包含另一个类的对象的类有关。
  • 我认为您不能在 Android 上创建相对文件,请尝试使用文件的完整路径
  • 你有什么问题?

标签: java android android-studio object saving-data


【解决方案1】:

如果您收到消息"Error opening file.",则表示对openFile() 的调用失败:

public void openFile() {
    try {
        fileOutputStream = new FileOutputStream("outgoings.tmp");
        objectOutputStream = new ObjectOutputStream(fileOutputStream);
    } catch (IOException ioException) {
        System.err.println("Error opening file.");
    }

ObjectOutputStream 构造函数在这种情况下几乎不会失败,所以问题一定是new FileOutputStream("outgoings.tmp") 抛出了IOException,最可能的解释是你没有创建权限当前目录中的一个文件。 (其他解释是可能的......)

要深入了解,您需要修改代码以打印或记录 IOException 的堆栈跟踪。


关于这个“初学者”代码应该说明的其他几点。

  1. 这样做是个坏主意:

    } catch (IOException ioException) {
        System.err.println("Error opening file.");
    }
    

    为什么?因为在报告错误之后,您是在告诉代码继续执行,就好像什么都没发生一样。接下来您将尝试做的事情是使用尚未初始化的objectOutputStream ...!

    您应该对代码进行结构化,以便在您的代码应该将其视为致命错误之后,您不会继续。

  2. 如果您在可能重复打开文件的实际程序中执行此操作,那么您很可能会泄漏文件描述符。打开和使用文件的正确模式(对于 Java 6 及更高版本)是使用“try-with-resources”构造;例如

    try (FileOutputStream out = new FileOutputStream(...)) {
        // write stuff
    }
    

    try 的正文结束时,开始时打开的资源将自动关闭。这在所有重要的情况下都会发生。相比之下,如果您手动关闭资源,则存在在所有情况下都不会全部关闭的风险。

【讨论】:

  • 感谢您的帮助。是的,我是新人,每个人都必须从某个地方开始。我现在明白为什么我的异常哪里错了。我编辑了我的问题。现在好点了吗?什么能解决我的问题?
  • 堆栈跟踪显示由于我描述为“这样做是个坏主意”的代码,您已经获得了 NPE。解决您的问题:1)彻底阅读我的回答,以便您理解我在说什么,2)解决我指出的“坏主意”问题。
  • 来自异常的错误消息显示“EROFS - 只读文件系统”。显然,您尝试打开文件的位置是只读文件系统。只读意味着你不能在那里写!!解决方案,1)阅读平台文档以找到写入文件的适当目录路径,2)将代码更改为写入该目录......而不是当前目录”。
  • (3) 不要自己编造错误信息。打印异常。
【解决方案2】:

首先我们可以尝试在公共目录中写入,以便使用任何文件管理器应用程序轻松检查结果。

在写入文件系统之前,确保AndroidManifest.xml 包含两个权限请求:

<manifest ...>

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

...
</manifest>

如果您的设备或模拟器/VM 运行 Android 5 或更低版本,我们可以继续写入文件。如果不是,请查看android developer documentation关于运行时请求权限的部分。

这里有一些代码可以让您以 95% 的概率为您提供可写目录:

File destination = new File(Environment.getExternalStorageDirectory(), "My Cool Folder");
destination.mkdirs();

所以现在你可以尝试在那里写一个文件

fileOutputStream = new FileOutputStream(new File(destination, "outgoings.tmp"));
//write there anything you want

【讨论】:

  • 谢谢。在创建的文件夹中保存工作(它创建了文件:“outgoings.tmp”)。如何阅读此顺序文件?
  • @PascalBurkard 你最好根据 SO 规则发布另一个关于此的问题 :)
猜你喜欢
  • 1970-01-01
  • 2018-04-18
  • 2013-04-27
  • 2011-12-14
  • 2013-06-22
  • 1970-01-01
  • 2017-11-06
  • 2020-07-18
  • 1970-01-01
相关资源
最近更新 更多