I am using FileReader wrapped in BufferedReader to read from 2 files, in case of an exception being thrown I want to know which file caused the error.
Is there a way of finding that out?
try (BufferedReader input1 = new BufferedReader(new FileReader(pathToFile1));
BufferedReader input2 = new BufferedReader(new FileReader(pathToFile2))){
// some more code here
} catch (FileNotFoundException e) {
System.err.println("File Not Found");
System.err.println(e.getMessage());
System.exit(2);
} catch (IOException e) {
System.err.println(e.getMessage());
System.exit(1);
Basically I want to know which file was not found and caused the first exception to be thrown.
Though I wouldn't recommend it (as it depends on linenumbers which might change if run through a preprocessor) You could use something like this
int topLine= new Throwable().getStackTrace()[0].getLineNumber();
try (BufferedReader input1 = new BufferedReader(new FileReader("pop"));
BufferedReader input2 = new BufferedReader(new FileReader("poo"))){
// some more code here
} catch (Exception e) {
StackTraceElement[] er= e.getStackTrace();
int exceptLine = er[er.length-1].getLineNumber() - topLine;
if (exceptLine==1) {
// error in first buffered reader
} else if (exceptLine==2) {
// error in second buffered reader
} else {
// error elsewhere
}
}
Related
I'm currently trying to save the output of my code into a text file, when I run it on a different project it generates the output file and stores the output respectively, however when I run the same code in a different project it gives me blank output file and I do not really know what's the matter. I'm confused as to where to put the .close() function and the flush function as well. Thank you in advance!
FileWriter output = new FileWriter("set.txt");
BufferedWriter writer = new BufferedWriter(output);
InputStream fis_n = new FileInputStream("/Users/User/NetBeansProjects/Test/src/test/sample.txt");
InputStreamReader isr_n = new InputStreamReader(fis_n, Charset.forName("UTF-8"));
BufferedReader br_n = new BufferedReader(isr_n);
while ((input = br_n.readLine()) != null) {
String[] s = input.split(":");
if (s[1].equals(text)) {
writer.write(s[0] + "'s result is " + sample_text);
writer.newLine();
break;
}
}
writer.close();
output.close();
This is what the edited code looks like, yet still the output file "set.txt" is empty upon running the program.
FileWriter output = new FileWriter("set.txt");
BufferedWriter writer = new BufferedWriter(output);
InputStream fis_n = new FileInputStream("/Users/User/NetBeansProjects/Test/src/test/sample.txt");
InputStreamReader isr_n = new InputStreamReader(fis_n, Charset.forName("UTF-8"));
BufferedReader br_n = new BufferedReader(isr_n);
try {
while ((input = br_n.readLine()) != null) {
String[] s = input.split(":");
if (s[1].equals(text)) {
writer.write(s[0] + "'s result is " + sample_text);
writer.newLine();
break;
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
writer.close();
fis_n.close();
isr_n.close();
br_n.close();
} catch (IOException e) {
e.printStackTrace();
}
}
// fis_n.close();
//isr_n.close();
//br_n.close();
}
This is what the final code looks like:
public static void dictionary(String sample_text, String text) throws FileNotFoundException, IOException {
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
new FileInputStream("/Users/User/NetBeansProjects/Test/src/test/sample.txt"),
Charset.forName("UTF-8")
));
try {
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream("/Users/User/NetBeansProjects/Test/src/test/set.txt"),
Charset.forName("UTF-8")
));
try {
String input;
while ((input = reader.readLine()) != null) {
String[] s = input.split(":");
if (s[1].equals(text)) {
writer.write(s[0] + "'s result is " + sample_text);
writer.newLine();
break;
}
}
} finally {
writer.close();
}
} finally {
reader.close();
}
} catch (IOException e) {
// Error handling
}
}
This is the main method where the dictionary method is being called.
public static void main(String[] args) throws FileNotFoundException, IOException {
case 2: {
BufferedReader d_br = new BufferedReader(new InputStreamReader(
new FileInputStream("/Users/User/NetBeansProjects/Test/src/test/input_file.txt"),
Charset.forName("UTF-8")
));
try {
String d_line;
while ((d_line = d_br.readLine()) != null) {
String h_input = test(d_line);
dictionary(d_line, h_input);
}
} catch(IOException e){
}finally {
d_br.close();
}
break;
}
}
You should put writer.close() after the while loop, and preferable, into the finally section.
If there is no requirement to store partially-processed files (as in most cases), you may remove flush at all. In the other case, it is better to leave it where it is.
The generic case of resource usage on Java 7+ looks like follows (this syntax is called try-with-resources:
try (
Resource resource1 = // Resource 1 initialization
Resource resource2 = // Resource 2 initialization
...
) {
// Resource utilization
} catch (XXXException e) {
// Something went wrong
}
Resource are freed (closed) automatically by try-with-resources.
If you need to use Java 6 or earlier, the above code could be roughly translated to the following (actually there are some subtle differences, that is not important at this level of details).
try {
Resource1 resource1 = // Resource initialization
try {
Resource2 resource2 = // Resource initialization
try {
// Resource utilization
} finally {
// Free resource2
resource2.close();
}
} finally {
// Free resource1
resource1.close();
}
} catch (XXXException e) {
// Something went wrong
}
Notice, how nested try-finally blocks used for resource management.
In your particular case we need to manage two resources: Reader and Writer, so the code will look as follows:
try (
// Notice, we build BufferedReader for the file in a single expression
BufferedReader reader = new BufferedReader(new InputStreamReader(
new FileInputStream("sample.txt"),
StandardCharsets.UTF_8 // Better replacement for Charset.forName("UTF-8")
));
// Alternative way to do the same
// BufferedReader reader = Files.newBufferedReader(Paths.get("sample.txt"), StandardCharsets.UTF_8);
// Output charset for writer provided explicitly
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream("set.txt"),
StandardCharsets.UTF_8
))
// Alternative way to do the same
// BufferedWriter writer = Files.newBufferedWriter(Paths.get("set.txt"), StandardCharsets.UTF_8)
) {
String input;
while ((input = reader.readLine()) != null) {
String[] s = input.split(":");
if (s[1].equals(text)) {
writer.write(s[0] + "'s result is " + text);
writer.newLine();
break;
}
}
} catch (IOException e) {
// Error handling
}
Or, using pre-Java7 syntax:
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
new FileInputStream("sample.txt"),
Charset.forName("UTF-8")
));
try {
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream("set.txt"),
Charset.forName("UTF-8")
));
try {
String input;
while ((input = reader.readLine()) != null) {
String[] s = input.split(":");
if (s[1].equals(text)) {
writer.write(s[0] + "'s result is " + text);
writer.newLine();
break;
}
}
} finally {
writer.close();
}
} finally {
reader.close();
}
} catch (IOException e) {
// Error handling
}
First of all, you call the flush method of a writer, whenever you want the current buffer to be written immediately. If you just write a file completely without any intermediate operation on your output, you do not need to call it explicitly, since the close call will do that for you.
Secondly, you only call the close method of the top-level reader or writer, in your case BufferedWriter. The close call is forwarded to the other assigned readers or writers. Multiple consecutive close calls do not have any effect on a previously closed instance, see here.
As a general note to using readers and writers, consider this pattern:
// This writer must be declared before 'try' to
// be visible in the finally block
AnyWriter writer = null;
try {
// Instantiate writer here, because it can already
// throw an IOException
writer = new AnyWriter();
// The the writing in a loop or as you wish
// If you need to write out the buffer in
// between, call flush
} catch (IOException e) {
// Something went wrong while writing
} finally {
try {
if (writer != null)
writer.close();
} catch (IOException e) {
// Exception while trying to close
}
}
The finally block is ALWAYS executed. If you need a more compact syntax and you use at least Java 7, you can have a look at the try-with notation here.
I want the user to enter a filename on the command line. If they don't enter any, I should print information says file was not processed and exit out. Here is my try catch block
try{
parser.openFile(args[0]);
if(parser.getCounter() == 3)
{
System.out.println("File was processed: true");
}
else
{
System.out.println("File was processed: false. Missing information.");
}
//found = true;
}
catch (IOException e)
{
e.printStackTrace();
System.out.println("File was processed: false. Re-enter filename.");
//fName = keyboard.nextLine();
}
The openFile method is in my class, and it is here, in case anyone needs it:
public void openFile (String filename)throws IOException{
fis = new FileInputStream(filename);
br = new BufferedReader(new InputStreamReader(fis));
String thisLine;
thisLine = br.readLine();
while(thisLine != null)
{
lines.add(thisLine);
thisLine = br.readLine();
}
}
Somehow "File was processed: false. Re-enter filename." does not printed out when there is not filename in the command line. Can anyone help me please?
Probably you're getting a different exception. Maybe
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException:
Try to validate the content of args
Example:
public class TesteArgs {
public static void main(String[] args) {
if (args.length == 0) {
System.out.println("Inform a valid name...");
System.exit(0);
}
// continue handling your args param
System.out.println(args[0]);
}
}
Change your IOException to Exception in your catch statement, that'll get 'em exceptions caught nicely for ya.
You can catch multiple exception in try{}catch{} block.
You have to catch specific exceptions (ArrayIndexOutOfBoundsException, which is child of Exception) first and generic exception (Exception) later.
Sample code:
try{
// Your code
File f = new File ("a.txt");
FileInputStream fio = new FileInputStream(f);
}catch(ArrayIndexOutOfBoundsException ae ){
System.out.println(ae);
}catch(IndexOutOfBoundsException ee ){
System.out.println(ee);
}catch(IOException ioe ){
System.out.println(ioe);
}catch(RuntimeException re ){
System.out.println(re);
}catch(Exception e ){
System.out.println(e);
}catch(Throwable t ){
System.out.println(t);
}
Have a look at hierarchy of exceptions
I'm creating a mini program that deletes Files using the File.delete() method but I'm having a little bit of an issue if I use the buffered Reader to read the .txt file before I delete it, it doesn't delete the file. I did come up with a solution for it: I just close the buffered reader before I delete the file. however this doesn't make sense to me as to why this is happening can anyone explain this.
import java.io.*;
import java.nio.file.Files;
public class Purge {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
String sample;
boolean result = false;
BufferedReader amg = new BufferedReader(new FileReader("C:/Users/Steven/Desktop/me.txt"));
sample = amg.readLine();
amg.close();// closes the buffered reader
System.out.println("Haha I'm stille here: "+sample);
File anesu = new File("C:/Users/Steven/Desktop/me.txt");
if (anesu.exists()){
try{result = anesu.delete();
}catch( Exception x){
System.out.println("Problem Deleting File"+x);
}
catch( Throwable e){
System.out.println("Problem Deleting File Throwable"+e);
}
}else{
System.out.println("No File ");
}
System.out.println("File has been deleted: "+result);
}
}
When a stream object is garbage collected, its finalizer closes the underlying file descriptor. So, the fact that the delete only works when you added the System.gc() call is strong evidence that your code is somehow failing to close some stream for the file. It may well be a different stream object to the one that is opened in the code that you posted.
Note :
Properly written stream handling code uses a finally block to make sure that streams get closed no matter what.
If you does not want to use System.gc(), read your content with FileInputStream
InputStream in = new FileInputStream(new File("C:/temp/test.txt"));
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuilder out = new StringBuilder();
try {
String line;
while ((line = reader.readLine()) != null) {
out.append(line);
}
System.out.println(out.toString()); //Prints the string content read from input stream
}
catch(Exception ex) {//TODO}
finally {
reader.close();
}
You can delete the file in the finally block.
A downside to this approach is that if an exception is thrown the file will still be deleted.
public Stream<String> readLines(Path archive) {
try {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(
(new FileInputStream(archive.toFile()))));
return bufferedReader.lines();
} catch (IOException e) {
throw new UncheckedIOException(e);
} finally {
try {
Files.delete(archive);
System.out.println("Deleted: " + archive);
} catch (IOException e) {
System.out.println("Unable to delete: " + archive);
}
}
}
i want use my java class on the hadoop hdfs, now i must rewrite my functions.
the problem is, if i use the InputStreamReader my app read wrong values.
here my code (so it's work, i want use the uncommented code part):
public static GeoTimeDataCenter[] readCentersArrayFromFile(int iteration) {
Properties pro = new Properties();
try {
pro.load(GeoTimeDataHelper.class.getResourceAsStream("/config.properties"));
} catch (Exception e) {
e.printStackTrace();
}
int k = Integer.parseInt(pro.getProperty("k"));
GeoTimeDataCenter[] Centers = new GeoTimeDataCenter[k];
BufferedReader br;
try {
//Path pt=new Path(pro.getProperty("seed.file")+(iteration-1));
//FileSystem fs = FileSystem.get(new Configuration());
//br=new BufferedReader(new InputStreamReader(fs.open(pt)));
br = new BufferedReader(new FileReader(pro.getProperty("seed.file")+(iteration-1)));
for(int i =0; i<Centers.length; i++){
String[] temp = null;
try{
temp = br.readLine().toString().split("\t");
Centers[i] = new GeoTimeDataCenter(Integer.parseInt(temp[0]),new LatLong(Double.parseDouble(temp[1]),Double.parseDouble(temp[2])),Long.parseLong(temp[3]));
}
catch(Exception e) {
temp = Seeding.randomSingleSeed().split("\t");
Centers[i] = new GeoTimeDataCenter(i,new LatLong(Double.parseDouble(temp[0]),Double.parseDouble(temp[1])),DateToLong(temp[2]));
}
}
br.close();
} catch (IOException e) {
e.printStackTrace();
}
return Centers;
}
maybe someone know this problem?
best regards
i have found the problem. i have get a checksum exception. now i delete all .crc files from my input file. in this way i get no checksum exception and the buffered reader work fine (uncommented code part, upstairs).
I'm sure there is a fairly simple answer to this question, so here we go.
I'm trying to use a FileWriter to write text to a file. My program reads text in from an already existing file, specified by the user and then asks whether to print the text to the console or to a new file, also to be named by the user.
I believe my problem is with passing the FileWriter to the "FileOrConsole" method. Am I not passing or declaring the FileWriter in the "FileOrConsole" method correctly? The file is always created but nothing is written to it.
Here is the code:
import java.io.*;
import java.util.*;
public class Reader {
public static void main(String[] args) throws IOException {
Scanner s = null, input = new Scanner(System.in);
BufferedWriter out = null;
try {
System.out.println("Would you like to read from a file?");
String answer = input.nextLine();
while (answer.startsWith("y")) {
System.out.println("What file would you like to read from?");
String file = input.nextLine();
s = new Scanner(new BufferedReader(new FileReader(file)));
System.out
.println("Would you like to print file output to console or file?");
FileOrConsole(input.nextLine(), s, input, out);
System.out
.println("\nWould you like to read from the file again?");
answer = input.nextLine();
}
if (!answer.equalsIgnoreCase("yes")) {
System.out.println("Goodbye!");
}
} catch (IOException e) {
System.out.println("ERROR! File not found!");
// e.printStackTrace();
} finally {
if (s != null) {
s.close();
}
if (out != null) {
out.close();
}
}
}
public static void FileOrConsole(String response, Scanner s, Scanner input,
BufferedWriter out) {
if (response.equalsIgnoreCase("console")) {
while (s.hasNext()) {
System.out.println(s.nextLine());
}
} else if (response.equalsIgnoreCase("file")) {
System.out.println("Name of output file?");
response = input.nextLine();
try {
out = new BufferedWriter(new FileWriter(response));
} catch (IOException e) {
e.printStackTrace();
}
while (s.hasNext()) {
try {
out.write(s.nextLine());
out.newLine();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
} else {
System.out.println("Sorry, invalid response. File or console?");
response = input.nextLine();
FileOrConsole(response, s, input, out);
}
}
}
you make classic error forgetting that parameters passed by value in case of java it is a value of the reference. The thing is that your assignment
out = new BufferedWriter(new FileWriter(response));
actually does not change the variable declared in main() it stays null
BufferedWriter out = null;
and then in finally it skips the close() by the if(out==null)
and as it is Buffered and you do no flush nothing is written to file.
what you got to do is out.close(); in side the FileOrConsole method call
OR
do the out = new BufferedWriter(new FileWriter(response));
outside of it. You choose :-)
Try flushing your stream, but more importantly, remember to close it.
Here's a code example of recommended practice for handling streams. Same approach can be used for input streams too and things like database code where it's important to always clean up after yourself to get the expected results.
BufferedWriter out = null;
try {
out = // ... create your writer
// ... use your writer
} catch(IOException ex) {
// maybe there was a problem creating or using the writer
} finally {
if (null != out) {
out.flush();
out.close();
out = null;
}
}