I want to save all elements of a HashMap in a file. To do this I wrote following code with the help of some google searches:
public void saveCalendars() {
try {FileOutputStream fos = new FileOutputStream(CALENDARPATH_STRING);
ObjectOutputStream oos = new ObjectOutputStream(fos);
for(Calendar elementCalendar : calendarRegister.values()) {
oos.writeObject(elementCalendar);
}
oos.close();
fos.close();
} catch (FileNotFoundException e) {
System.out.println("File not found");
try {FileOutputStream fos = new FileOutputStream(new File(CALENDARPATH_STRING));
ObjectOutputStream oos = new ObjectOutputStream(fos);
for(Calendar elementCalendar : calendarRegister.values()) {
oos.writeObject(elementCalendar);
}
oos.close();
fos.close();
} catch (IOException ex) {
System.out.println("Creating: Error initializing stream");
}
} catch (IOException e) {
System.out.println("Save: Error initializing stream");
}
}
With final static String CALENDARPATH_STRING = "C:\\Windows\\calendars.dat";.
I thought that I simply could use the same Code but with FileOutputStream fos = new FileOutputStream(new File(CALENDARPATH_STRING)); if the file hasn't been created yet to create one.
Unfortunately, it doesn't work. It's the firs time, that a make such saving stuff, so maybe you can help me.
A couple of suggestions:
Use File.createNewFile to create a new file and verify it's result
Use try-with-resources when dealing with IO stuff (I assume you use > JDK 7). You can read more about this feature on official site.
You can avoid duplications:
File calendarFile = new File(CALENDARPATH_STRING);
try {
if(calendarFile.createNewFile()) {
System.out.println("File not found. New file was created");
}
} catch (IOException e) {
System.out.printf("Can not create file %s\n", CALENDARPATH_STRING);
}
try(FileOutputStream fos = new FileOutputStream(calendarFile);
ObjectOutputStream oos = new ObjectOutputStream(fos)) {
for(Calendar elementCalendar : calendarRegister.values()) {
oos.writeObject(elementCalendar);
}
} catch (IOException e) {
System.out.println("Save: Error initializing stream");
}
Well, I can see that there is an issue with the path of your file CALENDAR_PATH_STRING
and use new File(CALENDAR_PATH_STRING) it would create a new file if the particular file was not found. Also in local I can see it is working.
public void saveCalendars(Map<String, Calendar> calendarRegister) {
try (FileOutputStream fos = new FileOutputStream(new File(CALENDAR_PATH_STRING));
ObjectOutputStream oos = new ObjectOutputStream(fos)) {
for (Calendar elementCalendar : calendarRegister.values()) {
oos.writeObject(elementCalendar);
}
} catch (IOException e) {
System.out.println("Creating: Error initializing stream");
}
}
Related
I am trying to add objects (people's names, phone numbers etc.) to a file and then reading it. When I run the program and add a few objects to the file, only the first object contains the header and the ones after the first one does not, which is what I want.
However, if I close the program and then rerun it, the previous objects are still there and functioning, but if I add a new object to the file, the program treats it as "the first object", so gives it a header, which causes an error when the program tries to read the information stored in the object.
This is my "add to file" code:
try {
FileOutputStream fos = new FileOutputStream("outputfile.ser", true);
oos = new ObjectOutputStream(fos);
}
catch (NotSerializableException e1) {
System.out.println("An object was not serializable, it has not been saved.");
e1.printStackTrace();
}
catch (IOException e1) {
e1.printStackTrace();
}
JButton btnAddContact = new JButton("Add Contact");
btnAddContact.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Address newContact = new Address(firstNameTextField.getText(), lastNameTextField.getText(), homePhoneNumberTextField.getText(), mobilePhoneNumberTextField.getText(), addressTextArea.getText(), emailTextField.getText());
try {
oos.writeObject(newContact);
}
catch (IOException e1) {
System.out.println("An object was not serializable, it has not been saved.");
e1.printStackTrace();
}
dispose();
firstNameTextField.setText("");
lastNameTextField.setText("");
homePhoneNumberTextField.setText("");
mobilePhoneNumberTextField.setText("");
addressTextArea.setText("");
emailTextField.setText("");
}
});
btnAddContact.setBounds(165, 384, 110, 46);
contentPane.add(btnAddContact);
I also thought that if i checked if the file is empty or not using if (file.length() == 0) would work, but it still doesn't work. sample of my code with this implemented:
File file = new File("outputfile.ser");
FileOutputStream fos = new FileOutputStream(file);
ObjectOutputStream oos = new ObjectOutputStream(fos);
ObjectOutputStream oas = AppendingObjectOutputStream(new FileOutputStream(file, true));
if (file.length() == 0){
try {
oos.writeObject(newContact);
}
catch (IOException e1) {
System.out.println("An object was not serializable, it has not been saved.");
e1.printStackTrace();
}
} else {
try {
oas.writeObject(newContact);
}
catch (IOException e1) {
System.out.println("An object was not serializable, it has not been saved.");
e1.printStackTrace();
}
}
public class AppendingObjectOutputStream extends ObjectOutputStream {
public AppendingObjectOutputStream(OutputStream oas) throws IOException {
super(oas);
}
protected void writeStreamHeader() throws IOException {
// do not write a header, but reset:
reset();
}
}
Is there any way to solve this problem?
Your first FileOutputStream fos = new FileOutputStream(file); will overwrite any existing file.
Try at first to change it FileOutputStream fos = new FileOutputStream(file, true);.
But I discourage opening at the same time the same file. You probably need to rework the logic.
in one of the activities when a button is pressed i want to create a file on the extran storage. so i wrote
the below code to do so.
but in the end the file is created but empty..why?
code:
public void tx(byte[] data) {
Log.w(TAG, CSubTag.bullet("tx"));
File file = new File(Environment.getExternalStorageDirectory() + File.separator + "test.txt");
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
try {
OutputStream os = new FileOutputStream(file);
BufferedOutputStream bos = new BufferedOutputStream(os);
try {
bos.write("data_stream".getBytes());
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
Please close the OutputStream and BufferedOutputStream inside finally block. Otherwise, the data will not be written.
I have this method supposed to read a file:
/* Read file's content */
private ArrayList<String> readFromFile() {
File file = new File("jokesBody1.bjk");
ArrayList<String> list = new ArrayList<String>();
try {
file.createNewFile();
ObjectInputStream ois = new ObjectInputStream( new FileInputStream( file ) );
try {
list = (ArrayList)ois.readObject();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
ois.close();
} catch (IOException e) {
Log.e("log activity", "Can not read file: " + e.toString());
}
return list;
}
When I call it, it returns:
02-16 06:15:32.686: E/log activity(1380): Can not read file: java.io.IOException: open failed: EROFS (Read-only file system)
Even, if the file is read only, why I can't read it? I really can't understand what is wroong. I have this premission in my manifest:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Can someone give me a clue? I know that I'm missing something small, but I really can't spot it.
Here is how I write the file:
/* Write content to a file */
private void writeToFile(ArrayList<String> list, Context cont) {
File file = new File("jokesBody1.bjk");
FileOutputStream fos;
if(list != null){
try {
fos = cont.openFileOutput("jokesBody1.bjk", Context.MODE_PRIVATE);
ObjectOutputStream out = new ObjectOutputStream(fos);
out.writeObject(list);
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}else{
try {
file.createNewFile();
fos = openFileOutput("jokesBody1.bjk",Context.MODE_PRIVATE);
ObjectOutputStream out = new ObjectOutputStream(fos);
out.writeObject("");
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
You are trying to create the file, which of course fails on a read-only file.
Remove this line:
file.createNewFile();
This is usually used to create a new empty file before writing to it. You really don't need it if you just want to read a file that already exists.
EDIT:
Just use this:
ObjectInputStream ois = new ObjectInputStream( context.openFileInput("jokesBody1.bjk"));
Of course, you'll also have to pass a Context to the function.
You can only use File with a full path. For accessing your private files, use Context, just as you do when saving the file.
Your full function should look like:
private ArrayList<String> readFromFile(Context context) {
ArrayList<String> list = new ArrayList<String>();
try {
ObjectInputStream ois = new ObjectInputStream( context.openFileInput("jokesBody1.bjk"));
try {
list = (ArrayList)ois.readObject();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
ois.close();
} catch (IOException e) {
Log.e("log activity", "Can not read file: " + e.toString());
}
return list;
}
You aren't specifying any path:
File file = new File("jokesBody1.bjk");
So, you are not saying the app WHERE to look for the file.
Maybe, you want to search it here?
Environment.getExternalStorageDirectory()
I have the below 2 methods, supposed to read and write to a file:
/* Write content to a file */
private void writeToFile(ArrayList<String> list) {
#SuppressWarnings("unused")
File file = new File("jokesBody1.bjk");
FileOutputStream fos;
if(list != null){
try {
fos = openFileOutput("jokesBody1.bjk",Context.MODE_PRIVATE);
ObjectOutputStream out = new ObjectOutputStream(fos);
out.writeObject(list);
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}else{
try {
fos = openFileOutput("jokesBody1.bjk",Context.MODE_PRIVATE);
ObjectOutputStream out = new ObjectOutputStream(fos);
out.writeObject("");
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/* Read file's content */
private ArrayList<String> readFromFile() {
File file = new File("jokesBody1.bjk");
ArrayList<String> list = new ArrayList<String>();
try {
ObjectInputStream ois = new ObjectInputStream( new FileInputStream( file ) );
try {
list = (ArrayList)ois.readObject();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
ois.close();
} catch (IOException e) {
Log.e("log activity", "Can not read file: " + e.toString());
}
return list;
}
When I'm calling the above methods I'm getting this error:
02-15 10:28:48.165: E/log activity(1743): Can not read file: java.io.FileNotFoundException: /jokesBody1.bjk: open failed: ENOENT (No such file or directory)
Ok, it clearly says that the file is not there, but, isn't this code supposed to create it:
File file = new File("jokesBody1.bjk");
Why I'm getting this error? I know that I'm missing something small - probably a piece of code that creates the file(I'm not sure), but as a beginner, I'm not able to spot the issue.
File file = new File("jokesBody1.bjk");
Just creates a File objects that points to that path, but no actual file.
Use
file.createNewFile();
To actually create the file.
Ok, it clearly says that the file is not there, but, isn't this code supposed to create it:
Actually, no. It only creates a File object, an then java assumes that file to exist.
I am using the following method to read from the internal storage:
private void deserialize(ArrayList<Alias>arrayList) {
try {
FileInputStream fis = openFileInput(filename);
ObjectInputStream ois = new ObjectInputStream(fis);
arrayList = (ArrayList<Alias>)ois.readObject();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
It reads the content of the file "filename" to the "arrayList".
The "serialize" method is as follows:
void serialize(ArrayList<Alias>arrayList) {
FileOutputStream fos;
try {
fos = openFileOutput(filename, Context.MODE_PRIVATE);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(arrayList);
oos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
The problem is that I whenever I run my program again, the "arrayList" is empty. So I guess I am opening the file in wrong input mode.
My aim is to first get the array from the file, then modify it within the app, and then write the modified array back to the file.
Can someone please help me with my problem?
Thanks!
Can you post your pice of your source code? I think the way which you used to parse file content get issue.
Read here:
Android ObjectInputStream docs
I read that the method readObject() read the next object...i this that you must iterate with something like this:
MediaLibrary obj = null;
while ((obj = (MediaLibrary)objIn.readObject()) != null) {
libraryFromDisk.add(obj);
}