Stream Object Initialization - java

Now I am getting compile time error at line 30 and 38 that 'fin' might not have been initialized. but its perfectly to write it this way
import java.io.*;
class CopyFile {
public static void main(String args[]) throws IOException {
int i;
FileInputStream fin;//can't it be done like this?
FileOutputStream fout= new FileOutputStream(args[1]);
try{
//open input file
try{
fin = new FileInputStream(args[0]);
}
catch(FileNotFoundException e){
System.out.println("Input file Not Found");
return;
}
//open output file
try{
fout = new FileOutputStream(args[1]);
}
catch(FileNotFoundException e){
System.out.println("Error Opening File");
}
}
catch(ArrayIndexOutOfBoundsException e){
System.out.println("usage: Copyfile From to");
}
try{
do{
i = fin.read();
if(i!= -1)
fout.write(i);
}while(i != -1);
}
catch(IOException e){
System.out.println("file error");
}
fin.close();
fout.close();
}
}
I have seen it many time initialized like this. I think its due to the try blocks.
it might miss the initialization due to being in the try block and hence the error?

The problem is that you're not initializing the FileInputStream fin at all. Your code will look like this to the compiler:
FileInputStream fin;
try {
fin = ...
//more code goes here...
} catch (...) {
//exception handling...
} finally {
fin.close(); //fin is not even null for the compiler
}
In order to make the code work, initialize it at least with a null value and check if fin != null before using the close method.
FileInputStream fin = null;
try {
fin = ...
//more code goes here...
} catch (...) {
//exception handling...
} finally {
if (fin != null) {
fin.close(); //fin is not null, at least the JVM could close it
}
}
More info:
Java: Declaring Variables
Uninitialized variables and members in Java

FileInputStream fin=null;
Assign it null or FileInputStream object.
Local variable need to be assigned to some value before being used.

Though in the first try block, you are initializing fin as fin = new FileInputStream(args[0]);, your nested statements confuse the compiler. Just update your declaration as below:
FileInputStream fin = null;

Dont use try catch for an if and vice versa.
Try/catch is for when things go wrong behind your control and that is no part of normal program flow for example writing to a hard disk that is full....
Use if for normal error checking
In your example check your args array with an if block and then initialize your fin.

Related

If a runtime exception was thrown after a resource was open - the program close the resource?

I wrote a simple java function that reads a file of Floating-point values and in the case file is not found or
the values that are being read are not floating-point the program throws exceptions.
My question is on the case that the program opened the file but the format of values was not floating-point - can the program close the resources? or should I consider the runtime exception that may happen?
public static ArrayList<Double> readValues(String filename) throws
FileNotFoundException {
var file = new File(filename);
var fileScanner = new Scanner(file);
var doubleList = new ArrayList<Double>();
//In case the values are not of double type and the scanner
while(fileScanner.hasNext())
doubleList.add( Double.parseDouble( fileScanner.next() ) );
fileScanner.close();
return doubleList;
}
o.k I updated the code to use in 'finally' statement
public static ArrayList<Double> readValues(String filename) throws
FileNotFoundException {
var file = new File(filename);
var fileScanner = new Scanner(file);
var doubleList = new ArrayList<Double>();
//In case the values are not of double type and the scanner
try {
while(fileScanner.hasNext())
doubleList.add( Double.parseDouble( fileScanner.next() ) );
}finally {
fileScanner.close();
}
return doubleList;
}
If there are better ideas, I would like to know.
Thanks for the help
Java finally block is always executed whether exception is handled or not.
Please refer to this
A standard approch
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
}
}
From java7: The try-with-resources Statement
From the oracle docs Refer here
You can close resources by using try with resources
try(// open resources here){
// use resources
} catch (FileNotFoundException e) {
// exception handling
}
// resources are closed as soon as try-catch block is executed.

BufferedWriter causes break

