2014-12-06 3 views
9

ПРИМЕЧАНИЕ. Пожалуйста, используйте точный код ниже; нет адаптации этого, в частности, не используйте File, так как эта ошибка связана с новым java.nio.file APIFiles.newInputStream() несущественное поведение, когда целевой путь является каталогом?

ОК, это на самом деле не «вопрос, который нуждается в ответе», а скорее призыв к свидетели ...

Сценарий:

  • есть каталог на ОС, какой бы она ни, что вы знаете, у вас есть права доступа - в Unix жаргоне, то, по крайней мере, доступ для чтения к нему (что означает, что вы можете перечислить записи в нем); в приведенном ниже коде предполагается, что путь, представленный System.getProperty("java.io.tmpdir"), соответствует счету;
  • имеют Oracle JDK или OpenJDK, 7+ установленный; так что у вас есть java.nio.file.

Теперь, что делает код ниже, он прост: он пытается установить open a new InputStream on this directory using Files.newInputStream(). Код (также here; добавлены комментарии мои):

import java.io.IOException; 
import java.io.InputStream; 
import java.nio.file.Files; 
import java.nio.file.Path; 
import java.nio.file.Paths; 

public final class Main 
{ 
    public static void main(final String... args) 
     throws IOException 
    { 
     final Path path = Paths.get(System.getProperty("java.io.tmpdir")); 
     try (
      final InputStream in = Files.newInputStream(path); // FAIL_OPEN 
     ) { 
      final byte[] buf = new byte[1024]; 
      int bytesRead; 
      while ((bytesRead = in.read(buf)) != -1) // FAIL_READ 
       System.out.printf("%d bytes read\n", bytesRead); 
     } 
    } 
} 

ОК, теперь, когда вы запустите этот код, это то, что происходит в следующих комбинациях JRE/OS:

  • Linux x86_64, Oracle JDK 1.8.0_25: IOException (is a directory) по адресу: FAIL_READ;
  • Linux x86_64, Oracle JDK 1.7.0_72: IOException (is a directory) по адресу FAIL_READ;
  • Mac OS X x86_64, Oracle JDK 1.8.0_25: IOException (is a directory) по адресу FAIL_READ;
  • Windows 7, Oracle JDK 1.8.0_25: AccessDeniedException по телефону FAIL_OPEN (!!).

Честно говоря, я не знаю, что делать с этим фрагментом кода. Как я сказал во вступлении, я ищу свидетелей здесь. Я обязательно открою для OpenJDK ошибку, это кажется довольно серьезным. Я также отправил список рассылки nio-dev об этой проблеме.

Хорошо, что касается вопроса, у меня будет один: как насчет IsDirectoryException в JDK (наследующий FileSystemException)? Я действительно определил его в one of my projects, чтобы учесть такую ​​проблему. Я не знаю, почему эта проблема не была рассмотрена в «Java парни» ...

+0

Кажется, что создается новый 'FileInputStream' (я только пробовал на Mac), чтобы понять, что это каталог сразу. –

+0

@SotiriosDelimanolis, похоже, это противоречит другим показаниям, которые я имею в Mac OS X; заботиться о том, чтобы поделиться точной трассировкой источника и стека (в частности, в строке, где говорится, что путь «является каталогом»)? – fge

+0

Просто 'final InputStream in = new FileInputStream (path.toFile())' производит 'Исключение в потоке 'main' java.io.FileNotFoundException:/var/folders/7z/ndxp48z14636frp1_rrr8x_8002l2v/T (является каталогом) '. Извините за код в комментариях. –

ответ

1

Мои наблюдения (извините, никаких других систем здесь атм, позже я мог бы добавить ARM):

  • JDK 1.8 .0_25, Linux x86_64: java.io.IOException: Is a directory по адресу // FAIL_READ.

Я согласен с тем, что такое поведение неожиданно, не должно быть возможности создать InputStream из каталога в первую очередь. Я предлагаю вам указать это как ошибку. Даже если Files.newInputStream не указывает его явно, поведение несовместимо с остальной частью API.

+0

«Я предлагаю вам записать это как ошибку» <- ну, я нахожусь в списке рассылки nio-dev OpenJDK и сообщил об этом; есть набор патчей, который готов к работе, но я не знаю, когда он это сделает. – fge