-1

We have the following exercise: Given a list of directories and files followed by the destination copy all these directories (recursively) and files into the destination.

Here is the code I wrote:

public static void copyFile(File source, File dest) throws IOException {

    //use DataOutputStream for its method size() to measure amount of bytes copied
    try(FileInputStream is = new FileInputStream(source);
        FileOutputStream os = new FileOutputStream(dest);
        DataOutputStream dos = new DataOutputStream(os)) {
            byte[] buffer = new byte[1000];
            int res;
            while ((res = is.read(buffer)) !=-1) {
                dos.write(buffer, 0, res);
            }
            int size1 = dos.size();
            if(size1<1024){
                System.out.println("Total of " + size1 + "B" + " were copied");
            }
            if(size1>1024){
                System.out.println("Total of " + size1/1024 + "KB" + " were copied");
            }
            if(size1>1e-6){
                System.out.println("Total of " + size1/1024/1024 + "MB" + " were copied");
            }
        }
    }

    static void recursiveCopy(File file, File Destination){
        if(file.isFile()){
            try {
                System.out.println(">Started: " + file.getAbsolutePath());
                copyFile(file, Destination);
                System.out.println(">Finished FILE : " + file.getAbsolutePath());
                return;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        for(File sub:file.listFiles()){
            String indent2 = "";
            System.out.println( indent2+ ">Started: " + sub.getAbsolutePath());
            recursiveCopy(sub, Destination);
            indent2+= "  ";
        }
    }

    static void copyAll(File[] listOfFiles, File dest) throws IOException{
        for(File f:listOfFiles){
            recursiveCopy(f, dest);
            System.out.println("        >Finished FOLDER: " + f.getAbsolutePath());
        }
    }

    public static void main(String[] args) throws IOException {
        File[] listOfFiles = new File[] {new File("resources/docs/books"),
                                         new File("resources/docs/books/some citations.txt")};
        copyAll(listOfFiles, new File("dest"));
    }

It throws the NullPointerException with this message:

Exception in thread "main" java.lang.NullPointerException: Cannot read the array length because " <local2> " is null

The issue starts with the line for(File sub:file.listFiles())

Does anyone know how I can resolve this issue? All the files and directories exist so I don't know which element of array could possibly be null. Perhaps there is something else?

Abra
  • 19,142
  • 7
  • 29
  • 41
CoderLala
  • 5
  • 3
  • I wanted to write "local 2 is null" but the website will not let me do it – CoderLala Apr 24 '22 at 08:20
  • Cause second `File` in array is file and not directory. So it returns null on `file.listFiles()` – Alex Apr 24 '22 at 08:42
  • Would you say that the problem is in code or the content of resources folder? – CoderLala Apr 24 '22 at 09:57
  • @Mar17Ava have you stepped through the code using a debugger? – D-Dᴙum Apr 24 '22 at 10:06
  • To get an advance solution of your assignment, have a look at `java.nio.file.Files#walkFileTree` together with `java.nio.file.Files#copy`. – cyberbrain Apr 24 '22 at 10:18
  • 1
    file.listFiles() also "[r]eturns null if this abstract pathname does not denote a directory, or if an I/O error occurs.". An I/O error could be that you are not allowed to read the content of the directory. Or it is a network-shared directory that suddenly is not available any longer. –  Apr 24 '22 at 12:11

1 Answers1

1

In your method recursiveCopy, your file is either a file (you match that with .isFile()) or else it is a folder. You handle that with the for-loop. But it cannot be both, so when it is a file, you must not fetch the list of files inside (since there are none). Skip the for-loop in that case.

cyberbrain
  • 3,433
  • 1
  • 12
  • 22