6

次のことを行うJavaコードがあります。

  1. を使用して、拡張子が ZIP の空の一時ファイルを作成します。File.createTempFile()
  2. で削除しますFile.delete()(一時ファイル名を生成するだけでした)
  3. 同じファイル名com.google.commons.io.ByteStreams.copy()の newを使用して、「テンプレート」ZIP ファイルを同じパスにコピーします。OutputSupplier
  4. TrueZIP 7.4.3 を使用して ZIP アーカイブを変更 (ディレクトリを削除)

特定のシステムでは、手順 4 が一貫して失敗しますFsReadOnlyArchiveFileSystemException - "This is a read-only archive file system!"( http://java.net/projects/truezip/lists/users/archive/2011-05/message/9を参照) 。

TrueZIP コードをデバッグすると、次のことがわかりました。

  • 上記のいずれかの手順の間、特に手順 4 の前では、このファイルには開いているファイル ハンドルはありません。
  • NIO ではなく File.canWrite() で同じファイルを確認すると、(デバッガーを使用して) まったく同じタイミングで返され、書き込み可能であることが示されます。

デバッガ式のリストには次のように表示されます。

fn => "C:/myworkdir/temp/myfile4088293380313057223tmp.zip"
java.nio.file.Files.isWritable(java.nio.file.Paths.get(fn)) => false
new java.io.File(fn).canWrite() => true

JDK 1.7.04 の使用

何か案は?

4

3 に答える 3

5

最終結果はそれほど驚くべきことではありません。

java.nio.file.Files.isWritable(java.nio.file.Paths.get(fn)) => false
new java.io.File(fn).canWrite() => true

File.canWrite は ACL にまったく注意を払わず、MS-DOS 読み取り専用属性のみをチェックします。

Files.isWriteable は ACL に注意を払っていますが、何らかの理由で (壊れたプログラムを壊れたままにしておくために?)、File.canWrite を修正せずに残しました。問題なくファイルを開くことができる場合でも、状況によっては false を返す可能性があるように見えるため、これは幸運であることが判明しました。

本当に、私はこのような方法を要約します:

  • File.canWrite は、実際にファイルに書き込めない場合に true を返すことがあります。
  • Files.isWriteable は、実際にファイルに書き込める場合に false を返すことがあります。

現在、どちらの方法のポイントが何なのかわかりません。これらを使用するすべての人は最終的に、実際にファイルを開こうとする壊れていない同等のものを作成する必要があるため、なぜ彼らはファイルを開いて自分でチェックを行わなかったのか疑問に思います。

于 2013-02-20T05:08:04.773 に答える
5

両方の API を使用することは避け、代わりに、eg によってスローされる例外に依存しますnew FileOutputStream()。それらは少なくとも現実のものであり、真の関心事です。あなたが言及したAPIを使用することはまったく無意味であり、タイミングウィンドウと繰り返されるコードが導入されます. とにかくキャッチする必要がありIOExceptionます。なぜそのコードをすべて2回書くのですか?

于 2012-10-02T10:21:17.487 に答える