web-dev-qa-db-ja.com

ディレクトリ内にファイルを作成する前に、ディレクトリ内の書き込みアクセスを確認する

私の小さなユーティリティアプリケーションは、GUIファイルセレクターを介してユーザーに出力ディレクトリを要求します。次に、いくつかの処理の後、この出力ディレクトリに多くのファイルを作成します。

アプリケーションに書き込みアクセス権があるかどうかを確認して、ユーザーに通知し、処理を続行しないようにする必要があります(時間がかかる場合があります)

私の最初の試みはcanWrite()メソッドJava.io.Fileでした。ただし、これはディレクトリエントリ自体を処理し、その内容を処理しないため、機能しません。名前を変更したり削除したりできるWindows XPフォルダーのインスタンスを少なくとも1つ見ましたが、(アクセス許可のために)ファイルを作成できません。これは実際には私のテストケースです。

私は最終的に次の解決策で解決しました

//User places the input file in a directory and selects it from the GUI
//All output files will be created in the directory that contains the input file
File fileBrowse = chooser.getSelectedFile(); //chooser is a JFileChooser
File sample = new File(fileBrowse.getParent(),"empty.txt"); 
try
{
     /*
      * Create and delete a dummy file in order to check file permissions. Maybe 
      * there is a safer way for this check.
      */
      sample.createNewFile();
      sample.delete();
}
catch(IOException e)
{
      //Error message shown to user. Operation is aborted
}

ただし、実際にファイルを作成して操作が成功したかどうかを確認するだけなので、これは私にはエレガントではありません。

これにはもっと良い方法があるはずですが、セキュリティマネージャなどでこれまでに見つけたすべてのソリューションはJavaアプレットであり、スタンドアロンアプリケーションではありません。何かが足りませんか?

実際にファイルを書き込む前に、ディレクトリ内のファイルアクセスをチェックするための推奨される方法は何ですか?

Java 5を使用しています。

26
kazanaki

ファイルのパーミッションをチェックし、ディレクトリが存在することを確認し、多くのチェックを行うか、すべてのチェックを行うライブラリを見つけることができますしかし(!)はチェックするための最良の方法ではありませんやってみますか?権限を確認してファイルシステムが変更された場合は、コードを変更する必要があります。しかし、ファイルを書き込もうとすると、ファイルを書き込めるかどうかが常にわかります。

あなたのソリューションは、最もエレガントなものである必要はありません。安価なハードコードされたパッチや醜いものではありません。これは通常のコードです。そして、それは常に機能します。しかし、コードのチェックインを確認したくない場合は、クラスに配置してコードを分離するだけです。このクラスの目的は、書き込みの可能性をチェックすることだけです。実際、エレガンスが好きかどうかに関係なく、ユーティリティクラスに入れる必要があります。

もう1つの解決策は、ハードドライブへの書き込みコード全体を試してみることです。また、書き込めない場合は、全体をスキップして、catch部分にメッセージを入れてユーザーにフィードバックします。

19

ファイルを書き込めない場合は、優れたユーザーエクスペリエンスを提供することに集中し、パスを事前に確認する必要はありません。処理には長い時間がかかると言っているので、処理が終了したときにそのパスに書き込むことができることを保証する方法はありません。権限は、チェックするときと書き込むときの間で非常によく変わる可能性があります。または、ディスクがいっぱいになる可能性があります。

0
Mark Bessey

Java 1.8を使用すると、次のものを使用できました。

Set<PosixFilePermission> permissions = Files.getPosixFilePermissions(Paths.get(destDir), LinkOption.NOFOLLOW_LINKS);
Assert.assertTrue("User did not have read permission.", permissions.contains(PosixFilePermission.OWNER_READ));
Assert.assertTrue("User did not have execute permission.", permissions.contains(PosixFilePermission.OWNER_EXECUTE));
Assert.assertTrue("User did not have write permission.", permissions.contains(PosixFilePermission.OWNER_WRITE));

Assert.assertFalse("Group did have read permission.", permissions.contains(PosixFilePermission.GROUP_READ));
Assert.assertFalse("Group did have execute permission.", permissions.contains(PosixFilePermission.GROUP_EXECUTE));
Assert.assertFalse("Group did have write permission.", permissions.contains(PosixFilePermission.GROUP_WRITE));

Assert.assertFalse("Others did have read permission.", permissions.contains(PosixFilePermission.OTHERS_READ));
Assert.assertFalse("Others did have execute permission.", permissions.contains(PosixFilePermission.OTHERS_EXECUTE));
Assert.assertFalse("Others did have write permission.", permissions.contains(PosixFilePermission.OTHERS_WRITE));

最終パスcanWriteを呼び出しても機能しませんか?

File sample = new File(fileBrowse.getParent(),"empty.txt"); 

if (sample.canWrite()) {
    doSomethingUseful(sample);
} else {
    notifyUser();
}
0
dfa

FilePermission を使用して詳細を取得できます。私はあなたが実装する必要がある1つの方法を見つけます SecurityManager コードは ここここ です

0
urmalp