java. nio. file. Nosuchfileexception: why NiO did not create a file

I'm using Java nio. File package and try to create a file using 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();
            }
    }           
}

Throw the 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 not create a file?

Please give me some advice

Thank you for your expectation

Solution

Update answer:

Now that you have shown the complete code, there are two main problems:

>You are trying to open the file, then make sure that the directory that caused it exists, and > you are using standardopenoption Append, but this does not create a file; It will be attached to an existing file

... and a number of best practice questions related to the actual number of lines of 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,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 that's how I 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,StandardOpenOption.APPEND)
    ) {
        // Write to out here,perhaps outputting `str`?
    }
}

... and handle exceptions in the call layer Note that, again, because we are using try with resources, close is automatic (when there are exceptions and when there are no exceptions)

Or, if you really want to record 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,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 actually failed, that is, calling newbufferedwriter (this one or this one) Newbufferedwriter adopts openoptions, and its standard set can start from standard openoption Ensure that standardopenoption. Is specified Create or standardopenoption CREATE_ NEW,

If you use one of these flags and the code in your problem is called before newbufferedwriter, it should work in addition to some other problems (permissions):

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
}
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>