Java.IO.FileNotFoundException Handling - java

When doing this, I am trying to make it "dummy proof" for my coworkers, so if they put in a file path instead of a file - the program doesn't stop so that they can just keep going in the application - it'll just ask them again. However currently
FileNotFoundException: C:\Users\usersname\Desktop\userImports\current (Access is denied)
java.io.FileNotFoundException: C:\Users\usersname\Desktop\userImports\current (Access is denied)
How do I work for this? I don't want it to crash like this, I'd rather it just say, "thats not a file - please try again"
How do I better handle file not found exceptions?
File f;
do {
System.out.print("Please give me the " + type + "file: " );
String file = console.nextLine();
f = new File(file);
} while (!f.exists());
Scanner readMe = null;
try {
readMe = new Scanner(f);
} catch (FileNotFoundException e) {
System.err.println("FileNotFoundException: " + e.getMessage());
e.printStackTrace();
}
return readMe;
}

I'm not sure I understood what you exactly want but this is my answer to what I understood :
Just loop while u don't find the file and you can also add a counter like after 5 times u exit the program.
File f;
boolean found = false ;
while (!found) {
do {
System.out.print("Please give me the " + type + "file: " );
String file = console.nextLine();
f = new File(file);
} while (!f.exists());
Scanner readMe = null;
try {
readMe = new Scanner(f);
found = true ;
} catch (FileNotFoundException e) {
found = false ;
System.err.println("FileNotFoundException: " + e.getMessage());
system.out.printl ( "A problem occured while loading the file please try again ");
//e.printStackTrace();
}
}
return readMe;
}

"Access is denied" means that the file does exist but the user who ran the program is not allowed to access - in your case read - it. It could be, i.a., that the user does not have the necessary authority, or that the file is being held by another program.

Try to use canRead() instead of exists()
do {
...
} while (!f.canRead());

Related

I keep getting an FileNotFoundException error, but I declared it thrown in the method and included a try/catch block

I can make this code work if I modify the main method class, but I am supposed to make it work WITHOUT modifying it at all. I'm confused as to what is causing the error.
Here is the method I have written in a class
public boolean addSongs(String fileName)throws FileNotFoundException
{
Scanner scan = null;
try //open the try block for FNFE
{
//open the file, declare scanner, set endFile to false
scan = new Scanner(new File(fileName));
boolean endFile = false;
while(!endFile) //continues until the end of the file
{
try //try block for mismatch exception or no such element
{
//scan in line and read through it with new delimiter
String line = scan.nextLine();
Scanner read = new Scanner(line);
read.useDelimiter("/");
//scan in name, minutes, and seconds on the scanned line
String scannedName = read.next();
int scannedMin = read.nextInt();
int scannedSec = read.nextInt();
//print the results
System.out.print("Name: " + scannedName + "\n" +
"Minutes: " + scannedMin + "\n" +
"Seconds: " + scannedSec +
"\n-----------------------------------\n");
//add to the playlist if no errors
title.add(new Song(scannedName, scannedMin, scannedSec));
}
catch(InputMismatchException e) // handle when data is N/A
{
String error = scan.nextLine(); //consume the error and return to see where error is occurring
System.out.print( " ERROR (cause): " + error + "\n");
}
catch(NoSuchElementException e) // handle when no more data in file
{
endFile = true; //nothing in file set endFile
}
} //close try block
//close and return true
scan.close();
return true;
}// close loop
//return false if no file found
catch (FileNotFoundException e)
{
System.out.println("THERE IS NO FILE BRETHREN");
return false;
}
}// close method
Here is the code thats causing an issue in the main class
if (b.addSongs("revolver.txt"))
System.out.println("Songs in file revolver.txt added successfully");
System.out.printf("The playlist \"%s\" has a total playing time of %5.2f minutes\n", b.getName(), b.getPlayingTime());
System.out.printf("It includes the song \"%s\" with a playing time of %4.2f minutes\n", song, b.getPlayingTime(song));
System.out.printf("The longest song is \"%s\"\n", b.longestSong());
if (b.removeSong("Taxman"))
System.out.println("The song \"Taxman\" was removed successfully");
System.out.println("\n" + b); }
This is the error message:
PLTest.java:32: error: unreported exception FileNotFoundException; must be caught or declared to be thrown
b.addSongs("revolver.txt");
^
My solution is to add in a FileNotFoundException throw in the main class, but as I stated before ._. I am banned from changing it. I don't see what keeps going wrong since the invoked method throws the exception. It's the only error that occurs and when I add the throw to the main class everything works perfectly.
For a side note: I attempted to put the throw in another method and got a duplicate error that went away when I just removed the throw. I don't know if that is relevant but my next guess is to find a way to change the boolean values without a try/catch?
Use
scan = new Scanner(new FileReader(new File(fileName)));
instead of
scan = new Scanner(new File(fileName));
and make sure that the text files are along side of the src folder. Hove the exceptions will solved.

