3

I am trying to copy files, folders, sub folders, zip files etc from a given location to another location. I used the code below.

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

public class CopyDirectoryExample
{
    public static void main(String[] args)
    {   
        File srcFolder = new File("C:\\Users\\Yohan\\Documents");
        File destFolder = new File("D:\\Test");

        //make sure source exists
        if(!srcFolder.exists()){

           System.out.println("Directory does not exist.");
           //just exit
           System.exit(0);

        }else{

           try{
            copyFolder(srcFolder,destFolder);
           }catch(IOException e){
            e.printStackTrace();
            //error, just exit
                System.exit(0);
           }
        }

        System.out.println("Done");
    }

    public static void copyFolder(File src, File dest)
        throws IOException{

        if(src.isDirectory()){

            //if directory not exists, create it
            if(!dest.exists()){
               dest.mkdir();
               System.out.println("Directory copied from " 
                              + src + "  to " + dest);
            }

            //list all the directory contents
            String files[] = src.list();

            for (String file : files) {
               //construct the src and dest file structure
               File srcFile = new File(src, file);
               File destFile = new File(dest, file);
               //recursive copy
               copyFolder(srcFile,destFile);
            }

        }else{
            //if file, then copy it
            //Use bytes stream to support all file types
            InputStream in = new FileInputStream(src);
                OutputStream out = new FileOutputStream(dest); 

                byte[] buffer = new byte[1024];

                int length;
                //copy the file content in bytes 
                while ((length = in.read(buffer)) > 0){
                   out.write(buffer, 0, length);
                }

                in.close();
                out.close();
                System.out.println("File copied from " + src + " to " + dest);
        }
    }
}

Now, I used the above code to take a copy of "My Documents". But unfortunatly, it ended up with NullPointerException after running for a while.

The reason for the error is it tried to take a copy of "My Music" folder, which is not even inside of the "My Documents" folder. I tested this code in 2 different machines running windows 7, got the same error in both.

A windows specific solution is fine for me, as I am targeting windows machines at the moment. What have I done wrong?

The error I am getting is below

Directory copied from C:\Users\Yohan\Documents\My Music  to D:\Test\My Music
Exception in thread "main" java.lang.NullPointerException
        at CopyDirectoryExample.copyFolder(CopyDirectoryExample.java:51)
        at CopyDirectoryExample.copyFolder(CopyDirectoryExample.java:56)
        at CopyDirectoryExample.main(CopyDirectoryExample.java:25)
PeakGen
  • 21,894
  • 86
  • 261
  • 463

3 Answers3

3

The reason this isn't working is because "My Music", "My Pictures" (or Images) and other directories are just symbolic links. See this post on how to detect symbolic links: Java 1.6 - determine symbolic links

Community
  • 1
  • 1
maraca
  • 8,468
  • 3
  • 23
  • 45
  • Not clear with what I have to really do. Mind providing a code help? Last time I messed up with the`canonical` path – PeakGen May 23 '15 at 01:34
  • Tested. It is not working, as the comment in that post has already mentioned. – PeakGen May 23 '15 at 06:11
  • @JustCause In `java.nio.file` you have everything out of the box. You can copy a directory and tell it to ignore or follow symlinks. Also you can check `Files.isSymbolicLink(file)`. It would reduce the code a lot. But I don't know if the bug exists there too (hopefully not). – maraca May 23 '15 at 10:15
  • @JustCause of course you could also catch NullPointerExceptions and assume it wa a symlink, but it's dirty. – maraca May 23 '15 at 10:22
2

Unfortunately, these folders (Images, Music, Videos) are NOT considered symbolic links in Java. Using Java 8,

Files.isSymbolicLink(srcFile.toPath())

While return false, and Files.readSymbolicLink(srcFile.toPath()) will fail with an Access Denied Exception.

So you can't process them automatically. Fix your code so that you handle properly the case where srcFile.isDirectory() returns true, but srcFile.listFiles() return null.

On my Windows 8 machine, three folders were in that case. I'm on a French machine, so I got a "Ma Musique" folder that gave null for listFiles. However,

new File("C:\\Users\\<user>\\Music").listFiles()

Does NOT return null. So I'm afraid you'll have to hardcode special code for the three folders (Music, Videos, Images) if you want to copy the data too.

JP Moresmau
  • 7,388
  • 17
  • 31
  • Thanks for the reply. Mind assisting me with some edits to my code? It seems so hard to do these file work in Java, unbelivevable! – PeakGen May 23 '15 at 14:22
  • Well they're special folders in windows, clicking on some folder via Windows Explorer gives access denied errors too, so I don't think it's Java's fault. In your code, you have String files[] = src.list(); files can be null, check for that. – JP Moresmau May 23 '15 at 14:47
-1

You are not handling the empty directories -- try making the following change, It will work after making the below change.

    //list all the directory contents
    String files[] = src.list();

    if (files!=null && files.length>0) {
       for (String file : files) {
          //construct the src and dest file structure
          File srcFile = new File(src, file);
          File destFile = new File(dest, file);
          //recursive copy
          copyFolder(srcFile,destFile);
       }
    }
Rajesh Balan
  • 593
  • 2
  • 7
  • 20
  • That's exactly the possibility for your Null Pointer exception. src.list() call returns a null and this happens if your directory does not contains any more sub-elements. I was able to simulate the error condition and after adding a null check the error was removed. Why was this given a negative vote ?? – Rajesh Balan May 26 '15 at 09:51