Search code examples
javanullpointerexceptionfileinputstreamfileoutputstream

How do you create non-existing folders/subdirectories when copying a file with Java InputStream?


I have used InputStream to succesfully copy a file from one location to another:

 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(); 
       } 
   }

The problem appears when I add a non-existing folder into the path, for example:

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

This returns a NullPointerException error. How can I create all of the missing directories when executing the copy process through Output Stream?


Solution

  • First, if possible I'd recommend you to use the java.nio.file classes (e.g. Path), instead of the File based approach. You will create Path objects by using a file system. You may use the default filesystem, if no flexibility is needed here:

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

    Then your problem is easily solved by a very convenient API:

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

    The Files.createDirectories() method will not fail if the directory already exists, but it may fail due to other reasons. For example if a file "foo/bar" exists, Files.createDirectories("foo/bar/folder") will most likely not succeed. ;)

    Please read the javadoc carefully!

    To check, if a path points to an existing directory, just user:

    Files.isDirectory(somePath);
    

    If needed, you can convert between File and Path. You will lose file system information, though:

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