I am using java.nio.file package and tried to create file with the following code.
private static void printReport(String filename, String str)throws Exception{ ErrorCheck ec = new ErrorCheck(); String fileName = "/var/Emails_log/"+filename; Path filePath = Paths.get(fileName); File file = new File(fileName); final BufferedWriter out = Files.newBufferedWriter(filePath, StandardCharsets.UTF_8, StandardOpenOption.APPEND); try{ final Path tmp = filePath.getParent(); if (tmp != null){ // null will be returned if the path has no parent Files.createDirectories(tmp); } else { out.write(str); out.write('n'); } } catch(Exception e) { ec.errorMsg("ERROR: GSW.SendEmail.Exception =>",e); } finally { if (out != null) { out.flush(); out.close(); } } }
This throws following Exception:
java.nio.file.NoSuchFileException: /var/Emails_log/GSWvalidSentAddresses.txt at sun.nio.fs.UnixException.translateToIOException(UnixException.java:86) at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:102) at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:107) at sun.nio.fs.UnixFileSystemProvider.newByteChannel(UnixFileSystemProvider.java:214) at java.nio.file.spi.FileSystemProvider.newOutputStream(FileSystemProvider.java:430) at java.nio.file.Files.newOutputStream(Files.java:170) at java.nio.file.Files.newBufferedWriter(Files.java:2720) at SendEmail.printReport(SendEmail.java:114) SendEmail.send(SendEmail.java:87)
My question is why file is not created?
Please advise
Thanks in anticipation
Advertisement
Answer
Updated Answer:
Now that you’ve shown the full code, there are two major problems:
You’re trying to open the file before ensuring that the directories leading up to it exist, and
You’re using
StandardOpenOption.APPEND
, but that won’t create a file; it will append to an existing file.
…along with a large number of issues around best practices relative to the number of lines of actual code.
See comments:
private static void printReport(String filename, String str) throws Exception /* No, it doesn't. The only calls you had outside your catch-all `try` don't throw exceptions. */ { ErrorCheck ec = new ErrorCheck(); // Recommend not creating this until/unless you need it String fileName = "/var/Emails_log/"+filename; // VERY poor practice having two locals that only differ by the capitalization of one character in the middle (`filename` and `fileName`) Path filePath = Paths.get(fileName); // File file = new File(fileName); <== Removed, since you never use it for anything try { // Make sure the directories exist Files.createDirectories(filePath.getParent()); // No need for your null check, so I removed it; based on `fileName`, it will always have a parent // Open the file, creating it if it doesn't exist try ( final BufferedWriter out = Files.newBufferedWriter( filePath, StandardCharsets.UTF_8, StandardOpenOption.CREATE, StandardOpenOption.APPEND) ) { // Write to out here } } catch (Exception e) { // Log-and-continue isn't generally best practice; and if you're going to do it ec.errorMsg("ERROR: GSW.SendEmail.Exception =>",e); // <== Um...send mail failed? This isn't sending mail, it's putting something in a file. } // Using the try-with-resources, we don't have to worry about the flush and close calls }
But here’s how I would suggest you write it:
private static void printReport(String filename, String str) throws IOException { Path filePath = Paths.get("/var/Emails_log/" + filename); // Make sure the directories exist Files.createDirectories(filePath.getParent()); // Open the file, creating it if it doesn't exist try ( final BufferedWriter out = Files.newBufferedWriter( filePath, StandardCharsets.UTF_8, StandardOpenOption.CREATE, StandardOpenOption.APPEND) ) { // Write to out here, perhaps outputting `str`? } }
…and handle exceptions in the calling layer. Note that, again, because we’re using try-with-resources
, the close
is automatic (both when there’s an exception and when there isn’t).
Or if you really want to do log-and-continue:
private static void printReport(String filename, String str) { try { Path filePath = Paths.get("/var/Emails_log/" + filename); // Make sure the directories exist Files.createDirectories(filePath.getParent()); // Open the file, creating it if it doesn't exist try ( final BufferedWriter out = Files.newBufferedWriter( filePath, StandardCharsets.UTF_8, StandardOpenOption.CREATE, StandardOpenOption.APPEND) ) { // Write to out here, perhaps outputting `str`? } } catch (Exception e) { new ErrorCheck().errorMsg("ERROR: GSW.SendEmail.Exception =>", e); // <== But surely this message is suspect? I don't see anything sending email here. } }
Original Answer:
You haven’t shown the code that’s actually failing, which is a call to newBufferedWriter
(this one, or this one). newBufferedWriter
takes OpenOption
s, the standard set of which are available from StandardOpenOption
. Make sure you’ve specified StandardOpenOption.CREATE
or StandardOpenOption.CREATE_NEW
,
If you use one of those flags, and the code in your question isbefore the newBufferedWriter
call, barring some other problem (permissions) it should work:
String fileName = "/var/Emails_log/"+filename; Path filePath = Paths.get(fileName); final Path tmp = filePath.getParent(); if (tmp != null) { // <== Note: There's no point to this check, given // your filename above, the path WILL have a parent. // You could remove the `if` and just use // `Files.createDirectories(tmp)` unless the `fileName` // is actually coming from somewhere else and so could // be a root (roots don't have parents) Files.createDirectories(tmp); } else { out.write(str); // I assume this is for logging or display? out.write('n'); // Specifically, that it's *not* trying to write // to the file you're trying to create. } try (BufferedWriter writer = Files.newBufferedWriter(filePath, StandardOpenOption.CREATE)) { // ------------------------------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^ // Write to the file here }