Renaming existing file in java

I am programming a basic notepad program and I want it to be able to rename files from the command line. If the user writes "rename" to scanner, the program changes the note's file name according to input, like -rename stack. But if user enter two new note names. Program will error like Invalid note name for renaming. It contains ' '. Enter one word.. If a proposed name is used by an existing file, the program will print File already exists.
How can i do this:
-rename stack
Enter new note name?
stack over
Invalid note name for renaming. It contains 'over'. Enter one word
-rename stack
Enter new note name?
over
File already exists
This is what I've written so far:
...
else if (noteNameSplited[0].equals("rename")) {
File file = new File(noteNameSplited[1]+".ncat");
if(!file.exists()) {
System.out.println("File does not exist !");
}
else {
System.out.println("Enter the new note name");
String data=scan.nextLine();
File file2 = new File(data+".ncat");
file.renameTo(file2);
}
}
This may help you:
https://github.com/openstreetmap/osmosis/blob/master/osmosis-core/src/main/java/org/openstreetmap/osmosis/core/util/AtomicFileCreator.java#L50
if (!tmpFile.exists()) {
throw new OsmosisRuntimeException("Can't rename non-existent file " + tmpFile + ".");
}
// Delete the existing file if it exists.
if (file.exists()) {
if (!file.delete()) {
throw new OsmosisRuntimeException("Unable to delete file " + file + ".");
}
}
// Rename the new file to the existing file.
if (!tmpFile.renameTo(file)) {
throw new OsmosisRuntimeException(
"Unable to rename file " + tmpFile + " to " + file + ".");
}
You can try the following:
public boolean renameTo(File dest) {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkWrite(path);
security.checkWrite(dest.path);
}
return fs.rename(this, dest);
}

Can't remove or rename file

I am trying to remove the last line of a CVS file, to do so I need to rename / delete my input file, I tried several things, but I can't get it to work, this is what I got now:
File inputFile = new File((file.getParent() + "/ExportLijst " + dateFormat.format(date) + ".csv"));
inputFile.setWritable(true, true);
File f = (inputFile);
if (!f.exists())
throw new IllegalArgumentException(
"Delete: no such file or directory: " + inputFile);
if (!f.canWrite())
throw new IllegalArgumentException("Delete: write protected: "
+ inputFile);
if (f.isDirectory()) {
String[] files = f.list();
if (files.length > 0)
throw new IllegalArgumentException(
"Delete: directory not empty: " + inputFile);
}
boolean success = f.renameTo(removeFile);
if (!success)
throw new IllegalArgumentException("Delete: deletion failed");
I also tried this, with no result:
public void forceRename(File source, File target) throws IOException
{
if (target.exists())
target.delete();
source.renameTo(target);
}
Most likely you did not close the file, and then the other file operations will not do on Windows.
The code snippets you have put together for us, are in this way not very coherent - of course.
They look fine, though one would need to see the context. A bit much.
So try ensuring a close:
try (PrintWriter csvOut = ...) {
...
} // Automatic close

How to solve my try-catch exception handling?

