将序列化对象写入文件
Writing an serialized object to a file
我在 将 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 向我显示:
什么是合适的文件路径?我应该使用哪种数据类型?
感谢您的帮助
如果您收到消息 "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
.
的堆栈跟踪
关于此 "beginner" 代码还应说明的其他几点。
这样做是个坏主意:
} catch (IOException ioException) {
System.err.println("Error opening file.");
}
为什么?因为在报错之后,你是在告诉代码继续,就好像什么事都没发生过一样。接下来您将尝试使用 objectOutputStream
... 尚未初始化!
您应该构建代码,以便您不会在应该被您的代码视为致命错误之后继续。
如果您在 real-life 可能会重复打开文件的程序中执行此操作,那么您很可能会泄露文件描述符。打开和使用文件的正确模式(对于 Java 6 及更高版本)是使用 "try-with-resources" 结构;例如
try (FileOutputStream out = new FileOutputStream(...)) {
// write stuff
}
当 try
的正文结束时,开始时打开的资源将自动关闭。这种情况 在所有重要的情况下都会发生 。相比之下,如果您手动关闭资源,则存在无法在所有情况下全部关闭的风险。
首先,我们可以尝试在 public 目录中写入,以便使用任何文件管理器应用程序轻松检查结果。
在写入文件系统之前确保 AndroidManifest.xml
包含两个权限请求:
<manifest ...>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
...
</manifest>
如果您的设备或 emulator/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
我在 将 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 向我显示:
什么是合适的文件路径?我应该使用哪种数据类型?
感谢您的帮助
如果您收到消息 "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
.
关于此 "beginner" 代码还应说明的其他几点。
这样做是个坏主意:
} catch (IOException ioException) { System.err.println("Error opening file."); }
为什么?因为在报错之后,你是在告诉代码继续,就好像什么事都没发生过一样。接下来您将尝试使用
objectOutputStream
... 尚未初始化!您应该构建代码,以便您不会在应该被您的代码视为致命错误之后继续。
如果您在 real-life 可能会重复打开文件的程序中执行此操作,那么您很可能会泄露文件描述符。打开和使用文件的正确模式(对于 Java 6 及更高版本)是使用 "try-with-resources" 结构;例如
try (FileOutputStream out = new FileOutputStream(...)) { // write stuff }
当
try
的正文结束时,开始时打开的资源将自动关闭。这种情况 在所有重要的情况下都会发生 。相比之下,如果您手动关闭资源,则存在无法在所有情况下全部关闭的风险。
首先,我们可以尝试在 public 目录中写入,以便使用任何文件管理器应用程序轻松检查结果。
在写入文件系统之前确保 AndroidManifest.xml
包含两个权限请求:
<manifest ...>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
...
</manifest>
如果您的设备或 emulator/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