I'm trying to make a save function for a program I'm working on, and for some reason whenever I run it, it only gets past the first line of the try{} statement.
My code is as appears below.
public void saveGame() {
System.out.println("saveGame");
try
{
System.out.println("try saveGame");
BufferedWriter b = new BufferedWriter(new FileWriter("chardata.txt"));
System.out.println("try saveGame2");
String sp = System.getProperty("line.separator");
System.out.println("try saveGame3");
b.write("Miscellaneous char data here");
b.close();
}
catch(IOException ex)
{
System.out.println("File Writing Error");
}
}
When I run the program, the only lines that get printed are "saveGame" and "try saveGame." There is no "File Writing Error" either, it simply doesn't do anything after the "try saveGame" line. I'm not sure if this is relevant, but I am doing this from a computer at a school, which may have restricted permissions. Any kind of explanation and/or help would be much appreciated.
I think a better way to write your file would be using FileOutputStream and OutputStreamWriter.
Additionaly, you should move your b.close to a finally statement because if an exception is thrown before that b.close was executed, it never will be executed.
public void saveGame() {
System.out.println("saveGame");
try
{
System.out.println("try saveGame");
String path = "./chardata.txt"; //your file path
File file = new File(path);
FileOutputStream fsal = new FileOutputStream(file);
OutputStreamWriter osw = new OutputStreamWriter(fsal);
Writer w = new BufferedWriter(osw);
System.out.println("try saveGame2");
String sp = System.getProperty("line.separator");
System.out.println("try saveGame3");
w.write("Miscellaneous char data here");
}
catch(IOException ex)
{
System.out.println("File Writing Error");
}
finally{
if(w!=null)
w.close();
}
}

Initializing In Try/Catch