I'm having problems with my try-catch exception here. Actually what it does is to prompt the user for the name of a text file say, Robot.txt but if say the file does not exist, I have to make sure that the application reprompts the user for the file name. Hope you guys can understand I'm still a newbie here so please feel free to provide suggestions or advices on my coding etc. Cheers!
Main method class:
import java.io.*;
import java.util.Scanner;
import java.util.Vector;
class TestVector3 {
public static void main(String [] args)
{
System.out.println("Please enter the name of the text file to read: ");
Scanner userInput = new Scanner(System.in);
Vector <KillerRobot> robotDetails = new Vector <KillerRobot>();
KillerRobot robot;
Scanner fileInput = null;
try
{
File textFile = new File(userInput.nextLine());
fileInput = new Scanner(textFile);
}
catch (FileNotFoundException e)
{
System.out.println("Error - file not found!");
System.out.println("Re-enter file name :"); //Reprompt user for name of the text file
fileInput = new Scanner(userInput.nextLine());
}
while(fileInput.hasNext())
{
robot = new KillerRobot();
String first = fileInput.next();
robot.setName(first);
String second = fileInput.next();
robot.setMainWeapon(second);
int third = fileInput.nextInt();
robot.setNumberOfKills(third);
robotDetails.add(robot);
}
for(KillerRobot i : robotDetails)
{
System.out.println(i);
}
fileInput.close();
}
}
KillerRobot class file:
class KillerRobot {
private String name;
private String mainWeapon;
private int numberOfKills;
KillerRobot()
{
}
public String getName()
{
return name;
}
public String getMainWeapon()
{
return mainWeapon;
}
public int getNumberOfKills()
{
return numberOfKills;
}
public String toString()
{
return name + " used a " + mainWeapon + " to destroy " + numberOfKills + " enemies ";
}
public void setName(String a)
{
name = a;
}
public void setMainWeapon(String b)
{
mainWeapon = b;
}
public void setNumberOfKills(int c)
{
numberOfKills = c;
}
}
As you state that you are a beginner, let us first look at the relevant part of your code, to make sure that we talk about the same thing:
Scanner fileInput = null;
try {
File textFile = new File(userInput.nextLine());
fileInput = new Scanner(textFile);
}
catch (FileNotFoundException e) {
System.out.println("Error - file not found!");
System.out.println("Re-enter file name :");
fileInput = new Scanner(userInput.nextLine());
}
You have an input and you want to check this input for a condition and require a new input until this condition is fulfilled. This problem can be solved using a loop like the following:
Scanner fileInput = null;
do {
System.out.println("Enter file name :");
try {
fileInput = new Scanner(new File(userInput.nextLine()));
} catch (FileNotFoundException e) {
System.out.println("Error - file not found!");
}
} while(fileInput == null);
So finally, why does this work? The fileInput variable is set to null and will remain null until the given file is successfully read from standard input because an exception is thrown otherwise what prevents the fileInput variable to be set. This procedure can be repeated endlessly.
On a side note, for performance reasons, it is normally not a good idea to implement control flow that is based on exceptions. It would be better to check for a condition if a file exists via File::exists. However, if you read the file after checking for its existence, it might have been deleted in the meantime which introduces a racing condition.
Answer to your comment: In Java (or almost any programming language), you can inline expressions. This means that instead of calling two methods in two different statements as in
Foo foo = method1();
Bar bar = method2(foo);
you can simply call
Bar bar = method2(method1());
This way, you save yourself some space (what becomes more and more important if your code gets longer) as you do not need the value that you saved in foo at any other place in your code. Similarly, you can inline (which is how this pattern is called) from
File file = new File(userInput.nextLine())
fileInput = new Scanner(file);
into
fileInput = new Scanner(new File(userInput.nextLine()));
as the file variable is only read when creating the Scanner.
Try putting the try-catch in a loop like below:
Scanner fileInput = null;
while (fileInput==null)
{
try
{
System.out.println("Please enter the file name.");
File textFile = new File(userInput.nextLine());
fileInput = new Scanner(textFile);
}
catch (FileNotFoundException e)
{
System.out.println("Error - file not found!");
}
}
Next you could think of moving the File creation part into separate method, so that the code was cleaner.
Do not fall for try-catch instead add this as your functionality. Exceptions are naturally for run time error handling not for logic building.
Check if file exists at given location.
File textFile = new File(userInput.nextLine());
// Check if file is present and is not a directory
if(!textFile.exists() || textFile.isDirectory()) {
System.out.println("Error - file not found!");
//Reprompt user for name of the text file
System.out.println("Re-enter file name :");
fileInput = new Scanner(userInput.nextLine());
}
You can put while loop instead of if loop if you want to continuously prompt user until correct path is entered.
You can call back your main(), like following
try
{
File textFile = new File(userInput.nextLine());
fileInput = new Scanner(textFile);
}
catch (FileNotFoundException e)
{
System.out.println("Error - file not found!");
main(args); // recursively call main() method
}
Now if user first attempt wrong then your code will asked to re enter file name.
How to check isFile exist?
File file = new File(filePathString);
if(file.exists() && !file.isDirectory()){
System.out.println("file exist");
}
This really is an XY problem because you assumed the only way to check for a file existence is by catching a FileNotFoundException (hence asking about try-catch exception handling) whereas other means exist to help you avoid a try-catch idiom in an elegant manner.
To check if a file exists at the given path or not you can simply use the File.exists method. Please also see the File.isFile method and/or the File.isDirectory method to verify the nature of the targeted File object.
EDIT : As stated by raphw, this solution is best used in simple scenario since it can incur a race condition in the case of concurrent file deletion happening during the file existence check. See his answer for handling more complex scenario.

