8
votes

Comment vérifier si un fichier est lisible?

J'écris Java 6 Application et je dois vérifier si un fichier est lisible. Cependant, sur Windows Canread () retourne toujours true . Je vois donc que probablement, la seule solution pourrait être une solution indigène basée sur Winapi et écrit dans la JNA / JNI.

Mais, il y a un autre problème, car il est difficile de trouver une fonction simple à Winapi qui retournerait des informations sur l'accès à un fichier. J'ai trouvé getnamedsecurityinfo ou getsecurityInfo mais je ne suis pas un programmeur de Winapi avancé et ils sont trop compliqués pour moi en relation avec JNA / JNI. Des idées comment faire face à ce problème?


10 commentaires

Vous pouvez essayer de lire le fichier et voyez si vous obtenez une erreur.


Connexes: BOGDATABASE/VIEW_BUNT.DOOFBUG_ID=6203387 < / a>


@Peter Lawrey J'ai bien peur que ce soit une solution lente et non une meilleure pratique.


L'exactitude est plus importante que la vitesse. ;) Vous n'avez pas besoin de lire le fichier entier, il suffit de l'ouvrir et de le fermer.


En termes d'opérations de disque, les travaux nécessaires pour ouvrir et fermer un fichier sont de la même manière que les travaux nécessaires pour lire le descripteur de sécurité associé au fichier. Je serais surpris si la performance n'était pas similaire.


@ user389658 au contraire. Il essaie de prédire l'avenir comme celui-ci qui n'est pas une «meilleure pratique».


@EJP pour que la "meilleure pratique" pour vous utilise et une exception au lieu d'une structure de contrôle? Bon ! :-)


Si vous essayez de lire le fichier de toute façon, l'exception est une bonne route. Si vous essayez de Afficher la lisibilité du fichier, l'exception ne représente pas non plus correctement votre opération souhaitée. Le contexte est roi.


@aleroot Il n'y a pas de "au lieu d'une structure de contrôle" à ce sujet. Vous devez utiliser l'exception pour éviter toutes les questions nommées dans ma réponse. Il n'y a pas de choix et la dichotomie que vous avez présentée entre exceptions et structures de contrôle est entièrement fausse. Votre concept de «meilleure pratique» est profondément défectueux.


Vérification de la lisibilité et essayant ensuite de lire le fichier ajoute non seulement une surcharge extérieure, elle introduit également un bug de TOCTOU < / a>. En général, "Do X pour voir si je peux faire Y avant que je fasse y" est une mauvaise idée - x ne duplique pas exactement ce que y fait et les conditions peuvent changer entre x et y. si vous devez faire y, < B> Juste faire Y - et gérer les erreurs correctement . Parce que vous devez manipuler des erreurs de Y quand même.


5 Réponses :


8
votes

Essayez d'utiliser le code suivant

public boolean checkFileCanRead(File file){
    try {
        FileReader fileReader = new FileReader(file.getAbsolutePath());
        fileReader.read();
        fileReader.close();
    } catch (Exception e) {
        LOGGER.debug("Exception when checking if file could be read with message:"+e.getMessage(), e);
        return false;
    }
    return true;
}


2 commentaires

Je n'aime pas utiliser l'exception à la place de la structure de contrôle, mais pas mal la solution de contournement dans ce cas ...


L'existence et la vérification de la lisibilité sont juste des frais généraux redondants. De toute évidence, ils doivent arriver quand même lorsque vous essayez d'ouvrir le fichier: il ne sert à rien de faire tout cela deux fois.



5
votes

Vous pouvez utiliser FilePermision et AccessController plus difficile de cette manière: xxx

Si un accès demandé est autorisé, la checkpermission retourne tranquillement. Si refusé, une erreur AccessControlException est lancée.



4
votes

Il vous suffit de savoir si c'est lisible si vous allez le lire. Alors, essayez simplement de le lire, lorsque vous en avez besoin, et de le gérer si vous ne pouvez pas. La meilleure façon de tester la disponibilité de toute ressource est juste d'essayer de l'utiliser et de gérer les exceptions ou les erreurs au fur et à mesure de leur apparition. N'essayez pas de prédire l'avenir.


8 commentaires

Donc, le meilleur moyen n'est pas d'essayer de lire l'attribut de fichier, est d'essayer de lire et si vous obtenez une exception, le fichier n'est pas lisible ... il ne semble pas la meilleure solution


@aleroot Il ne semble pas la meilleure solution pourquoi? Comparé à quoi?


S'appuyer sur une exception au lieu d'utiliser le flux de contrôle n'est jamais la meilleure solution, pourrait être une solution de contournement viable mais loin de la meilleure solution ...


@aleroot C'est juste un dogme sans signification, d'autant plus que vous n'avez clairement aucune idée de la "meilleure solution" réellement: sinon vous ne demanderiez pas ici. Si attraper une exception fournit l'état que vous recherchez, c'est ce que vous utilisez. Ce que j'ai recommandé ici n'est pas une "solution de contournement", c'est la bonne technique. Tout le reste est répétitif et redondant, sinon incorrect, et définitivement une solution de contournement.


