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();
}
Related
I am trying to open a PDF file when a button is clicked. However I can't seem to get this working when I run my program as a JAR.
Initially, I was using this code:
if(Desktop.isDesktopSupported())
{
try
{
File myFile = new File("src/1. Handel - And the Glory of the Lord.pdf");
Desktop.getDesktop().open(myFile);
}
catch (Exception e)
{
JOptionPane.showMessageDialog(null,e);
}
}
That worked on Netbeans, however it didn't work on the JAR. After research, I found out its because I need to open it using a stream. Meaning I had to make a copy of it as a stream, and open that copy as a File. After looking around on stack overflow, I am now using this code:
try {
String inputPdf = "src/1. Handel - And the Glory of the Lord.pdf";
InputStream manualAsStream = getClass().getClassLoader().getResourceAsStream(inputPdf);
Path tempOutput = Files.createTempFile("1. Handel - And the Glory of the Lord", ".pdf");
tempOutput.toFile().deleteOnExit();
Files.copy(manualAsStream, tempOutput, StandardCopyOption.REPLACE_EXISTING);
File file = new File (tempOutput.toFile().getPath());
if (file.exists())
{
Desktop.getDesktop().open(file);
}
} catch (IOException ex) {
Logger.getLogger(HandelNotes.class.getName()).log(Level.SEVERE, null, ex);
}
This does not even work on Netbeans, whilst on another thread on Stack Exchange, the user said it worked for them.
I am getting a java.lang.NullPointerException error, on this line:
Files.copy(manualAsStream, tempOutput, StandardCopyOption.REPLACE_EXISTING);
Does anyone know what's going wrong, and could someone please tell me how to correct my code?
Thanks,
Rohan
bellow is the code of a house cleaning function i have written, the function is supposed to check for a files existance, if it is not there it then creates the file and adds some data to it.
However when i check that i have read and write permisions using the file.canRead() and file.canWrite() these both return false when checked however the program should have access to the file path where specified.
public void HouseCleaning()
{
//inform the user that the file is not available
System.out.println("According the the checks we have run, the current system you are on we do not have the required files set up");
System.out.println("...");
//create info.txt
try
{
File file = new File("C:\\GameCounter\\info.txt");
System.out.println(file.canRead());
System.out.println(file.canWrite());
if(file.canRead() && file.canWrite())
{
//then we can create the file
System.out.println("we can do this");
if(!file.exists())
{
//file does not exist
if(file.createNewFile())
{
//file has been created
System.out.println("File has been successfully created!");
PrintWriter writer = new PrintWriter("C:\\GameCounter\\info.txt", "UTF-8");
writer.println("Info File:");
writer.flush();
writer.close();
}
else
{
//file has not been created!
System.out.println("for some reason the file cannot be created!");
}
}
else
{
//file must already exist? so check for other required ones!
}
}
else
{
System.out.println("we require extre permissions!");
}
}
catch(Exception e)
{
//error has been thrown
System.out.println(e);
}
}
So my question is firstly is that theoretically if the code bellow is correct then it is permissions on the hard disk itself then? if the code is not correct please do correct me.
Many Thanks for any help regarding this.
I suggest you change your program and use the advantages Javas Exception Handling has to offer.
private final static String COUNTER = "C:\\GameCounter\\info.txt";
public static void main(String[] args) {
File file = new File(COUNTER);
if (!file.exists()) {
try {
PrintWriter writer = new PrintWriter(COUNTER, "UTF-8");
writer.println("Info File:");
writer.flush();
writer.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
/// ... more to come
}
This is a lot shorter and you have to take care of the exceptions anyway. If the file can not be written to (In my test I simply created it and assigned the readonly attribute) you will receive an according exception:
java.io.FileNotFoundException: C:\GameCounter\info.txt (Access denied)
at java.io.FileOutputStream.open0(Native Method)
at java.io.FileOutputStream.open(FileOutputStream.java:270)
at java.io.FileOutputStream.<init>(FileOutputStream.java:213)
at java.io.FileOutputStream.<init>(FileOutputStream.java:162)
at java.io.PrintWriter.<init>(PrintWriter.java:192)
at java.io.PrintWriter.<init>(PrintWriter.java:232)
at xyz.main(xyz.java:12)
In my example I only dump the exception to the screen. In a real life scenario you need to react on the exception and perhaps re-throw a exception you defined on your own.
The methods canRead and canWrite return false if the file does not exist.
Quote from the documentation (canRead):
Returns:
true if and only if the file specified by this abstract pathname exists and can be read by the application; false otherwise
and (canWrite):
Returns:
true if and only if the file system actually contains a file denoted by this abstract pathname and the application is allowed to write to the file; false otherwise.
The reason the file.canRead() file.canWrite() return false are most likely because you have not created the files.
Java Doc
public boolean canRead() Tests whether the application can
read the file denoted by this abstract pathname.
The method calls return true when you create the files first.
Remember, File is a representation of a system file, simply creating an instance of the File object will not create a file
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.
I have a java application that processes the contents of a file, and then I need to move it to another location.
This is how I read the file:
String filePath = new String("foo.bar");
String fileContents = new String("");
char[] myBuffer = new char[chunkSize];
int bytesRead = 0;
BufferedReader in;
try {
FileReader fr = new FileReader(filePath);
in = new BufferedReader(fr);
try {
while ((bytesRead = in.read(myBuffer,0,chunkSize)) != -1)
{
//System.out.println("Read " + bytesRead + " bytes. They were: " + new String(myBuffer));
fileContents+= new String(myBuffer).substring(0, bytesRead);
}
// close the stream as I don't need it anymore. (If I don't close it, then java would hold the file open thus preventing the subsequent move of the file)
in.close();
fr.close();
} catch (IOException e) {
e.printStackTrace();
return null;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
}
the file should be closed as I close both input stream and file reader.
Then after this I try to move the file to another directory using File.renameTo(newFileName); but this fails (under unix!, under windows it works fine)
Right after the move fails, I test whether I can create a file called newFileName and whether I can delete the original file. The new file gets to be created, while the original file fails to delete.
Interestingly enough I can delete the original file from command line while the application is running (right after the failure).
Any idea why is that or any alternative?
More details: I am working under unix and I'm bound to use java 1.6 for legacy reasons (thus I can not revert to Files.move() which is supported starting from java 1.7).
I found what was the problem in my java application.
Basically I extract a list of files from a directory using a custom FileFilter. This gives me an array File[] foundFiles.
What I do afterwards is reading each file in a while loop using the snippet of code in the question.
Right after the file is read for some reason I created a new File object using the i-th file from the array as parameter for the constructor
File file = new File(foundFiles[i].getName()); // File to be moved
and then I tried to rename this one.
Now for some reason this works under windows while it doesn't under unix (the file is somehow locked I think by the foundFiles[i] object).
In fact if I print the results of these lines
System.out.println("I can read foundFiles[i]: " +foundFiles[i].canRead());// DEBUG
System.out.println("I can write foundFiles[i]: " +foundFiles[i].canWrite());// DEBUG
System.out.println("I can read file : " +file.canRead());// DEBUG
System.out.println("I can write file : " +file.canWrite());// DEBUG
I get
I can read foundFiles[i]: True
I can write foundFiles[i]: True
I can read file: False
I can write file: False
It was simply enough to use renameTo() directly on the foundFiles[i] objects to make it work fine.
Hope this helps, but I don't know why the first version would work under windows and not under unix.
Let's analyze the above observation...
I can read foundFiles[i]: True
I can write foundFiles[i]: True
I can read file: False
I can write file: False
The result is normal, because the file object has been produced via new File(foundFiles[i].getName()) but the method getName provides only the name of the file, WITHOUT its filepath !
By creating the file via new File(foundFiles[i].getParent() + File.separator + foundFiles[i].getName()), the results would then be :
I can read foundFiles[i]: True
I can write foundFiles[i]: True
I can read file: True
I can write file: True
this is a really basic one, but it got me scratch my hear for 4 hours, now i'm giving up.
to give as much as possible information , i can say it's a java webapp project with zk 5.0.8 as frontend+spring+hibernate+maven under ubuntu 11.04 with permission to the basedir set to 777.
tried the file upload everything seems to be ok and where i have confidence that my code is correct it's just not working.
here is the code
private boolean saveUploadledFile(Media uploadedMedia, String basedir) {
String code = codeGenerator.generateContentCode(15);
String FINAL_DIR_PATH = basedir + "/"+"Racing" + "/" + code;
String FINAL_FILE_PATH = FINAL_DIR_PATH + "/" + uploadedMedia.getName();
alert(FINAL_DIR_PATH);
try {
File finaldir = new File(FINAL_DIR_PATH);
//apache commons
FileUtils.forceMkdir(finaldir);
alert("Size equals" + uploadedMedia.getByteData().length);
fout = new FileOutputStream(new File(FINAL_DIR_PATH+"/"+addContentWindow1$txtName.getText()+".jar"));
//apache commons
IOUtils.copy(uploadedMedia.getStreamData(), fout);
} catch (IOException e) {
throw new RuntimeException(e);
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
try {
IOUtils.closeQuietly(in);
IOUtils.closeQuietly(fout);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
return false;
}
new FileOutputStream always throws exceptions. so if i can't specify where i want to save how to save the files. any ideas? i intentionally output the size of the file to make sure there is a file. Can anyone shed some light? thanks for reading this
the actual exception is
Caused by: java.io.FileNotFoundException: /joseph/mbcs/Games/Racing/20314/somthing.jar (is a directory)
I may be wrong, but isn't this part of your code faulty?
if (!finaldir.exists()) {
if (!finaldir.canWrite())
finaldir.mkdirs(); // this creates no directory no error
else
alert("Cannot write to the directory" );
}
If the directory doesn't exist, you check if you can't write there and then create it, otherwise you output an error. I think that ! there is wrong.
Might be the reason for your problem but it just as well might not be.
Leave out:
if(finalfile.canWrite()) {
as you just created the file and are writing to it.
You will get a misnamed FileNotFoundException (I think renamed in Java 7) when the OutputStream constructor failed in writing.
Another tip, general work like copying may be done using apache-commons (IOUtils, FileUtils),
i.e.:
import org.apache.commons.fileupload.util.Streams;
Streams.copy(in, out, false);