How to deal with corrupted files that were created but IOException occured?

Could you please suggest how to deal with these situations ? I understand that in the second example, it is very rare that it would happen on unix, is it ? If access rights are alright. Also the file wouldn't be even created. I don't understand why the IOException is there, either it is created or not, why do we have to bother with IOException ?
But in the first example, there will be a corrupted zombie file. Now if you tell the user to upload it again, the same thing may happen. If you can't do that, and the inputstream has no marker. You loose your data ? I really don't like how this is done in Java, I hope the new IO in Java 7 is better
Is it usual to delete it
public void inputStreamToFile(InputStream in, File file) throws SystemException {
OutputStream out;
try {
out = new FileOutputStream(file);
} catch (FileNotFoundException e) {
throw new SystemException("Temporary file created : " + file.getAbsolutePath() + " but not found to be populated", e);
}
boolean fileCorrupted = false;
int read = 0;
byte[] bytes = new byte[1024];
try {
while ((read = in.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
} catch (IOException e) {
fileCorrupted = true;
logger.fatal("IO went wrong for file : " + file.getAbsolutePath(), e);
} finally {
IOUtils.closeQuietly(in);
IOUtils.closeQuietly(out);
if(fileCorrupted) {
???
}
}
}
public File createTempFile(String fileId, String ext, String root) throws SystemException {
String fileName = fileId + "." + ext;
File dir = new File(root);
if (!dir.exists()) {
if (!dir.mkdirs())
throw new SystemException("Directory " + dir.getAbsolutePath() + " already exists most probably");
}
File file = new File(dir, fileName);
boolean fileCreated = false;
boolean fileCorrupted = false;
try {
fileCreated = file.createNewFile();
} catch (IOException e) {
fileCorrupted = true;
logger.error("Temp file " + file.getAbsolutePath() + " creation fail", e);
} finally {
if (fileCreated)
return file;
else if (!fileCreated && !fileCorrupted)
throw new SystemException("File " + file.getAbsolutePath() + " already exists most probably");
else if (!fileCreated && fileCorrupted) {
}
}
}
I really don't like how this is done in Java, I hope the new IO in Java 7 is better
I'm not sure how Java is different than any other programming language/environment in the way you are using it:
a client sends some data to your over the wire
as you read it, you write it to a local file
Regardless of the language/tools/environment, it's possible for the connection to be interrupted or lost, for the client to go away, for the disk to die, or for any other error to occur. I/O errors can occur in any and all environments.
What you can do in this situation is highly dependent on the situation and the error that occured. For example, is the data structured in some way where you could ask the user to resume uploading from record 1000, for example? However, there is no single solution that fits all here.

Categories

Resources