Je ne demande rien ici, et je ne suis pas disposé à compter sur des exceptions lorsqu'un énoncé de flux de contrôle normal peut être utilisé en place ... Si vous pensez que c'est bien compter sur Exception, c'est votre avis ...


@aleroot alors quelle est votre alternative "meilleure pratique"? Qu'est-ce que vous comparez-le à? Pourquoi continuez-vous à éviter cette question? Et quelle est votre alternative à accrocher dire eofexception lorsque vous appelez dites DataGuTretstream.readutf ()? `Ou ObjectInputStrream.readObject () ?


La meilleure solution pour moi est ce qui a été signalé par l'OP: si le fichier existe, lisez l'attribut du fichier, s'il dispose d'un attribut LIRE, allez lire le fichier et, dans le cas, quelque chose ne va pas attraper l'exception ...


@aleroot qui souffre de tous les problèmes que j'ai déjà signalés ci-dessus: En résumé, fenêtres de synchronisation et redondance, c'est-à-dire une inefficacité. Et vous n'avez pas répondu à mes autres questions. Il semble que ces discussions toujours gio de la même manière: un cas motivé soutenu par des faits est rejeté comme une simple "opinion", tandis qu'une application non supportée d'esprit d'un dogme reçu est présentée comme une "meilleure pratique". N'investissez pas trop fortement dans la programmation de la mode. Lorsque vous avez eu un peu plus longtemps, vous réaliserez qu'il y en aura une autre dans une minute, et souvent, ils sont souvent incompatibles.



9
votes

Java 7 a introduit la méthode Statique code> code>, il accepte un fichier chemin code> et retourne true si le fichier existe et est lisible, sinon false.

des docs p>

teste si un fichier est lisible. Cette méthode vérifie qu'un fichier existe et que cette machine virtuelle Java a des privilèges appropriés qui seraient Laissez-le ouvrir le fichier pour la lecture. En fonction de la mise en œuvre, cela la méthode peut nécessiter de lire les autorisations de fichier, les listes de contrôle d'accès ou d'autres attributs de fichier afin de vérifier l'accès effectif au fichier. Par conséquent, cette méthode peut ne pas être atomique par rapport à d'autres fichiers Opérations système. P>

Notez que le résultat de cette méthode est immédiatement obsolète, il y a aucune garantie qu'une tentative ultérieure d'ouvrir le fichier à lire sera réussir (ou même qu'il accédera au même fichier). Les soins doivent être pris Lorsque vous utilisez cette méthode dans les applications sensibles à la sécurité. P> blockQuote>

Exemple: P>

File file = new File("/path/to/file");
Files.isReadable(file.toPath()); // true if `/path/to/file` is readable


4 commentaires

+1 pour indiquer clairement la réponse est immédiatement inutile. Pour tous ceux qui veulent faire quelque chose comme ça, comme tous les autres "Je dois vérifier si je peux lire le fichier avant de le lire" réponses, Cette réponse est un bug de TOCTOU .


@Andrewmartin Je vais utiliser cela pour vous assurer que l'utilisateur est entré dans un chemin de sortie valide qui est différent et un objectif fondamentalement différent de vérifier si le fichier est lisible (écritable dans votre cas?). Vous validez un chemin de chemin.


@Andrewhenle tu as raison, je ne vois pas mon commentaire aussi utile, alors je l'ai supprimé.


@Andrewmartin Je pensais que c'était un commentaire très utile - vous utilisiez iSreadable () de manière innovante de valider un nom de chemin, où la partie "lisible" n'était pas pertinente.



1
votes

Il peut être parfaitement raisonnable de vérifier l'accessibilité d'une ressource (lisibilité d'un fichier dans ce cas) bien avant l'utilisation réelle de cette ressource.

Imaginez une application de serveur qui utilisera un sous-composant qui lira un fichier particulier dans certaines circonstances quelque temps ultérieurement. Il peut être utile de vérifier la lisibilité du fichier au démarrage du serveur et de l'avertissement s'il n'est pas lisible. Ensuite, quelqu'un peut résoudre la situation (faire le dossier lisible, tout) avant que les circonstances entraînent réellement le sous-composant d'essayer de lire ce fichier.

Bien sûr, cette vérification initiale n'est pas un substitut de la manipulation appropriée des exceptions dans le sous-composant (il est très possible que le fichier soit lisible au début mais est devenu illisible plus tard).

La question de la pré-vérification est parfaitement valide, je pense.

Quant à la méthode de vérification de la ressource, essayez de faire quelque chose aussi semblable que possible à l'utilisation réelle. Si plus tard, le fichier sera lu, essayez de le lire!

Comme pour les fichiers.Readable (...): il n'y a aucune garantie que le fournisseur de système de fichiers sous des fichiers.Sreadable (...) n'est pas une buggy. Il peut retourner vrai, puis jeter une exception si le fichier est réellement lu.

Bien sûr, si vous écrivez une application de gestionnaire de fichiers, utilisez des fichiers.Sreadable (...), mais je suppose que ce n'est pas le cas.


0 commentaires