How to check if a file already contains an object? - java

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.

Related

Can't create file in directory - Java

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");
}
}

local class incompatible error

The following code gives me the error InvalidClassException My User class implements Serializable so I'm lost. I'm trying to store list filled with User objects and then be able to read it back.
List<User> userList = new ArrayList<User>();//list used
try {
ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream(fileName, true));
os.writeObject(userList);
os.close();
} catch (IOException e1) {
e1.printStackTrace();
}
// input
try {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(fileName));
userList = (List<User>) ois.readObject();
ois.close();
} catch (FileNotFoundException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
} catch (ClassNotFoundException e1) {
e1.printStackTrace();
}
If you are trying to store and later retrieve a single object (a List<> in your example) in a file, you do not want to append to the file each time you write to it. Rather, you want to overwrite the file each time, with the new object.
// Write
List<User> userList = new ArrayList<User>();
try (FileOutputStream fos = new FileOutputStream(fileName);
ObjectOutputStream oos = new ObjectOutputStream(fos)) {
oos.writeObject(userList);
} catch (IOException e1) {
e1.printStackTrace();
}
// read
try (FileInputStream fis = new FileInputStream(fileName);
ObjectInputStream ois = new ObjectInputStream(fis)) {
userList = (List<User>) ois.readObject();
} catch (FileNotFoundException | IOException | ClassNotFoundException e1) {
e1.printStackTrace();
}
Notice new FileOutputStream(fileName) does not have the true argument. Using the true argument indicates you want to open the file for "append". Using false, or leaving the append argument off entirely, will open the file for "overwrite".
Notes:
I've also used the try-with-resources statement my example. This eliminates the need for explicitly closing the streams; the streams are automatically closed for you at the end of the try { } block.
I've also used the multi-catch clause, because you are not handling the 3 exceptions any differently, so it is a bit cleaner.

How to append an object to an existing file (generics)?

I'm having problems with appending a generic object within an existing file. This method is supposed to append the object to the existing file if the parameters are "true" and overwrites the entire file if "false". The "false" statement works perfectly fine, it overwrites the entire file but I can't seem to get the append one to work. It seems to do nothing at first glance but when I placed a simple System.out.println("test"); in the while (true) loop, it runs forever. How can I fix this?
public <T> void writeOneObject(T type, boolean append) throws NotSerializableException{
if (append == true){
//TODO
if (file.exists ()){
ObjectOutputStream ois = null;
try{
ois = new ObjectOutputStream (new FileOutputStream (file, true));
while (true){
ois.writeObject(type);
}
}catch (StreamCorruptedException e){
}catch (EOFException e){
}catch (Exception e){
e.printStackTrace ();
}finally{
try{
if (ois != null) ois.close();
}catch (StreamCorruptedException e){
}catch (IOException e){
e.printStackTrace ();
}
}
}
}
else { //overwrites the entire file
try {
FileOutputStream fos = new FileOutputStream(file);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(type);
oos.flush();
oos.close();
} catch (FileNotFoundException ex) {
ex.printStackTrace();
} catch (StreamCorruptedException e) {
System.out.println("error");
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
I also have this inside the class:
class NoHeaderObjectOutputStream extends ObjectOutputStream {
public NoHeaderObjectOutputStream(OutputStream os) throws IOException {
super(os);
}
protected void writeStreamHeader() {}
}

Strange issue when creating a new file

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.

Reading from internal storage (deserialization)

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);
}

Categories