public static void generateOutput() {
File file = new File ("C:/Users/me/Desktop/file.txt");
PrintWriter outputFile = null;
outputFile = new PrintWriter(file);
}
Above is my code, I am trying to make a PrintWriter that writes to a file I have made on my desktop called file.txt, however I am getting the error "unhandled exception type, file not found exception". I have looked at other posts and I'm unsure why I am still getting this error. I have also tried doing so without the File object. I was hoping for some guidance as to where I went wrong
The most important idea you have to understand here, is that your file may:
not be found;
have its descriptor locked (which means, that some other process uses it);
be corrupted;
be write-protected.
In all above cases, your Java program, triggering OS Kernel, will crush, and the exception will happen at the runtime. In order to avoid this accident, Java designers decided (and well they did), that PrintWriter should throw (meaning, it is a possibility to throw) FileNotFoundException and this should be a checked exception at compile time. This way developers will avoid more serious run-time problems, like program crush crush.
Hence, you either have to:
try-catch in your method that PrintWriter; or
throw the exception one level up.
I think, your question was about why that happens. Here is the answer for both - (1) why? and (2) how to solve it.
Java has an exception catch mechanism that helps you program better. You will have to handle an exception FileNotFoundException to warn that what will happen if the program cannot find your file Or you can throws this exception. I recommend learning about exception handling in Java.
This code can help you
public static void generateOutput() {
File file = new File ("C:/Users/me/Desktop/file.txt");
PrintWriter outputFile = null;
try {
outputFile = new PrintWriter(file);
} catch (FileNotFoundException e) {
// Handle if your file not found
e.printStackTrace();
}
}
Or
public static void generateOutput() throws FileNotFoundException {
File file = new File ("C:/Users/me/Desktop/file.txt");
PrintWriter outputFile = null;
outputFile = new PrintWriter(file);
}
Assuming your file exists in the given location, you need one of the following,
public static void generateOutput() throws Exception {... Your code ...}
Or
try {
//Your code
}
catch(FileNotFoundException fnne) {
// Precise exception catching example
}
catch(Exception e) {
// Not required, but adding it to catch any other exception you might face
}
You can always use precise exception in throws/catch. You need it because, PrintWriter can has compile time exception. Basically, it means if file is not found then it can throw exception and it is known at compile time. Hence you need to use one of the approach.
In addition to that, you make 2 lines into 1 as follows,
PrintWriter output = new PrintWriter(file);
You don't need to initialize the output object to null, unless you have it on purpose.
Related
We have this code. SONAR is complaining about the main() function.
"main" should not "throw" anything
There's no reason for a main method to throw anything. After all, what's going to catch it?
Instead, the method should itself gracefully handle any exceptions that may bubble up to it, attach as much contextual information as possible, and perform whatever logging or user communication is necessary.
Q: Would adding a catch(IOException e) {} mitigate this issue?
public class EncryptionHelper {
private static final int NO_OF_ARGUMENTS = 3;
/**
* Ctor
*/
protected EncryptionHelper() {
// Empty Ctor
}
/**
* Main
*
* #param args
*
* 0 - Input text to be encrypted or decrypted
* 1 - Encrypt/Decrypt [0-Encrypt, 1-Decrypt]
* 2 - File to write the output
* #throws IOException
*/
public static void main(String[] args) throws IOException {
if (args.length != NO_OF_ARGUMENTS) {
throw new IllegalArgumentException("Expected 3 arguments to encrypt/decrypt.");
}
OutputStreamWriter fw = null;
Crypto crypto = CryptoFactory.getCrypto(CryptoType.KBE);
String en = "";
if ("0".equals(args[1])) {
en = crypto.encryptString(args[0]);
} else {
en = crypto.decryptString(args[0]);
}
try {
fw = new OutputStreamWriter(new FileOutputStream(args[2]), Charset.forName("UTF-8"));
fw.write(en);
} finally {
if (fw != null) {
fw.close();
}
}
}
}
Would adding a catch(IOException e) {} mitigate this issue?
No! I think, that's the worst solution available. By the way, if you would write that, Sonar would complain about the empty catch block - so one issue solved, and one new issue would be the result.
It's more of a design error.
Think about Microsoft Word, or LibreOffice, when you want to open a file, that not exist. (For example you write in the open dialog: notExistingFile.doc and press Enter). If there's not a file, called notExistingFile.doc, it raises some kind of exception (based on the programming language/framework they use).
But instead of, crashing the app, and throw that exception towards, they handle the situation - pop up a window to inform you about the not existent file.
If this is a test-app, or some private project, where you are 100% sure about the file would exist, I would do nothing about it. But if it's a public project, you should handle the exception in some way: write a log about the missing file, inform the user about the missing file (suggest some solution for the problem), etc.
If you want the issue to go away, you should mark that as solved (or hide that issue, there's some way for it). If you'd like to solve it from java code, you should write the following:
try {
// some methods that throw IOException
} catch (IOException ignored) {
// if you call your variable ignored, Sonar won't complain about it
// but you should provide some information about this, why did you ignore that exception
// for developers looking at this code later.
}
In short, yes. Adding a catch block and removing throws IOException from the signature would prevent the issue from being raised. But as Nagy Vilmos points out, that doesn't really solve the problem. Because this is a console application, you should use the catch opportunity to inform the user of the problem. Yes, barfing the exception out at the user (via throws IOException) does that, but it takes so little effort to do that nicely (via catch and logging, as recommended by the rule description).
I am trying to make a java program that appends text into an existing document. This is what it has gotten me at:
import java.util.*;
import java.io.*;
public class Main
{
public main(String args[])
{
System.out.print("Please enter a task: ");
Scanner taskInput = new Scanner(System.in);
String task = taskInput.next();
System.out.print(task);
PrintWriter writer = new PrintWriter("res\tasks.txt", "UTF-8");
writer.println("The first line");
writer.println("The second line");
writer.close();
}
}
I have some errors and do not know how to fix them. I looked at the Bufferedwriter but I don't know how it's used, and yes I have looked javadocs. C++ was not nearly this complicated. Once again, I want to know how to make the program append text to an existing file. It should be efficient enough to make into an app. Are there any good resources to teach how to write/append/read files?? javadoc is not doing it for me.
The main() method in Java has to have the following signature
public static void main(String[] args)
Without the method being declared as above, JVM would fail to run your program. And, just like you closed the PrintWriter, you need to close your Scanner too.
I suggest you get the basics of Java down before diving into File I/O because this API would throw a lot of checked Exceptions too and for someone this new to Java it would just be terribly confusing as to what the try catchs or throws are doing.
try this,
PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter("tasks.txt", true)));
The following should work:
public static void main(String[] args) {
try{
Formatter out = new Formatter("fileName.txt");
out.format("Write this to file");
out.close();
} catch (Exception e) {
System.out.println("An error occurred");
}
}
This is using a Formatter object to create a file (if it doesn't already exist) and then you can use the method "format" just like you would use any print method to write to the file. The try and catch is necessary for it to compile b/c the constructor of the Formatter class throws an exception that must be caught. Other than that, just make sure you type:
import java.util.Formatter;in the beginning of your file.
And btw, C++ is NOT easier than Java lol. Cheers.
while running a sort program for some custom data, I got some runtime exception which took up the whole console in eclipse. I would like to see the cause and the message of the exception.So I used a FileWriter as below to write the exception message. However the textfile is of 0 bytes, meaning nothing is written.
I also tried to run the code from the terminal(in linux -ubuntu) and using > to redirect the exception message ,but only got the output from system.out.println()
The FileWriter doesn't write the exception message.
Below is the relevant part of code.. Can someone tell me why this happened? I tried adding fw.flush() but it didn't make any difference.
public class MySort{
...
public static void sort(String[] data){
...
}
public static void main(String[] args) throws IOException {
String[] a = {"E","A","S","Y","Q","U","E","S","T","I","O","N"};
FileWriter fw = new FileWriter("sorterr.txt");
try{
sort(a);
}catch(RuntimeException e){
System.out.println("some text");
fw.write(e.getMessage());
fw.flush();
fw.close();
System.exit(0);
}
}
}
When run in Eclipse or Linux terminal, sorterr.txt is 0 bytes
In terminal, redirect also behaves the same. In short nothing inside the catch block prints out the values.
UPDATE:
It was a stackoverflow error ,that was the reason why it wasn't caught by the catch block (which was meant for RuntimeException)..
I detected this by setting
System.setErr(new PrintStream(new File("error.txt")));
thus,the stacktrace was printed in error.txt and this showed
Exception in thread "main" java.lang.StackOverflowError
at mysort.exercises.MySort.partition(MySort.java:67)
Try
File file = new File("sorterr.txt");
BufferedWriter output = new BufferedWriter(new FileWriter(file));
output.write(e.getMessage());
output.close();
The problem is that you are using FileWriter wrong.
I just write a simple commandwrapper in java, this is construction function:
Process process;
Thread in;
Thread out;
public CommandWrapper(Process process) {
this.process = process;
final InputStream inputStream = process.getInputStream();
// final BufferedReader
//final BufferedReader r = new BufferedReader(new InputStreamReader(inputStream));
final byte[] buffer = new byte[1024];
out = new Thread() {
// String line;
int lineNumber = 0;
public void run() {
try {
while (true) {
int count = inputStream.read(buffer);
System.out.println(lineNumber + ":"
+ new String(buffer, 0, count - 1));
// line=r.readLine();
// System.out.println(lineNumber+":"+line);
lineNumber++;
}
} catch (Exception e) {
}
}
};
final BufferedReader reader = new BufferedReader(new InputStreamReader(
System.in));
final OutputStream outputStream = process.getOutputStream();
in = new Thread() {
String line;
public void run() {
try {
//while (true) {
outputStream.write((reader.readLine() + "/n")
.getBytes());
outputStream.flush();
//}
} catch (Exception e) {
}
}
};
}
public void startIn() {
in.start();
}
This is when it invoke:
public static void main(String[] args) {
try {
CommandWrapper command = new CommandWrapper(Runtime.getRuntime()
.exec("wget www.google.com"));
//command.startIn();
command.startOut();
} catch (Exception e) {
e.printStackTrace();
}
}
It works OK when I run simple command like ls -l or other local commander, but when I want to run wget command it is print out nothing as output. I do know why.
From the code you've shown and your description of how you use it, the best guess is that an exception occurs, and you silently swallow it. This happens whenever you have an empty catch-block, like this:
catch (Exception e) {
}
You happen to have one in the run() method of your out thread.
Silently swallowing exceptions is extremely bad practice.
You should never ever ever do this! Depending on your application the appropriate solution varies, but since you're writing a console application you probably want to print the stack trace of the exception. In Java, this is done with e.printStackTrace():
catch (Exception e) {
e.printStackTrace();
}
Another option (which might not be appropriate in this specific case) is to rethrow the exception, possibly after wrapping it in another exception (for example one you've written specifically for your application):
catch (Exception e) {
throw e;
}
// or
catch (Exception e) {
throw new MyOwnException(e);
}
Doing either of these two (printing stack trace or rethrowing) will ensure that no exceptions go unnoticed.
However, no rule without exceptions ;)
There are cases when it is appropriate to have empty catch-clauses. If you know that some operation might throw an exception and you just want to proceed when it happens, an empty catch-clause is a good way to do it. However, the cases where this is appropriated are limited to (at least) the following conditions:
You must know the specific type of the exception. You never want to catch a general exception (i.e. catch (Exception e) since that might be thrown for any reason which you cannot possibly predict. If you use empty catch clauses, always catch specific exception type (such as IOException).
You must know why the exception was thrown. You should only swallow exceptions that you know the origin of. If you swallow any other exceptions, you'll end up like in this situation, where your code doesn't do what you expect and you can't understand why. Swallowed exceptions are extremely difficult to debug, since they are, well, swallowed, and thereby hidden.
You must know that you don't care about the exception. The reason to use empty catch-clauses is mainly (read: only) to handle situations where the code you're using treats something as exceptional, while you do not. By exeptional in this context we mean "something that shouldn't really happen, and if it does, something is seriously wrong."
An example of when empty catch-clauses are appropriate:
Say that you are using someone elses code that opens a file for reading, given the absolute path of the file. Most such routines throw exceptions if the file does not exist - it is the job of the client code (i.e. the code that calls the "open file routine") to ensure that the file exists before trying to open it. Exceptions will also be thrown if, for example, the user running the program does not have permissions to read the file.
Now, you might not really care why the file couldn't be opened, but if it couldn't you just want to keep going - in that case, you swallow all exceptions related to reading the file (in Java, likely an IOException of some sort). Note that you do not swallow all exceptions - only the ones related to opening the file!
public void exportUrlsToFile(String file, String urls) throws IOException {
String[] urlsArray = urls.split("\\s+");// split on one or more white space characters.
// create a fresh file
RandomAccessFile raf = new RandomAccessFile(file, "rw");
for (String line : urlsArray) {
line = line.trim();
if (line.isEmpty()) {// this won't happen!
continue;
}
raf.writeBytes(line);
raf.writeBytes(newline);
}
// close the file handler
raf.close();
}
Basically, I use this class to do something. This is part of the application that is running inside Tomcat JVM. I have noticed that anytime this method is called, it creates a file with the same name as the argument and after raf.close(), it is still there.
How can I make sure that the temp file is removed?
A better question would be why you would want to go through all the trouble of making the file, writing things to the file, and then just delete the file?!
Regardless you don't need a random access file - a FileWriter would be better.
To ensure that the file is deleted do as Eddie suggests and put the delete in a finnaly block - but you will also need to ensure that the raf.close() IOException is handled... something like:
} finally {
try
{
raf.close();
}
catch(final IOException ex)
{
// in 14 years of Java programming I still don't know what to do here! ;-)
}
finally
{
File todelete = new File(file);
if (!todelete.delete()) {
// Log a complaint that we couldn't delete the temp file
}
}
}
Edit:
You might also mean that after the Tomcat process finished the file is still there and you want it gone. If that is the case look at java.io.File.deleteOnExit(). That should delete the files when the Tomcat JVM exists.
I'm going to assume that you're showing only a small portion of the code and that there's a good reason that you're using RandomAccessFile when it doesn't appear that any random access is being done.
I would do something like this:
public void exportUrlsToFile(String file, String urls) throws IOException {
String[] urlsArray = urls.split("\\s+");
// create a fresh file
RandomAccessFile raf = new RandomAccessFile(file, "rw");
try {
for (String line : urlsArray) {
line = line.trim();
if (line.isEmpty()) { // this won't happen!
continue;
}
raf.writeBytes(line);
raf.writeBytes(newline);
}
} finally {
// don't leak file handles on Exception -- put close in "try/finally"
try { raf.close(); } catch (IOException e) { /* ignore */ }
File todelete = new File(file);
if (!todelete.delete()) {
// Log a complaint that we couldn't delete the temp file
}
}
}
EDIT: I agree, we don't want the theoretical IOException on close() to cause problem. Better than ignoring it would be to log a "We never expected to see this...." with the exception. I often create a closeWithoutException() method just to wrap this. Close theoretically throwing IOException seems an abuse of checked exceptions because there's nothing you can expect the caller to do in response.
Use File.createTempFile() instead?
I realize that won't give you the same features as RandomAccessFile but you could build what you need on top of that.
Actually I'm not even sure why you're writing these things to a file. Is this some kind of usage tracking thing? Why not just store it in memory?
Did you try this ?
File temp = File.createTempFile("file", ".tmp");
temp.deleteOnExit( );