I have run into quite a snag while writing my app. Here is my issue:
I am trying to initialize the file input stream like so:
FileInputStream fis
fis = openFileInput(selectedFile);
Then put this 1 line later:
byte[] input = new byte[fis.available()];
Problem is both bits of code need try/catch statements and the second block cannot recognize fis because it was initialized within a try/catch. Here is my code:
private void openFile(String selectedFile) {
String value = "";
FileInputStream fis;
try {
fis = openFileInput(selectedFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
byte[] input = new byte[fis.available()];
} catch (IOException e) {
e.printStackTrace();
}
What should I do? (Thanks in advance)
The best approach in this situation is not to catch IOException at all.
private void openFile(String selectedFile) throws IOException {
FileInputStream fis = openFileInput(selectedFile);
byte[] input = new byte[fis.available()];
It does not make sense to continue after you got FileNotFoundException
Set FileInputStream fis = null; when you first declare the variable.
You could also run your code like this because IOException will also catch the file not found exception.
String value = "";
FileInputStream fis;
try {
fis = openFileInput(selectedFile);
byte[] input = new byte[fis.available()];
} catch (IOException e) {
e.printStackTrace();
}
Set the FileInputStream to a temporary value. null would be the best option, as in:
FileInputStream fis = null;
The reason for this is because if your try statement throws an error, then the fis will never me initialized. Then you'll have problems. If you don't exit the thing entirely, you should also add the statement after the try/catch blocks that tests if the value is null, just so that the program does not throw a null pointer exception.
So maybe something like:
if(fis == null) {
return; // Which will just end the method.
}
Also might want to put the try/catches together (you should still declare the other stuff outside of the try, at least anything you plan on using directly later on in the code) but it just might be more efficient coding wise), as in:
FileInputStream fis = null;
byte[] input = null;
try {
fis = openFileInput(selectedFile);
input = new byte[fis.available()];
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

inside try block a FileIStream variable might not have been initialized error

I am trying to execute this code and I am also providing the valid argument but still I am getting error at line no. 34 and 35 that local variable fin and fout might not have been initialized. How to solve thisenter code here
package maxbj.myTest.p1;
import java.io.*;
public class CopyFile {
public static void main(String[] args)throws IOException {
int i;
FileInputStream fin;
FileOutputStream fout;
try{
//trying to open input file
try{
fin=new FileInputStream(args[0]);
}catch(FileNotFoundException e){
System.out.println("Input file not found");
return;
}
//trying to open output file
try{
fout=new FileOutputStream(args[1]);
return;
}catch(FileNotFoundException e){
System.out.println("Output file cannot be opened or created");
return;
}
}catch(ArrayIndexOutOfBoundsException e){
System.out.println("Array index out of bound exception");
}
//code to copy file
try{
do{
i=fin.read();
if(i!=-1) fout.write(i);
}while(i!=-1);
}catch(IOException e){
System.out.println("File Error");
}
fin.close();
fout.close();
}
}
PS- This code is from the book "JAVA COMPLETE REFRENCE"
The compiler is right (and the book is wrong, they should have tried compiling their code before publishing): there is a path through the code when fin remains uninitialized by the time the code reaches the fin.read() line.
Specifically, if ArrayIndexOutOfBoundsException gets thrown in the first outer try/catch block, the fin variable will not be assigned. Adding return to the outer catch block should fix this problem:
try {
...
} catch(ArrayIndexOutOfBoundsException e){
System.out.println("Array index out of bound exception");
return; // <<== Here
}
With the return statement in place, control will never reach the fin.read() unless fin has been initialized, fixing the compile-time error.
A simple way around this is to perform anything which requires fin and fout within the try block. This way you will never be trying to use the streams when they have failed on opening.
try
{
fout = new FileOutputStream(...);
fin = new FileInputStream(...);
// Code goes here
fout.close();
fin.close();
}
catch(FileNotFoundException e)
{
// Error code - e should contain the file name/path
}
Also, it is always good practice to initialise variables when you declare them:
FileOutputStream fout = null;
FileInputStream fin = null;
However, this way (just initialising to null) you programming logic will not cause compiler errors, but if not handled correctly you may get NullPointerExceptions if you try block throws.

IOException and NullPointerException from ObjectInputStream

I'm writing a small program for an assignment and part of it involves reading from a file using ObjectInputStream. I've run into a brick wall because I keep getting errors when trying to close the file in the finally block as well as a NullPointerException but I cannot understand why. Any help is much appreciated! I have checked already and the file path is correct, so it is able to find the file.
Example file:
hello || apples, acai berry, bananas || shopping || 0.0005 || yes
public Disease[] readInCancers() {
Disease[] cancerList = null;
try {
FileInputStream fis = new FileInputStream(myData);
BufferedInputStream bis = new BufferedInputStream(fis);
ois = new ObjectInputStream(bis);
while(true) {
Disease disease = null;
try {
disease = (Disease)ois.readObject();
} catch (EOFException eofx) {
break;
}
if (cancerList == null || cancerList.length == 0) {
cancerList = new Disease[1];
cancerList[0] = disease;
} else {
Disease[] newList = new Disease[cancerList.length + 1];
System.arraycopy(cancerList, 0, newList, 0, cancerList.length);
newList[cancerList.length] = disease;
cancerList = newList;
}
}
} catch (FileNotFoundException fnfx) {
JOptionPane.showMessageDialog(null, "File could not be found");
} catch (IOException iox) {
JOptionPane.showMessageDialog(null, "Problem with reading from file");
} catch (ClassNotFoundException cnfx) {
JOptionPane.showMessageDialog(null, "Class could not be found");
} catch (NullPointerException npx) {
System.out.println("blah");
} finally {
try {
ois.close();
} catch (IOException iox) {
JOptionPane.showMessageDialog(null, "Problem with closing file");
}
}
return cancerList;
}
When I run the program, it gives a NullPointerException at ois.close() as well as an IOException that produces the pop-up "Problem with reading from file".
I have also tried changing how the file itself is structured, replaced the || (delimiters) with a word or even blank space but nothing changes.
Your FileInputStream is throwing an exception (I'm guessing from incorrect file permissions, but you'll have to look into this further); this occurs before you initialize your ObjectInputStream, so ois is still null when you reach your finally block which is resulting in a null pointer exception. It's usually a good idea to precede close statements in final blocks by null pointer checks for this reason.
When using an ObjectInputStream the input data is required to be in a byte format that can be read into a serialized object, Disease in this case. If the format is not in the expected format a StreamCorruptedException will be thrown. If you are changing the text file manually, chances are that this exception is being thrown but the exact message is not displayed as you are displaying a generic Problem with reading from file message.
Displaying the stack trace will help
iox.printStackTrace();
Ensure that you are writing the objects correctly to file. Alternatively you could use a text based file, and use Printwriter to write, Scanner to read. You can use || for as a Scanner delimiter.

Categories

Resources