Loop the deserialization is performed only once - java

I want to load a loop objects to the list, but I have a problem, because the loop is performed only once and the next loop crashes IOException line 'movie = (Movie) ois.readObject () ;'.
#SuppressWarnings("unchecked")
static <T> void loadDatabase(List<T> tab, int index) {
if(index == 1) {
try {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("movies.ser"));
try {
while(true) {
Movie movie = new Movie();
movie = (Movie) ois.readObject();
tab.add((T) movie);
}
} catch(EOFException ignored) {
ois.close();
}
} catch (FileNotFoundException e) {
System.out.println("Can not find the file. Please try again later...");
} catch (IOException e) {
System.out.println("Unable to save file. Please try again later...");
} catch (ClassNotFoundException e) {
System.out.println("The error of the projection class Movie");
}
} else if(index == 2) {
try {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("series.ser"));
while(ois.available() != 0) {
Series series = new Series();
series = (Series) ois.readObject();
tab.add((T) series);
}
ois.close();
} catch (FileNotFoundException e) {
System.out.println("Can not find the file. Please try again later...");
} catch (IOException e) {
System.out.println("Unable to save file. Please try again later...");
} catch (ClassNotFoundException e) {
System.out.println("The error of the projection class Series");
}
}
}

Lets dissect your (sorry, but horrible, horrible) code a bit:
#SuppressWarnings("unchecked")
static <T> void loadDatabase(List<T> tab, int index) {
if(index == 1) {
Dont do that. The whole point of index seems to be to distinguish what this method should do. Hint: create two methods instead; and avoid that parameter, and the if!
One method you would call loadMovieFromDataBase(); the other loadSeriesFromDataBase().
try {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("movies.ser"));
try {
while(true) {
Do you really want to loop forever?! That is what while(true) will.
Well, not forever, but until some exception will be thrown. So, even when your loop body would be doing the right thing (which it isnt!) ... that code must lead into some error condition.
Movie movie = new Movie();
movie = (Movie) ois.readObject();
That is like absolute nonsense. There is no point in calling new on a Movie object to have then read by an ObjectInputStream.
Movie movie = (Movie) ois.readObject();
is how you deserialize an object from an ObjectInputStream.
tab.add((T) movie);
}
} catch(EOFException ignored) {
ois.close();
Hint: you are a beginner. You have no idea what your code is doing; but you feel confident enough to ignore exceptions; not even trace them?!
And the following catches are not much better:
} catch (FileNotFoundException e) {
System.out.println("Can not find the file. Please try again later...");
} catch (IOException e) {
System.out.println("Unable to save file. Please try again later...");
You try to read a file. Hint: be careful when doing copy&paste of ERROR messages. This one doesn't make any sense here. Beyond that: don't replace the exception with some self-defined message. At least print the exception message, too. Because: your own code is all lying.
} catch (ClassNotFoundException e) {
System.out.println("The error of the projection class Movie");
}
No, the above error would mean that you tried to deserialize a class which does not exist in the context of the JVM that this code is running it.
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("series.ser"));
while(ois.available() != 0) {
Series series = new Series();
series = (Series) ois.readObject();
Same story as above. And hint: don't query the stream if more input is there. Just serialize one list of Series objects; than you just de-serialize one object later on.
The reason why I spent my time here: it seems that you are blindly putting together code without the slightest idea what that code is doing. That is, well a bad idea.
You better step back and read & run good tutorials on serialization. And only when you are able to run and understand that part, you try to come up with your own code.

Actually it is bad idea. best is deserialization once, clone and add to list how many time u wants.

Related

Why does my program stop running and does not return error?

I put the declaration in the while loop, and the program would not running and also does not return any error. I suspect the while loop become an infinite loop.
try
{
while (true)
{
inputStream = new ObjectInputStream (new FileInputStream (fileName));
Ship copyObject = (Ship) inputStream.readObject();
String nameCompany = copyObject.getCompanyName();
if (compName.equalsIgnoreCase(nameCompany)){
listShipName += (copyObject.getShipName() + ", ");
numberOfShip ++;
}
}
}
catch (EOFException e)
{
}
catch (Exception e)
{
e.printStackTrace();
}
But if I put the declaration of input stream out of the while loop, the program runs successfully. Can someone explain why this happens?
try
{
inputStream = new ObjectInputStream (new FileInputStream (fileName));
}
catch (Exception e)
{
e.printStackTrace();
}
try
{
while (true)
{
Ship copyObject = (Ship) inputStream.readObject();
String nameCompany = copyObject.getCompanyName();
if (compName.equalsIgnoreCase(nameCompany)){
listShipName += (copyObject.getShipName() + ", ");
numberOfShip ++;
}
}
}
catch (EOFException e)
{
}
catch (Exception e)
{
e.printStackTrace();
}
You're reopening your file on every iteration through the loop, which means you are only ever reading the first object from the file. But you're reading the same object over and over again.
As well as opening your file only once, you really should try to detect the end of file without throwing an exception. As a matter of style, exceptions should be thrown when things go wrong, not as a matter of course.
Now I realize that in each iteration, I reopen the input stream, so the loop would not reach to the end of the file, and it becomes infinite.

write to file from stack

folks. I'm trying to write to a file from a stack. The stack was created by reading from another file. I'm using the stack so that I can reverse the file I read in. The file names to read and write to are from the command line.
This is how I have my stack implemented:
while(read.hasNext()) {
stack.push(read.next());}
The code for my other file that the stack is supposed to write to:
FileWriter w = null;
try {
w = new FileWriter(new File(args[1]));
} catch (IOException e) {
e.printStackTrace();
}
if (!stack.isEmpty()) { //this was a while statement
try {
w.write(stack.pop());
} catch (IOException e) {
e.printStackTrace();
}
} else {
System.out.println("Didn't make it.");
}
The problem that I'm having is when I run my program, the file I want to write to is created, but nothing gets written to the file. I originally thought that my stack didn't have anything in it (that's why I changed my while statement to an if; it's temporary). The "Didn't make it." didn't print so I now know it's not that. What am I doing wrong here? Any help is appreciated.
After w.write(stack.pop()); call the fush() method:
w.write(stack.pop());
w.flush();
and you can return the while statement. At the end call w.close();
the method stack.pop returns an Object if you do not specify at the time of declaration like this
Stack<String> stack = new Stack<String>();
and after writing you should use w.flush() and also you should use the w.close.
you should nest the while statement itself into the try block
for instance
try {
while(!stack.isEmpty()) {
w.write(stack.pop()); // assuming you have declared it as Stack<E>
}
w.flush();
w.close();
} catch(IOException e) {
e.printStackTrace();
}
EDIT:
after you are done with FileWriter when you close it, that has to nested inside a try catch block to catch any IOException if thrown. if you use the w.write() method inside the try catch block that is within the while loop then after the while loop iteration is over you have to build another try catch to place w.close()

Trying to output a string variable to a .txt file within an IF statement. - Java

I'm pretty new to java and i still have alot to learn. I'm trying to output the data within a variable to a text file, and I'm not sure why this will not work. Could anyone help me out?
if ("Y".equals(output_to_file)) {
System.out.print("You selected Yes");
PrintStream out = null;
try {
out = new PrintStream(new FileOutputStream("filename.txt"));
out.print(first_input);
}
finally {
if (out != null) out.close();
}
}
else System.out.print("You selected No");
"(new FileOutputStream("filename.txt"))" is underlined red, and it says: Unhandled exception: java.io.FileNotFoundException
Thanks for your help!
Anytime you're doing file operations, there is the possiblity that a FileNotFoundException will be thrown. Therefore, Java wants you to tell it what to do in the event that one is thrown. Thus, you need to add a catch clause for the possible FileNotFoundException. You already have a try block, so you simply need to add a catch clause before your finally clause:
try {
out = new PrintStream(new FileOutputStream("filename.txt"));
out.print(first_input);
}
catch(FileNotFoundException e) {
//do something in the event that a FNFE is thrown
}
finally {
if (out != null) out.close();
}
}

Strange input error, I have used this code before

After a very bad attempt at doing my homework, I decided it would be faster to abandon everything and start from scratch. Well not everything ... I copied this part since it worked perfectly so I saw no need to modify it. While maybe not perfect, it worked.
However now, when I compile just to test it out, I get an unexpected error:
Input error: java.io.EOFException.
Notice that "Input error" is from my catch(IOException ioe).
The file (fileName) is completely empty. Nothing in it. What could cause this. Is there a way to tell the ObjectInputStream to do nothing if the file is empty ?
Also I tested this out with an empty file on my other "iteration", didn't have this problem. I even named my file the same.
public Repository (String fileName) throws FileNotFoundException,
IOException,
SecurityException,
ClassNotFoundException {
this.fileName = fileName;
this.clients = new ArrayList<Client> ();
FileInputStream fileIn = null;
ObjectInputStream in = null;
try {
fileIn = new FileInputStream(this.fileName);
in = new ObjectInputStream(fileIn);
this.clients = (ArrayList<Client>) in.readObject();
} catch (FileNotFoundException fnfe) {
System.out.println("File not found, error: " + fnfe);
} catch (IOException ioe) {
System.out.println("Input error: " + ioe);
} catch (ClassNotFoundException cnfe) {
System.out.println("Class not found, error: " + cnfe);
} catch (SecurityException se) {
System.out.println(
"You do not have permission to access this file, error: "
+ se);
} finally {
if (fileIn != null)
fileIn.close();
if (in != null)
in.close();
}
Surely before
in = new ObjectInputStream(fileIn);
this.clients = (ArrayList<Client>) in.readObject();
you want to check the file size via File.length().
I assume if it's empty then you'd want to return an empty array list. You can't do that via deserialising an empty file. After all, even an empty array list has a non-zero size (and would need to identify itself as an array list via serialised attributes)
The file (fileName) is completely empty. Nothing in it.
That's exactly the problem. You cannot read an object (or an array) from an empty file. It will not find any data and throw an End-of-file-Exception (EOFException).
Even an empty array - when serialized to a file - will produce some data because the object stream will write the type (ArrayList) and the size of the array (0) to the file. When you try to read it, it will expect to find this data.

How do I update a File created by openFileOutput

I'm currently building an application where the user will generate data over time and, should he/she has an internet connection, transmit it to the web. However, if he doesn't have web access, I need to store this data in the phone until the user recovers his access, when I'll need to recover this data to be transmitted. However, I'm facing lots of troubles to do this, as per below.
Note: before anything, I'm using a local java-created file because I know no other way to save/restore this data on the device. If you happen to know any other way to store/access this data from within the device please feel free to comment here.
Just for reference,
phantoms is an ArrayList containing objects with the data I need to
store,
Arquivador is the class that I'm using to make my data persistent and to recover it,
Funcionario is the class with the data generated by the program (just a few strings and numbers)
I am able to write a file to the file system through the code below, on my Activity:
try {
arq = new Arquivador();
arq.addFirstObjectInFile(
openFileOutput("dados.jlog", MODE_WORLD_WRITEABLE),
phantoms.get(0));
phantoms.remove(phantoms.get(0));
for (Funcionario func : phantoms) {
arq.addObjectInFile(openFileOutput("dados.jlog", MODE_APPEND),
func);
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
}
Here is the code inside Arquivador that adds the data to a file:
public void addObjectInFile(FileOutputStream arquivo,
Object objetoAAdicionar) {
try {
ObjectOutputStream aoos = new ObjectOutputStream(arquivo);
aoos.writeObject(objetoAAdicionar);
aoos.close();
} catch (IOException ioe) {
Log.d(TAG_NAME, "Erro no Appendable OOS.");
}
}
public void addFirstObjectInFile(FileOutputStream arquivo,
Object objetoAAdicionar) {
try {
AppendableObjectOutputStream aoos = new AppendableObjectOutputStream(
arquivo);
aoos.writeObject(objetoAAdicionar);
aoos.close();
} catch (IOException ioe) {
Log.d(TAG_NAME, "Erro no Appendable OOS.");
}
}
You will notice that I'm adding data to persistence in 2 steps, the first Object and the rest of them. This was an idea I saw on this post, here in StackOverflow, to allow appending data to a Java generated file. I have no problem with this code, it works perfectly.
Later on, back on my Activity, the internet connection is detected and I try to recover the file saved on the disk:
phantoms = new ArrayList<Funcionario>();
Object obj = arq.readObjectFromFile(openFileInput("dados.jlog"));
Funcionario func = null;
if (obj instanceof Funcionario) {
func = (Funcionario) obj;
}
while (func != null) {
phantoms.add(func);
arq.removeObjectFromFile(openFileInput("dados.jlog"), func,
getApplicationContext());
func = (Funcionario) arq
.readObjectFromFile(openFileInput("dados.jlog"));
}
The original idea was to read 1 object at a time, then attempt to transmit it and, if successful, erase the object from the file (so it didn't get retransmitted). However, I was having too many error messages with this. Instead, I decided to load all the objects at once, one by one, to see where my problem was more clearly.
Back to the Arquivador class:
public Object readObjectFromFile(FileInputStream arquivo) {
Object retorno = null;
if (arquivo.equals(null)) {
Log.e(TAG_NAME, "FIS is null!");
}
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(arquivo);
retorno = ois.readObject();
} catch (IOException ioex) {
} catch (ClassNotFoundException e) {
} finally {
try {
if (ois != null) ois.close();
} catch (IOException e) {
}
}
return retorno;
}
public void removeObjectFromFile(FileInputStream arqPrincipal,
Object objetoARemover, Context contexto) {
try {
// Construct the new file that will later be renamed to the original
// filename.
ObjectOutputStream oos = new ObjectOutputStream(
contexto.openFileOutput("dados.jlog.temp",
contexto.MODE_APPEND));
ObjectInputStream ois = new ObjectInputStream(arqPrincipal);
Object obj = null;
// Read from the original file and write to the new
// unless content matches data to be removed.
try {
while ((obj = ois.readObject()) != null) {
if (!(objetoARemover.equals(obj))) {
oos.writeObject(obj);
oos.flush();
}
}
} catch (EOFException eof) {
} finally {
oos.close();
ois.close();
// Delete the original file
File aDeletar = contexto.getFileStreamPath("dados.jlog");
File aRenomear = contexto.getFileStreamPath("dados.jlog.tmp");
if (!aDeletar.delete()) {
return;
} else {
// Rename the new file to the filename the original file
// had.
if (!aRenomear.renameTo(aDeletar)) Log.d(TAG_NAME,
"Error renaming file");
else Log.d(TAG_NAME, "Renaming successful");
}
}
} catch (FileNotFoundException ex) {
ex.printStackTrace();
Log.d(TAG_NAME, "Arquivo não encontrado");
} catch (IOException ex) {
ex.printStackTrace();
Log.d(TAG_NAME, "Erro de entrada/saída");
} catch (ClassNotFoundException e) {
Log.d(TAG_NAME, "Classe Não Encontrada.");
}
}
The method readObjectFromFile() seems to work just fine. I can even convert the read Object to Funcionario class and read its data.
My problems appear when I use removeObjectFromFile(). The idea is to create a temporary file to store objects from "dados.jlog" file other than the one that has been already loaded in the main program, then once this temp file is created the file "dados.jlog" should be deleted and the temporary file should be renamed to replace it.
The first thing I found out to be strange here is that the ois.readobject() keeps throwing an EOFException. While this makes sense, the tutorial I read on the internet doesn't mention this error. In fact, their code indicates that when the readObject() method reaches the EOF, it would return a reference to null, but instead this class throws this EOFException. I handled this exception in the code - though I'm not sure if this would be the right way to do it.
Another thing I find strange is the fact that this code fails to recognize the object that it should NOT copy. When I compare the object read from the file to the one received as argument, no matter what I try ( == , equals(), etc) they seem different objects to the compiler. Funcionario class is serializable has a serialversionUID, so the object read from the file should be identical to the one I stored. Worse than this, these 2 Objects being compared are read from the same file. They should be identical, right?
After creating the temporary file, I try to delete the original file and rename the temporary file. Though this seems to be working, once the removeObjectFromFile() ends the first time, the program is unable to read the data from the file "dados.jlog" again. I can't read the remaining data from the file and the program enters on an endless loop - since the 1st object is never removed from the list in the file.
Please enlighten me with this matter.
Personally I'd use an SQLLite database. Store each object in a row in the database. Once you've successfully transmitted you can remove the row from the database.
You can even reuse most of your code that you've already done. The easiest way to get there from where you are is to use a separate file for each object and store only the filename of the object in the database. You can then iterate over the rows in the database. Each time you transmit an object to your server simply delete that row from the database (and remove the file from the filesystem!). No rows in the database means no objects remain to be transmitted.

Categories