Как вы создаете несуществующие папки / подкаталоги при копировании файла с помощью Java InputStream?

#java #nullpointerexception #fileinputstream #fileoutputstream

#java #исключение nullpointerexception #fileinputstream #fileoutputstream

Вопрос:

Я использовал InputStream для успешного копирования файла из одного местоположения в другое:

  public static void copy(File src, File dest) throws IOException { 
       InputStream is = null;
       OutputStream os = null; 

       try { 
           is = new FileInputStream("C:\test.txt");
           os = new FileOutputStream("C:\javatest\test.txt"); 

           byte[] buf = new byte[1024]; 
           int bytesRead; 
        while ((bytesRead = is.read(buf)) > 0) { 
            os.write(buf, 0, bytesRead); 
        } 
       } finally { 
           is.close(); 
           os.close(); 
       } 
   }
  

Проблема возникает, когда я добавляю несуществующую папку в path, например:

 os = new FileOutputStream("C:\javatest\javanewfolder\test.txt"); 
  

Это возвращает ошибку исключения NullPointerException. Как я могу создать все отсутствующие каталоги при выполнении процесса копирования через выходной поток?

Комментарии:

1. Кстати, потоки ввода-вывода можно закрывать автоматически. Вы должны использовать их в инструкции try-with, подобной той, которую я использовал в своем ответе на этот вопрос. Таким образом, вам не понадобится явный вызов .close(): docs.oracle.com/javase/tutorial/essential/exceptions /…

Ответ №1:

Во-первых, если возможно, я бы рекомендовал вам использовать классы java.nio.file (например, Path) вместо подхода, основанного на файле. Вы создадите объекты Path с использованием файловой системы. Вы можете использовать файловую систему по умолчанию, если здесь не требуется гибкость:

 final String folder = ...
final String filename = ...
final FileSystem fs = FileSystems.getDefault(); 
final Path myFile fs.getPath(folder, filename);
  

Тогда ваша проблема легко решается с помощью очень удобного API:

 final Path destinationFolder = dest.getParent();
Files.createDirectories(myPath.getParent());
try (final OutputStream os = Files.newOutputStream(myFile)) {
  ...
}
  

Метод Files.createDirectories() не завершится ошибкой, если каталог уже существует, но он может завершиться ошибкой по другим причинам. Например, если файл «foo /bar» существует, Files.createDirectories(«foo/bar /папка»), скорее всего, не завершится успешно. 😉

Пожалуйста, внимательно прочитайте javadoc!

Чтобы проверить, указывает ли путь на существующий каталог, просто user:

 Files.isDirectory(somePath);
  

При необходимости вы можете конвертировать между файлом и путем. Однако вы потеряете информацию о файловой системе:

 final Path path1 = file1.toPath();
final File file2 = path2.toFile();
  

Ответ №2:

Вы могли бы использовать Files.createDirectories:

 Files.createDirectories(Paths.get("C:\javatest\javanewfolder"));
  

Также вы могли бы использовать Files.copy для копирования файла)