I am trying to do some kind of serialization where I can directly read and write objects from file.
To start of I just tried to write a character to file and tried to read it. This keeps giving me EOF exception always.
I am trying it on a Android device. Here is my code:
public class TestAppActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
try {
WriteToFile();
Load();
} catch (Exception e) {
e.printStackTrace();
}
}
public void Load () throws IOException
{
InputStream fis;
ObjectInputStream in = null;
try {
fis = new FileInputStream(Environment.getExternalStorageDirectory() + "\\test2.ser");
in = new ObjectInputStream(fis);
char temp = in.readChar();
} catch (IOException e) {
e.printStackTrace();
} finally {
in.close();
}
}
public static void WriteToFile() throws Exception {
try {
OutputStream file = new FileOutputStream(Environment.getExternalStorageDirectory() + "\\test2.ser");
ObjectOutput output = new ObjectOutputStream(file);
try {
output.writeChar('c');
} finally {
output.close();
}
} catch (IOException ex) {
throw ex;
}catch (Exception ex) {
throw ex;
}
}
}
In this case, EOFException means there is no more data to be read, which (again in this case) can only mean that the file is empty.
Why are you using ObjectInput/OutputStreams but only writing chars? You'd be better off with DataInput/OutputStreams for that usage.
Also there is no point in catching exceptions only to rethrow them.
Also there is no point in reading a char from a file unless you are going to put it somewhere other than in a local variable that isn't even returned by the method.
I have imported this code in my sample project with following change.
i replaced "\\test2.ser"with "/test2.ser" and it worked. please try this.
Related
I'm a Pythonista moving into Java/Scala, and I am wondering how to handle the case where you want an exception to be thrown if it occurs. Take the following toy example:
public class PersonSaver {
private final File file;
public PersonSaver(File file) {
this.file = file;
}
public void save(List<Person> people) {
try (ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream(file))) {
output.writeObject(people);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
In Python I would want this to throw an error if the file isn't found, and let the calling code handle the exception. Is it convention just to re-throw the same exception?
You can make your method throw those exceptions :
public class PersonSaver {
private final File file;
public PersonSaver(File file) {
this.file = file;
}
public void save(List<Person> people) throws FileNotFoundException {
try (ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream(file))) {
output.writeObject(people);
} catch (IOException e) {
//handle the exception you want to handle
e.printStackTrace();
}
}
}
Just make sure you declare your method with the throws statement, or your compiler might not like it ;)
You can also go this way (let's call this a semi-exception-handling) :
public class PersonSaver {
private final File file;
public PersonSaver(File file) {
this.file = file;
}
public void save(List<Person> people) throws FileNotFoundException, IOException {
try (ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream(file))) {
output.writeObject(people);
} catch (IOException e) {
/*Some code to clear some data or to handle the
exception but still throw an exception higher*/
throw e;
}
}
}
You can just do the following...
public class PersonSaver {
private final File file;
public PersonSaver(File file) {
this.file = file;
}
public void save(List<Person> people) throws FileNotFoundException {
try (ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream(file))) {
output.writeObject(people);
} catch (IOException e) {
e.printStackTrace();
}
}
}
In any part of your code you can throw a throwable object, such as an Exception.
You should also state it in the method signature, letting the JVM know you'll handle that Exception in a caller's block.
Example:
public void save(List<Person> people) throws FileNotFoundException{
try (ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream(file))) {
output.writeObject(people);
} catch (IOException e) {
e.printStackTrace();
}
}
You need to consider if the calling code actually knows what to do with the specific exception. You have defined an API about saving a collection of Person. The calling code knows only about a Person and has no idea ideally where the save is done.
If you throw a lower level exception about the file not found you are leaking the abstraction and you won't be able to change the implementation easily if the calling code is starting to be aware of where things are saved.
The proper approach would be to throw an "business" exception like PersonNotPersisted or PersonNotSaved since this is something the calling code would understand and avoid the low level IO exceptions to the higher layer
If you declare a method to throws an checkedexception you dont need to catch it or any of it subtypes:
public void save(List<Person> people) throws IOExcetion {
try (ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream(file))) {
output.writeObject(people);
}
}
If you want to handle the exception before you can also do like:
public void save(List<Person> people) throws IOException {
try (ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream(file))) {
output.writeObject(people);
} catch (IOException e) {
e.printStackTrace();
throw e;
}
}
The keyword 'throw' fires the exception to the caller.
I'm trying to read ObjectOutputStream from a file and convert it to an arraylist.
This whole thing is happening inside a method which should read the file and return the array list:
public static List<Building> readFromDatabase(){
String fileName="database.txt";
FileInputStream fileIStream=null;
ObjectInputStream in=null;
List<Building> buildingsArr=null;
try
{
fileIStream = new FileInputStream(fileName);
in = new ObjectInputStream(fileIStream);
buildingsArr=(ArrayList<Building>)in.readObject();
}
catch(IOException e)
{
e.printStackTrace();
}
catch(ClassNotFoundException e)
{
Console.printPrompt("ArrayList<Building> class not found.");
e.printStackTrace();
}
finally{
Console.printPrompt("Closing file...");
close(in);
close(fileIStream);
return buildingsArr;
}
}
Java tells me that this is dangerous.
What are the alternatives?
I can't put the return in the "try" block because it won't do it / it won't close files in the "finally" block.
I need to both make sure files will be closed, and return the array list I created as well.
Any ideas?
I can't put the return in the "try" block because it won't do it / it
won't close files in the "finally" block.
Wrong, finally block would still execute if you put return in try block. Thus you can return in your try block.
try
{
//your code
return buildingsArr;
}
catch(IOException e)
{
e.printStackTrace();
}
catch(ClassNotFoundException e)
{
Console.printPrompt("ArrayList<Building> class not found.");
e.printStackTrace();
}
finally{
Console.printPrompt("Closing file...");
close(in);
close(fileIStream);
}
I would suggest starting to use Java 7, and the try with resources clause. http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
Ex:
static String readFirstLineFromFile(String path) throws IOException {
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
return br.readLine();
}
}
You must either throw an Exception or return a value:
All you need to prove this is comment out the return "File Not Found" after the finally block and see that it won't compile.
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
public class ReturnFinallyExample
{
public static void main(final String[] args)
{
returnFinally();
}
private static String returnFinally()
{
try
{
final File f = new File("that_does_not_exist!");
final FileInputStream fis = new FileInputStream(f);
return "File Found!";
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
finally
{
System.out.println("finally!");
}
return "File Not Found!";
}
}
You must have the return after the finally or you have to either:
declare the method to throws FileNotFoundExceptoin and re-throw the FileNotException out.
or
wrap the FileNotFoundException with throw new RuntimeException(e)
I am wondering why I get this warning with the new eclipse Juno despite I think I correctly closed everything. Could you please tell me why I get this warning in the following piece of code?
public static boolean copyFile(String fileSource, String fileDestination)
{
try
{
// Create channel on the source (the line below generates a warning unassigned closeable value)
FileChannel srcChannel = new FileInputStream(fileSource).getChannel();
// Create channel on the destination (the line below generates a warning unassigned closeable value)
FileChannel dstChannel = new FileOutputStream(fileDestination).getChannel();
// Copy file contents from source to destination
dstChannel.transferFrom(srcChannel, 0, srcChannel.size());
// Close the channels
srcChannel.close();
dstChannel.close();
return true;
}
catch (IOException e)
{
return false;
}
}
IF you're running on Java 7, you can use the new try-with-resources blocks like so, and your streams will be automatically closed:
public static boolean copyFile(String fileSource, String fileDestination)
{
try(
FileInputStream srcStream = new FileInputStream(fileSource);
FileOutputStream dstStream = new FileOutputStream(fileDestination) )
{
dstStream.getChannel().transferFrom(srcStream.getChannel(), 0, srcStream.getChannel().size());
return true;
}
catch (IOException e)
{
return false;
}
}
You won't need to explicitly close the underlying channels. However if you're not using Java 7, you should write the code in a cumbersome old way, with finally blocks:
public static boolean copyFile(String fileSource, String fileDestination)
{
FileInputStream srcStream=null;
FileOutputStream dstStream=null;
try {
srcStream = new FileInputStream(fileSource);
dstStream = new FileOutputStream(fileDestination)
dstStream.getChannel().transferFrom(srcStream.getChannel(), 0, srcStream.getChannel().size());
return true;
}
catch (IOException e)
{
return false;
} finally {
try { srcStream.close(); } catch (Exception e) {}
try { dstStream.close(); } catch (Exception e) {}
}
}
See how much better the Java 7 version is :)
You should always close in finally because if an exception rise, you won't close the resources.
FileChannel srcChannel = null
try {
srcChannel = xxx;
} finally {
if (srcChannel != null) {
srcChannel.close();
}
}
Note: even if you put a return in the catch block, the finally block will be done.
eclipse is warning you about the FileInputStream and FileOutputStream that you can no longer reference.
I have the following Java Class that does one thing, fires out values from config.properties.
When it comes time to close the fileInputStream, I think I read on Wikipedia that it is good to have it in a finally block. Because it honestly works just fine in try/catch block.
Can you show me correction to get fileInputStream.close() in a finally section?
ConfigProperties.java
package base;
import java.io.FileInputStream;
import java.util.Properties;
public class ConfigProperties {
public FileInputStream fileInputStream;
public String property;
public String getConfigProperties(String strProperty) {
Properties configProperties = new Properties();
try {
fileInputStream = new FileInputStream("resources/config.properties");
configProperties.load(fileInputStream);
property = configProperties.getProperty(strProperty);
System.out.println("getConfigProperties(" + strProperty + ")");
// use a finally block to close your Stream.
// If an exception occurs, do you want the application to shut down?
} catch (Exception ex) {
// TODO
System.out.println("Exception: " + ex);
}
finally {
fileInputStream.close();
}
return property;
}
}
Is the solution only to do as Eclipse suggests and do this in the finally block?
finally {
try {
fileInputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Yes, that is the common pre-Java 7 solution. However, with the introduction of Java 7, there are now try-with-resource statements which will automatically close any declared resources when the try block exits:
try (FileInputStream fileIn = ...) {
// do something
} // fileIn is closed
catch (IOException e) {
//handle exception
}
The standard approach is:
FileInputStream fileInputStream = null;
try {
fileInputStream = new FileInputStream(...);
// do something with the inputstream
} catch (IOException e) {
// handle an exception
} finally { // finally blocks are guaranteed to be executed
// close() can throw an IOException too, so we got to wrap that too
try {
if (fileInputStream != null) {
fileInputStream.close();
}
} catch (IOException e) {
// handle an exception, or often we just ignore it
}
}
Because FileInputStream.close() throws an IOException, and the finally{} block doesn't catch exceptions. So you need to either catch it or declare it in order to compile. Eclipse's suggestion is fine; catch the IOException inside the finally{} block.
It's a good habit to close streams because what it does in background it's called buffering, meaning that it does not free the internal buffer and does not free the file descriptor.
I am using a buffered writer and my code, closes the writer in the finally block. My code is like this.
...........
BufferedWriter theBufferedWriter = null;
try{
theBufferedWriter =.....
....
......
.....
} catch (IOException anException) {
....
} finally {
try {
theBufferedWriter.close();
} catch (IOException anException) {
anException.printStackTrace();
}
}
I have to use the try catch inside the clean up code in finally as theBufferedWriter might also throw an IOException. I do not want to throw this exception to the calling methos. Is it a good practice to use a try catch in finally? If not what is the alternative? Please suggest.
Regards,
Hiral
A somewhat nicer way to do this is to use IOUtils.closeQuiety from Apache commons-io. It keeps your code tidy and eliminates some of the boilerplate that's inherent in Java.
You code then becomes:
BufferedWriter theBufferedWriter = null;
try{
theBufferedWriter = ...
...
} catch (IOException anException) {
...
} finally {
IOUtils.closeQuietly(theBufferedWriter);
}
Much nicer and more expressive.
In pre Java 7, I'd say what you have written is the best solution.
In Java 7 and onwards you have Automatic Resource Management intended to simplify these things. With this feature, you can do
BufferedWriter theBufferedWriter = null;
try (BufferedWriter theBufferedWriter = ...) {
....
......
.....
} catch (IOException anException) {
....
}
Or you can use Lombok and the #Cleanup annotation and you shall never write a try catch inside finally again.
This is how you would normally write it (Note the throws IOException):
//Vanilly Java
import java.io.*;
public class CleanupExample {
public static void main(String[] args) throws IOException {
InputStream in = new FileInputStream(args[0]);
try {
OutputStream out = new FileOutputStream(args[1]);
try {
byte[] b = new byte[10000];
while (true) {
int r = in.read(b);
if (r == -1) break;
out.write(b, 0, r);
}
} finally {
out.close();
}
} finally {
in.close();
}
}
}
Now with Lombok you just write #Cleanup on the streams
import lombok.Cleanup;
import java.io.*;
public class CleanupExample {
public static void main(String[] args) throws IOException {
#Cleanup InputStream in = new FileInputStream(args[0]);
#Cleanup OutputStream out = new FileOutputStream(args[1]);
byte[] b = new byte[10000];
while (true) {
int r = in.read(b);
if (r == -1) break;
out.write(b, 0, r);
}
}
}
This is what we will have to live with until Java 7 and ARM Blocks.
It's OK but you should test if theBufferedWriter is not null before closing it.
You could also do:
BufferedWriter theBufferedWriter;
try {
theBufferedWriter = new ...
try {
...
} finally {
try {
theBufferedWriter.close();
} catch (IOException closeException) {
closeException.printStackTrace();
}
}
} catch (IOException anException) {
...
}
or:
BufferedWriter theBufferedWriter;
try {
theBufferedWriter = new ...
} catch (IOException createException) {
// do something with createException
return; // assuming we are in a method returning void
}
try {
...
} catch (IOException anException) {
...
// assuming we don't return here
}
try {
theBufferedWriter.close();
} catch (IOException closeException) {
closeException.printStackTrace();
}
but mostly I do such operations (e.g. writing a file) in a dedicated method and prefer to throw the/an Exception so the caller can handle it (e.g. asking for another file, stopping the application, ...):
void someMethod(...) throws IOException {
BufferedWriter theBufferedWriter = new ...
try {
...
} catch (IOExcepption anException) {
try {
theBufferedWriter.close();
} catch (IOException closeException) {
closeException.printStackTrace();
// closeException is not thrown, anException represents the main/first problem
}
throw anException;
}
theBufferedWriter.close(); // throws the Exception, if any
}
Please note: English is not my first nor my second language, any help would be appreciated
It's ok to put a try-catch in a finally. It is the tool that does what you want to do. However, I feel the thrown IOException on close is uncommon enough that I would allow it to suppress any exception in the body like so.
try {
BufferedWriter writer = .....
try {
.....
} finally {
writer.close();
}
} catch (IOException e) {
....
}