java.nio.file.nosuchfileException:NIOがファイルを作成しない理由[クローズ] -- java フィールド と file-io フィールド と nio フィールド 関連 問題

java.nio.file.NoSuchFileException: why nio not creating file [closed]












4
vote

問題

日本語

この質問を改善したいですか? ON-TOPIC スタックオーバーフローでは、質問を更新します。

閉じられた 5年前

この質問を改善します

java.nio.fileパッケージを使用して、次のコードでファイルを作成しようとしました。

<事前> <コード> 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(' '); } } catch(Exception e) { ec.errorMsg("ERROR: GSW.SendEmail.Exception =>",e); } finally { if (out != null) { out.flush(); out.close(); } } }

これは例外を下回る:

<事前> <コード> 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)

私の質問は、ファイルが作成されていない理由ですか?

を助長してください

予想がありがとう

英語

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(' ');             }                        } 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

</div
        
         
         

回答リスト

9
 
vote
vote
ベストアンサー
 

更新された回答

あなたが全額を表示した今、2つの大きな問題があります:

  1. ファイルを開く前にファイルを開こうとし、存在するディレクトリと

  2. StandardOpenOption.APPEND を使用していますが、それは create ファイルを作成しません。 既存のファイルに追加されます。

  3. ...実際のコードの行数に対するベストプラクティスについての多数の問題とともに。

    コメントを見る:

    <事前> <コード> 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 }

    しかし、ここにあなたがそれを書くことを提案する方法です:

    <事前> <コード> 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`? } }

    ...および呼び出し層の例外を処理します。 try-with-resources を使用しているので、<コード> close は自動(例外がある場合、およびいない場合は両方)です。

    または本当にログアンドンをやりたい場合:

    <事前> <コード> 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. } }

    元の答え

    実際に失敗したコードを表示していません。 newBufferedWriter (この 1、またはこの 1)。 newBufferedWriter OpenOption S、標準セットは <コード> StandardOpenOption 。必ず指定したことを確認してください または <コード> 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 } 1

    これらのフラグの1つを使用し、質問のコードはの前の> 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 } 2 呼び出しの前に、その他の問題(権限)をバリリングする必要があります。 <コード> 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 } 3

 

Updated Answer:

Now that you've shown the full code, there are two major problems:

  1. You're trying to open the file before ensuring that the directories leading up to it exist, and

  2. 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 OpenOptions, 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(' ');    // 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 } 
</div
 
 
         
         

関連する質問

9  どのファイルのSytemがJava UserDefinedFileAttributeviewをサポートしていますか?  ( What file sytems support java userdefinedfileattributeview ) 
ファイルシステム(各ファイルと約50バイト)のファイルをファイルに格納する必要があります。データを保存するための他のストレージがありません。これに追加のファイルを作成できません。これらは私の要求です私はそれを変えることができない。 これはUserDefined...

0  クローズアップでSocketchannelに書き込む  ( Writing to socketchannel in close wait ) 
SocketChannel.write は、基礎となる接続が CLOSE-WAIT 状態にある場合に、例外をスローしないことに気づいた。それは行動が期待されていますか?もしそうなら、接続が<コード> ESTABLISHED ?でないことをどのように理解する...

7  ファイルへのJava Nioサーブレット  ( Java nio servlet to file ) 
は、JavaサーブレットからHttpServletRequestを取得し、すべてのNIOを使用してファイルに書き込むための方法がありますか?試す価値がありますか?通常のjava.ioストリームからの迅速な読みやjava.nioチャネルへの書き込み、または両方と...

3  NIO:メッセージを送信してから直ちに切断してください  ( Nio send message and then disconnect immediately ) 
状況によっては、非ブロッキングI / O( SocketChannel.write(ByteBuffer) )を使用してサーバーからクライアントにエラーメッセージを送信し、クライアントを切断したいと思います。メッセージの全内容を書いてからすぐに切断すると仮定す...

0  バイトが読み込まれる前に接続が切断された場合、TCPソケット接続のバイト数は失われますか?  ( Are bytes on a tcp socket connection lost if the connection is severed before th ) 
Selector が sockets を受け入れ、それらを他のスレッドのキューにプッシュして、他のスレッドのキューにプッシュして、スレッドは2分のためのソケットを取ります。クライアントはデータをプッシュしますが、タイムアウトして切断します。 thread...

0  NIO非同期通話でHTTP POSTパラメータを設定する方法  ( How to set http post parameters on a nio asynchronous call ) 
これへの答えはかなり簡単でなければなりませんが、まだ見つけることができません。 GETパラメータを利用するJava非同期呼び出しの動作例を持っているとしましょう。 <事前> <コード> final CloseableHttpAsyncClient client...

0  Java NIO.2グロブ問題  ( Java nio 2 glob problem ) 
私は持っています: <事前> <コード> Path path = Paths.get("Foo.class"); Path path2 = Paths.get("Foo.java"); FileSystem fs = FileSystems.getDefau...

280  Javaでファイルを再帰的にリストします  ( Recursively list files in java ) 
Javaのディレクトリの下のすべてのファイルを再帰的にリストする方法フレームワークはすべてのユーティリティを提供しますか? 私は多くのハッキーな実装を見ました。しかし、フレームワークまたは nio ...

3  SocketChannelをJavaで送信する方法を送信する方法  ( How to send and then read n using socketchannel in java ) 
クライアント/サーバアプリケーションの SocketChannel Javaクラスを使用しています。データを送受信することができます。ただし、データに ' ' が含まれている場合は、正しいデータを読みません。たとえばです <事前> <コード> sending...

-3  Java NIOソケットチャネルを使用した大規模データの書き込みに関する問題  ( Problem with writing large data using java nio socket channel ) 
Java NIOを使用して小さなデータを送信することができます。 しかし、私が非常に大きなデータを送りたいのなら、私のソケットチャネルはうまくいかなかった。 <事前> <コード> message = "very large data"+" "; ByteBu...




© 2022 cndgn.com All Rights Reserved. Q&Aハウス 全著作権所有