canWrite () не возвращает значение, как ожидалось - PullRequest
0 голосов
/ 25 марта 2020

Я пытаюсь создать файл в указанном каталоге c, и до этого проверочный каталог имеет доступ для записи и, если да, создает файл. Хотя canWrite () возвращает значение true, но при создании выдает PermissionException.

public static void main(String[] args) {
        String downloadPath="\\\\pc.liferay.com\\lfs\\zone\\asia\\banglore";
        StringBuilder fileName=new StringBuilder();
        fileName.append(downloadPath);      
        fileName.append(File.separator);
        fileName.append("liferay-");
        fileName.append(new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()));
        fileName.append(".csv");
        //new File(fileName.toString());
         try {
              File destLocation = new File(downloadPath.toString());
              System.out.println("Abstract path: "+destLocation);            
              System.out.println("Write access? "+destLocation.canWrite());           
                if(destLocation.canWrite()) {
                  File destFile = new File(fileName.toString());
                  System.out.println("File path:"+destFile.getPath()); 
                  if (destFile.createNewFile()) {
                    System.out.println("File created: " + destFile.getPath());
                  } else {
                    System.out.println("File already exists.");
                  }
                }
            } catch (IOException e) {
              System.out.println("An error occurred.");
              e.printStackTrace();
            }
        System.out.println("Done");
    }

Выход:

java.io.IOException: Access is denied
    at java.io.WinNTFileSystem.createFileExclusively(Native Method)
    at java.io.File.createNewFile(File.java:1012)
    at com.local.file.downloader.PermissionExcpetionTH.main(PermissionExcpetionTH.java:29)

Ответы [ 2 ]

0 голосов
/ 25 марта 2020

Я считаю, что это Java ошибка / функция. Если вы выполняете поиск в базе данных Java Bugs , появляется ряд сообщений об ошибках, касающихся несовместимого поведения canWrite() и canRead() в Windows системах.

Основы c проблема в том, что когда Microsoft добавила поддержку файловых систем NTFS в библиотеку Win32, они не стали «учить» вызовы проверки доступа для понимания NTFS ACLS. Вместо этого старые вызовы по-прежнему сообщают о возможности чтения / записи, основываясь исключительно на разрешениях MSDOS. Были добавлены новые методы API для обработки проверки доступа к файловой системе NTFS, но для их использования необходимо изменить код приложения (в данном случае JVM).

Судя по сообщениям об ошибках Java, реакция Команда Sun Java, когда они обнаружили, что эта ошибка была нарушена Java в WindowsNT, должна была (правильно) сказать, что «это ошибка Windows». Но Microsoft не исправила это. И инженерам Sun было уже слишком поздно применять обходной путь к собственной реализации Java. Конечным результатом является то, что File.canRead() и File.canWrite() могут давать неверные результаты на Windows при некоторых обстоятельствах.

Связанные Java ошибки были помечены как WontFix.


Так в чем же решение?

Одним из решений является использование Files.isReadable() и Files.isWritable(). Насколько я понимаю, одной из (многих) вещей, которые они исправили в Files, было аномальное поведение методов File.canRead() и File.canWrite().

Однако я не советую проверять, файлы существуют, доступны для чтения или записи. Просто попытайтесь выполнить файловую операцию и разобраться с исключениями. Это имеет следующие преимущества:

  • Это позволяет избежать необходимости устранения несоответствий в управлении доступом. (Например, существуют несоответствия в Linux при использовании SE- Linux. Доступ к файлу может быть заблокирован SE- Linux, несмотря на то, что это разрешено битами разрешения доступа к файлу и списками ACL.)

  • Это позволяет избежать условий гонки, когда что-то еще (другой поток или другая программа) изменяет разрешения файловой системы в неподходящее время.

Также рекомендуется переключиться на используя более новые java.nio.*.* API, а не старый File класс. Более новые API дают лучшую диагностику.

0 голосов
/ 25 марта 2020
 * @param      file   the system-dependent filename.
 * @exception  SecurityException  if the calling thread does not
 *             have permission to access the specified file.
 * @exception  NullPointerException if the file argument is null.
 * @see        #checkPermission(java.security.Permission) checkPermission
 */
 public void checkWrite(String file) {
     checkPermission(new FilePermission(file,
         SecurityConstants.FILE_WRITE_ACTION));
 }

Таким образом, у вас нет разрешения на запись в файл. Вы можете изменить это разрешение двумя способами.

  1. Используя командную строку (Windows) или терминал (Linux или Ma c)
  2. Вы можете легко использовать file.setWriteable (true)
    * Если true, устанавливает разрешение на доступ, чтобы разрешить операции записи; если false запретить операции записи.

Более того, если вы не хотите изменять права доступа и если вы не хотите писать в этот путь в случае отсутствия разрешения. Вы можете поймать ошибку и создать новый файл, используя wi sh. Следующий фрагмент кода может вам немного помочь, если вы выберете этот способ.

    try {
        boolean canWrite = destLocation.canWrite();
    }catch (SecurityException ex){
        //Do what you need here.
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...