In my current project I am having an issue with not receiving a file not found exception. My driver file passes the path to be opened to the constructor that is building a library of books. I am using JFileChooser to get the path. In trying to force an error (entering the name of a file that does not exist), it builds the library with no information in it, and does not throw an error.
Driver Code:
//open an existing library
JFileChooser dlg = new JFileChooser ("LibraryData");
FileNameExtensionFilter filter = new FileNameExtensionFilter ("Text Files", "txt");
dlg.setFileFilter(filter);
dlg.setDialogTitle("Select Existing File");
dlg.setApproveButtonToolTipText("Select the file you want to open and click me.");
int button = dlg.showOpenDialog(null);
if (button == dlg.APPROVE_OPTION)
{
currentPath = dlg.getSelectedFile().getPath();
library = new PersonalLibrary(currentPath);
System.out.println("===========================================================");
System.out.println("File opened successfully from: \n" + currentPath);
System.out.println("===========================================================");
}
Util.enterToContinue();
Util.clearScreen();
break;
Library Code:
public PersonalLibrary(String path)
{
try
{
File myFile = new File(path);
if (myFile.exists())
{
Scanner input = new Scanner(myFile);
while(input.hasNext())
{
//code that populates the library
}
input.close();
saveNeeded = false;
}
}
catch (FileNotFoundException e)
{
System.out.println("Error: " + e.getMessage());
}
Your checking if the file exists the catch block will never be executed.
if(myFile.exists())
If it doesn't exist nothing else will be executed including catch block. FileNotFoundException could not occur in this block of code. If you want to catch FileNotFoundException get rid of the if block. Or just add an else block and do you processing there whatever processing you want to do when a file doesn't exist.
the method File#exists() checks if a file is existing or not. If it does, it returns true and goes into your if block.
Since the file is not there, it just simply skips the if block and moves on. Since no attempt was made to access a non-existing file object, the exception is not thrown.
If you would like to throw an exception, you have to do so yourself like this,
if(file.exists()) {
//do file operation
} else {
throw new FileNotFoundException("Oops! No file...");
}
Related
I have a program that have a file in which I write the progress I've done, so if the program is closed I can just re-read what I already did.
So if the file doesn't exist (first time I launch the program), I create it, and after that I write in it.
This work while I work with Eclipse. But since I exported to an Executable JAR, I have an error if the file already exists ! That is, I can create the file and write in it the first time, but not if I close and re-launch the program.
Here's the code :
String donePath = "./done.txt";
try {
File doneFile = new File(donePath);
doneFile.createNewFile();
allreadyDone = new ArrayList<String>(Arrays.asList(new String(
Files.readAllBytes(Paths.get(donePath))).split("\n")));
doneFileWriter = new FileWriter(donePath, true);
} catch (IOException e1) {
e1.printStackTrace();
}
and I'm getting :
java.io.FileNotFoundException: .\done.txt (Accès refusé)
at java.base/java.io.FileOutputStream.open0(Native Method)
at java.base/java.io.FileOutputStream.open(FileOutputStream.java:292)
at java.base/java.io.FileOutputStream.<init>(FileOutputStream.java:235)
at java.base/java.io.FileOutputStream.<init>(FileOutputStream.java:156)
at java.base/java.io.FileWriter.<init>(FileWriter.java:82)
at =============.Main.main(Main.java:51)
I run your program (on Windows 10) with the extension of
printing the work already done
writing something (current time)
a finally-block that flushes and closes the doneFileWriter.
With the finally block everything is OK.
Without the finally block nothing is actually written.
I would expect "Accès refusé" if the log file is already open (by a different running instance).
Or if you run your code first with one user that owns the log file. And then use a different user for the next run, that has not write access.
You use the rather modern java.nio.Paths. So I suggest some type changes and debugging output:
Path donePath = Paths.get("./done.txt");
try {
File doneFile = donePath.toFile();
UserPrincipal owner = Files.getOwner(donePath);
String permissions = PosixFilePermissions.toString(
Files.getPosixFilePermissions(donePath));
System.out.println(
String.format("abs path:%s, owner:%s, can write:%b, permissions:%s",
doneFile.getAbsolutePath(), owner.getName(),
doneFile.canWrite(), permissions));
allreadyDone = new ArrayList<String>(Arrays.asList(new String(
Files.readAllBytes(donePath)).split("\n")));
What operating system do you use?
Which Java implementation (vendor/version)?
And what is your debug output?
You need to put the createNewFile() among an if-statement, so that if it is successfully created it goes ahead, and if it does not it simply outputs "File already exists".
try {
File myObj = new File(filename);
if (myObj.createNewFile()) {
System.out.println("File created: " + myObj.getName());
} else {
System.out.println("File already exists.");
}
} catch (IOException e) {
System.out.println("An error occurred.");
e.printStackTrace();
}
I want to convert a text file to a html file and then open it with a browser. I try to use file.renameTo() to rename the text file's extension to .html but the rename attempt always fails and file.renameTo() always returns false. Therefore, when I try to open the file in the below method, the file is opened in notepad.
file declaration:
private File file;
file declaration in constructor:
file = new File("D:/dc1000/Project/webPage.txt");
file.getParentFile().mkdirs();
method that doesn't work:
public void compileWebpage(){
File file2 = new File("D:/dc1000/Project/CompiledWebpage.html");
file2.getParentFile().mkdirs();
addFileTags("end"); //add ending tags like </body>
boolean success = true;
try{
success = file.renameTo(file2);
}catch (Exception e){
System.out.println(e);
}
if(!success){
System.out.println("webPage compilation failed.");
}
Desktop desktop = Desktop.getDesktop();
try{
desktop.browse(file.toURI());
}catch (IOException e){
e.printStackTrace();
}
}
No exceptions are thrown, "Webpage compilation failed" is printed to the console and then notepad opens the file. The file looks like this when opened in notepad:
<html>
<head>
</head>
<body>
<p>hi</p>
</body>
</html>
Why does File.renameTo() always fail? How can I open this text file in a browser as a html file?
Well, off hand it's rather hard to tell without truly knowing what the addFileTag() method is doing. The only reason I can think of is that the webPage.txt file is still open for either read or write operations.
Your code has accessed the file but never closed it again. You can't rename a file that is open. I would have to assume this is in fact done somewhere within the addFileTag() method.
Because your call to the File.renameTo() method was unsuccessful the "webPage.txt" text file was never renamed to "CompiledWebpage.html" so in essence the "CompiledWebpage.html" file simply does not exist within the system. This however is not the reason why the Windows NotePad application is opening your file instead of the expected default Web Browser:
To begin with the File object variable so conveniently named 'file' was declared and initialized to be related to the "D:/dc1000/Project/webPage.txt" text file and it always will be since it's Class global unless of course that relationship is changed somewhere within your code. To be blunt... it's not and I guess it's a good thing for now because IF your File Rename was successful you would have simply gotten an FileNotFound Exception because the text file related to the 'file' variable would no longer exist due to the simple fact that it was renamed.
What you really want to pass to the DeskTop.browse() method is the File object 'file2' variable which is related to the "D:/dc1000/Project/CompiledWebpage.html" text file. Mind you, you'll still get an FileNotFound Exception because the File.renameTo() method had failed. So you definitely want to make sure you have success here.
Whatever...Why did the Windows NotePad application open instead of the Web Browser?
Here's why:
The Operating System File Associations is what determines which application will open the file when using the DeskTop.browse() method. In the Windows Operating System, by default, a file with the file name extension of ".txt" is automatically opened and displayed within NotePad, a file with the file name extension of ".docx" is automatically opened and displayed in MS Office WORD, a file with the file name extension of ".html" is opened and displayed within the default Web Browser. I think you get the idea here.
Because the 'file' variable is still related to the file "D:/dc1000/Project/webPage.txt" and because the File.renameTo() method failed, Windows simply seen the .txt file extension and displayed the file (as stipulated within the 'file' variable) to NotePad.
So...How do I get all this to actually Work!?
Well, if I may be so bold, do this instead:
Place this somewhere in your code, a button action event or whatever:
String sourceFile = "D:/dc1000/Project/webPage.txt";
String destinationFile = "D:/dc1000/Project/CompiledWebpage.html";
boolean success = CompileToWebPage(sourceFile, destinationFile, "This is My Head Text");
if (success) {
System.out.println("Text File Successfully Compiled!");
}
else {
System.out.println("Text File Compilation FAILED!");
}
//Display our new file in the web Browser...
try {
File htmlFile = new File(destinationFile);
Desktop.getDesktop().browse(htmlFile.toURI());
} catch (IOException ex) {}
Here is a new CompileToWebPage() method:
private static boolean CompileToWebPage(final String sourcefilePath,
final String destinationFilePath, String... headText) {
// headText is OPTIONAL.
String headTxt = "";
if (headText.length != 0) { headTxt = headText[0]; }
//Read sourcefilePath file data into a String ArrayList...
BufferedReader input;
try {
input = new BufferedReader(new FileReader(sourcefilePath));
if (!input.ready()) { throw new IOException(); }
}
catch (FileNotFoundException ex) {
JOptionPane.showMessageDialog(null,"CompileToWebPage() Method Error!\n\nThe supplied "
+ "file path was not found!\n\n" + sourcefilePath, "File NotFound",
JOptionPane.ERROR_MESSAGE);
return false;
}
catch (IOException ex) {
JOptionPane.showMessageDialog(null,"CompileToWebPage() Method Error!\n\nThe supplied "
+ "file is not ready to be read!\n\n" + ex.getMessage(), "File Not Ready",
JOptionPane.ERROR_MESSAGE);
return false;
}
// Place required HTML Tags into String ArrayList
ArrayList<String> txt = new ArrayList<>();
txt.add("<html>");
txt.add("<head>");
txt.add(headTxt);
txt.add("</head>");
txt.add("<body>");
// Read each line of the source text File and add
// them to our String ArrayList...
try {
String str;
while((str = input.readLine()) != null){
txt.add("<p>" + str + "</p>");
}
input.close();
}
catch (IOException ex) {
JOptionPane.showMessageDialog(null,"CompileToWebPage() Method Error!\n\n"
+ "There was a problem reading the source Text from file!\n\n"
+ ex.getMessage(), "File Read Error", JOptionPane.ERROR_MESSAGE);
return false;
}
// Place our HTML finishing Tags into our String ArrayList...
txt.add("</body>");
txt.add("</html>");
// Write the String ArrayList to our supplied Destination
// File Path...
try {
FileWriter fw = new FileWriter(destinationFilePath);
Writer output = new BufferedWriter(fw);
for (int i = 0; i < txt.size(); i++) {
// Some Windows applications (such as NotePad require
// the \r tag for a new line to actually be accomplished
// within a text file.
output.write(txt.get(i) + "\r\n");
}
output.close();
return true;
}
catch (IOException ex) {
JOptionPane.showMessageDialog(null,"CompileToWebPage() Method Error!\n\n"
+ "There was a problem writing the Compiled Web Text to file!\n"
+ "Ensure that permissions are properly set.\n\n" + ex.getMessage(),
"File Write Error", JOptionPane.ERROR_MESSAGE);
return false;
}
}
Well, I hope this has helped you somewhat or at the very least been entertaining.
The following program has the purpose of creating a directory,
folderforallofmyjavafiles.mkdir();
and making a file to go inside that directory,
File myfile = new File("C:\\Users\\username\\Desktop\\folderforallofmyjavafiles\\test.txt");
There are two problems though. One is that it says the directory is being created at the desktop, but when checking for the directory, it is not there. Also, when creating the file, I get the exception
ERROR: java.io.FileNotFoundException: folderforallofmyjavafiles\test.txt (The system cannot find the path specified)
Please help me resolve these issues, here is the full code:
package mypackage;
import java.io.*;
public class Createwriteaddopenread {
public static void main(String[] args) {
File folderforallofmyjavafiles = new File("C:\\Users\\username\\Desktop");
try {
folderforallofmyjavafiles.mkdir(); //Creates a directory (mkdirs makes a directory)
if (folderforallofmyjavafiles.isDirectory() == true) {
System.out.println("Folder created at " + "'" + folderforallofmyjavafiles.getPath() + "'");
}
} catch (Exception e) {
System.out.println("Not working...?");
}
File myfile = new File("C:\\Users\\username\\Desktop\\folderforallofmyjavafiles\\test.txt");
//I even tried this:
//File myfile = new File("folderforallofmyjavafiles/test.txt");
//write your name and age through the file
try {
PrintWriter output = new PrintWriter(myfile); //Going to write to myfile
//This may throw an exception, so I always need a try catch when writing to a file
output.println("myname");
output.println("myage");
output.close();
System.out.println("File created");
} catch (IOException e) {
System.out.printf("ERROR: %s\n", e); //e is the IOException
}
}
}
Thank you so much for helping me out, I really appreciate it.
:)
You're creating the Desktop folder in the C:\Users\username folder. If you check the return value of mkdir, you'd notice it's false because the folder already exists.
How would the system know that you want a folder named folderforallofmyjavafiles unless you tell it so?
So, you didn't create the folder, and then you try to create a file in the (nonexistent) folder, and Java tells you the folder doesn't exist.
Agreed that it's a bit obscure, using a FileNotFoundException, but the text does say "The system cannot find the path specified".
Update
You're probably confused about the variable name, so let me say this. The following are all the same:
File folderforallofmyjavafiles = new File("C:\\Users\\username\\Desktop");
folderforallofmyjavafiles.mkdir();
File x = new File("C:\\Users\\username\\Desktop");
x.mkdir();
File folderToCreate = new File("C:\\Users\\username\\Desktop");
folderToCreate.mkdir();
File gobbledygook = new File("C:\\Users\\username\\Desktop");
gobbledygook.mkdir();
new File("C:\\Users\\username\\Desktop").mkdir();
I have the following code in my app:
final File f = new File(path);
try {
boolean folderCreated = f.mkdirs();
// if dir wasn't created this time, and doesn't exist
if (!folderCreated && !f.exists()) {
throw new IOException("Unable to create path");
}
} catch (SecurityException e) {
throw new IOException("Unable to create path");
}
When I run findbugs (in Android Studio), it reports Bad Practice Bad use of return value from method Method ignores exceptional return value of java.io.File.mkdirs()
Javadoc states that java.io.File.mkdirs() returns true if the directory was created, or false on failure OR if the directory already existed, hence the !f.exists() check.
I don't want to ignore findbugs messages - not even warnings, but I don't see how I can resolve this as the return value is clearly being checked.
Note, I added the try{...}catch (SecurityException){...} as a suggestion from this post: https://stackoverflow.com/a/23631948/1423896, but it doesn't make any difference.
Maybe the reason is that you invoke method of f instance even if folderCreated is false. Instead, you can invoke it before you invoke f.mkdirs().
boolean folderExisted = f.exists() || f.mkdirs();
if (!folderExisted) {
throw new IOException("Unable to create path");
}
refs: CheckReturnAnnotationDatabase.java
I don't know if it is relevant but it's a good idea to pass the caught exception to the created exception like this (on the last lines):
try {
boolean folderCreated = f.mkdirs();
// if dir wasn't created this time, and doesn't exist
if (!folderCreated && !f.exists()) {
throw new IOException("Unable to create path");
}
} catch (SecurityException e) {
throw new IOException("Unable to create path", e);
}
Use if condition to create a directory. That way you can eliminate findbug error. This works:
if (f.mkdir()) {
System.out.println("directory " + f+ " created");
}
I'll post my code first:
private void validateXml(String xml) throws BadSyntaxException{
File xmlFile = new File(xml);
try {
JaxbCommon.unmarshalFile(xml, Gen.class);
} catch (JAXBException jxe) {
logger.error("JAXBException loading " + xml);
String xmlPath = xmlFile.getAbsolutePath();
System.out.println(xmlFile.delete()); // prints false, meaning cannot be deleted
xmlFile.delete();
throw new BadSyntaxException(xmlPath + "/package.xml");
} catch (FileNotFoundException fne) {
logger.error("FileNotFoundException loading " + xml + " not found");
fne.printStackTrace();
}
}
You can see in my comment where I print that the file cannot be deleted. Files can't be deleted from a try/catch? So, if there is a file with bad xml syntax, I want to delete the file in the catch.
EDIT: I can delete the file when I use delete() from outside of this function. I am on Windows.
Make sure that this method invocation JaxbCommon.unmarshalFile(xml, Gen.class); closes any stream when the exception occurs. If the stream that was reading the file is left opened then you cannot delete it.
The problem is unrelated to the try/catch. Do you have permissions to delete the file?
If you are using Java 7 you can use the Files.delete(Path) which I think will actually throw an IOException with the reason why you can't delete the file.
There is no general restriction regarding the use of java.io.File.delete() on try/catch blocks.
The behavior of many java.io.File methods can depend on platform/enviroment that the application is running. It is because they can need to access file system resources.
For example, the following code returns false on Windows 7 and true on Ubuntu 12.04:
public static void main(String[] args) throws Exception {
File fileToBeDeleted = new File("test.txt");
// just creates a simple file on the file system
PrintWriter fout = new PrintWriter(fileToBeDeleted);
fout.println("Hello");
fout.close();
// opens the created file and does not close it
BufferedReader fin = new BufferedReader(new FileReader(fileToBeDeleted));
fin.read();
// try to delete the file
System.out.println(fileToBeDeleted.delete());
fin.close();
}
So, the real problem can depend on several factors. However, it is not related to the code residing on a try/catch block.
Maybe, the resource that you is trying to delete was opened and not closed or locked by another process.