12

次のコード スニペットがあります。

public class ExampleClass {

public static void main(String[] args) throws FileNotFoundException {
    String filePath = args[0];
    File file = new File(filePath);

    if (!file.exists())
        throw new FileNotFoundException();

    if (file.canWrite())
        System.out.println(file.getAbsolutePath() + ": CAN WRITE!!!");
    else
        System.out.println(file.getAbsolutePath() + ": CANNOT WRITE!!!!!");

    if (file.canRead())
        System.out.println(file.getAbsolutePath() + ": CAN READ!!!");
    else
        System.out.println(file.getAbsolutePath() + ": CANNOT READ!!!!!");

    if (file.canExecute())
        System.out.println(file.getAbsolutePath() + ": CAN EXECUTE!!!");
    else
        System.out.println(file.getAbsolutePath() + ": CANNOT EXECUTE!!!!!");
}
}

Linux OS では動作しますが、windows7 では動作しないことが問題です。質問は次のとおりです。Java OS のファイルへの権限を個別にチェックする方法を知っている人はいますか?

4

3 に答える 3

8

これは、一貫性のない方法でファイル アクセスを「仲介」する何か (たとえば、ウイルス対策製品) が原因である可能性があります。

File.canXxxx()確かに、Windows のどのフレーバーでも Javaメソッドが一般的に壊れているとは信じがたいです。


更新- 私はそれを取り戻します。この Sun のバグ レポートを読んで、涙を流してください。簡単に言えば、これは Windows のバグであり、Sun はこれを回避しないことにしました。(しかし、新しい Java 7 API機能します...)

FWIW、そのようなファイルアクセス許可をチェックしようとするのは悪い習慣だと私は主張します。単純にファイルの使用を試み、例外が発生した場合は例外をキャッチすることをお勧めします。私の理由については、https://stackoverflow.com/a/6093037/139985を参照してください。(そして今、別の理由があります...)

于 2012-05-28T11:40:06.900 に答える
5

(Java 7 の) NIO API でいくつかのテストを行ったところ、完全に機能しているようです。

import java.io.FileNotFoundException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

public class PermissionCheck {

    public static void main(String[] args) throws FileNotFoundException {

        String filePath = args[0];
        Path p = Paths.get(filePath);

        if (Files.notExists(p))
            throw new FileNotFoundException();

        if (Files.isWritable(p))
            ...

        if (Files.isReadable(p))
            ...

        if (Files.isExecutable(p))
            ...
    }
}

JDK: 1.7.0_25、1.8.0_91

OS:Windows7、8(64ビット)

于 2016-05-06T10:49:30.850 に答える
2

まず第一に、Java はデフォルトおよび設計上、ローカル ファイルを信頼し、リモート ファイルを信頼しません。したがって、テストするときは、自宅のコンピューターで実行できることが、会社のサーバーのリモート ドライブでは実行できない可能性があることに注意してください。

次に、リモート ドライブのファイル アクセス許可を確認する場合、通常、Windows エクスプローラーで設定するだけでは十分ではありません ( Property...- Read only/ Hide/Archiveなど)。たとえば、私の組織には、ローカルとリモートの両方のファイル許可を制御するための他のメカニズムがあり、PC の管理者であってもすべてを保証することはできません。手動/プログラムでファイルのアクセス許可を変更できる場合でも、他のアプリケーション/グループ ポリシーなどで禁止されている場合は、変更に失敗する可能性があります。(たとえば、それが不可能であることを示唆する をsetReadable()返しますfalse)たとえば、リモート ディレクトリにexecuteあるファイルを開くことはできますが、txtbat同じディレクトリにあるファイルは実行可能ではありません。実際、私の場合、batファイルを作成したいときは、管理者に権限を増やすよう依頼する必要があります。bat多分延長禁止だと思います。Windowsのユーザーグループのユーザーとして、あなたのアクションとあなたが実行するJVMは、JVM自体よりも高いルールによって制限されているためです。私が間違っている場合は修正してください。

ただし、ファイルの許可を設定できない場合でも、Java 7 でそれらを正しく読み取ることができるようになりました。明らかに、バグ レポートの後、Java 関係者はそのほとんどを修正するために何かを行いました。を使用してjdk 1.7.0_19おり、テストするために次のことを行いました。

  1. Windows エクスプローラーで、リモート ファイルのプロパティを および に設定しRead OnlyますHidden

  2. 以下のコードを使用してJavaから読んでください(Stephen Cのリンクから、setXxxxx()メソッドが機能することを確認するために変更されています)。

    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    
    public class FilePermissionTester {
        public static void main( String[] args ) throws IOException {
            File file = new File("Y:\\some\\remote\\drive\\directoy\\xxxxx.txt");
            System.out.println( "exists:"  + file.exists() );
            System.out.println( "is file:"  + file.isFile() );
            System.out.println( "can read:" + file.canRead() );
            System.out.println( "can execute:" + file.canExecute() );
            System.out.println( "can write:" + file.canWrite() );
            System.out.println( "is hidden:" + file.isHidden() );
    
            System.out.println("change it to be unreadable, and it works? " + file.setReadable(false));
            System.out.println( "can read:" + file.canRead() );
            System.out.println("change it to be writable, and it works? " + file.setWritable(true));
            System.out.println( "can write:" + file.canWrite() );
            FileInputStream fileInputStream = new FileInputStream(file);
            fileInputStream.read();
            fileInputStream.close();
    
    
        }
    
    }
    

私が得た:

exists:true
is file:true
can read:true
can execute:true
can write:false
is hidden:true
change it to be unreadable, and it works? false
can read:true
change it to be writable, and it works? true
can write:true

これで、このファイルを読み取り、編集して保存できるようになりました。Save As..保存時に求められた許可を変更する前。

setReadable(false)ファイルは読み取り可能であり、 を返しますfalseが、ファイルはまだ読み取り可能であることに注意してください。JavaDoc はここで、ユーザーがアクセス権を変更する権限を持っていない場合、またはが既にであり、基盤となるシステムにこれに対する実装がない場合にsetReadable()返されると述べています。Java API へのデバッグは、実装がマークされており、それ以上の情報を表示できないため、多くの情報を提供しません。しかし、私は書き込み可能性を変更する許可を持っているので、それは私には理解できないものです.falsereadablefalsenative

java.util.Fileただし、 など、 でサポートされていない属性が他にもあることに注意してくださいsetHidden()。たぶん、 AccessControllerjava.securityのような他のパッケージをチェックできますか?

于 2016-08-12T12:00:06.833 に答える