0

I tried over a thousand times and I can't figure out a way to return all file paths as a string, only as a list. For example, I want the string called filePath to return c:/users/exampleuser/file.txt but for all the files in a directory and it's subdirectory.

public void listFilesAndFilesSubDirectories(String directoryName){
     directoryName = "C:\\";
    File directory = new File(directoryName);
    //get all the files from a directory
    File[] fList = directory.listFiles();
    for (File files : fList){
        if (files.isFile()){
            System.out.println(files.getAbsolutePath());
        } else if (files.isDirectory()){
            listFilesAndFilesSubDirectories(files.getAbsolutePath());
        }
    }
}

This is an example code I tried but returns nothing. I need to return the filePaths as a string because I am trying to get the md5 using this method.

Thanks in advance.

3
  • 2
    you're recursively using the same directoryName Commented Jan 27, 2018 at 11:56
  • Consider switching to the newer Path from java.nio.files.*: docs.oracle.com/javase/7/docs/api/java/nio/file/Path.html Commented Jan 27, 2018 at 12:05
  • You're passing a diretoryName as argument, but you ignore its value and replace it with "C:\\" Commented Jan 27, 2018 at 12:08

2 Answers 2

1

Your code works fine after removing the first line. Then it prints a list of files, with full path.

If you also want to print MD5 sums, you can just pick the relevant parts from the code you refer. Which are not too many, as you have File objects in the loop already, so you need that single line with the md5 thing:

public static void listFilesAndFilesSubDirectories(String directoryName){
    File directory = new File(directoryName);
    //get all the files from a directory
    File[] fList = directory.listFiles();
    for (File file : fList){
        if (file.isFile()){
            System.out.print(file.getAbsolutePath());
            try(FileInputStream fis=new FileInputStream(file)){
                System.out.println(" - MD5: "+DigestUtils.md5Hex(IOUtils.toByteArray(fileInputStream)));
            }catch(Exception ex){
                System.out.println(" - Error: "+ex);
            }
        } else if (file.isDirectory()){
            listFilesAndFilesSubDirectories(file.getAbsolutePath());
        }
    }
}

As I do not really like the dependence on an external library, and especially the fact that it loads the entire file in the memory (the toByteArray call indicates it), here is a replacement for the first if, without Apache Commons and without loading the entire file into an array, but requiring a throws NoSuchAlgorithmException for the method header or an extra try-catch somewhere:

...
if (file.isFile()){
    System.out.print(file.getAbsolutePath());
    try(DigestInputStream dis=new DigestInputStream(new BufferedInputStream(new FileInputStream(file)), MessageDigest.getInstance("MD5"))){
        while(dis.read()>=0);
        System.out.println(" - MD5: "+javax.xml.bind.DatatypeConverter.printHexBinary(dis.getMessageDigest().digest()));
    }catch(Exception ex){
        System.out.println(" - Error: "+ex);
    }
} else if (file.isDirectory()){
...

Or a long one which throws no exception and does not depend on javax stuff either (which is not necessarily present after all):

...
if (file.isFile()){
    System.out.print(file.getAbsolutePath());
    MessageDigest md5=null;
    try{md5=MessageDigest.getInstance("MD5");}catch(NoSuchAlgorithmException nsae){};
    try(DigestInputStream dis=new DigestInputStream(new BufferedInputStream(new FileInputStream(file)), md5)){
        while(dis.read()>=0);
        System.out.print(" - MD5: ");
        for(Byte b: md5.digest())
            System.out.printf("%02X",b);
        System.out.println();
    }catch(IOException ioe){
        System.out.println(" - Error: "+ioe);
    }
} else if (file.isDirectory()){
...

Here is the actual code (RecDir.java) I used for testing, now modified for c:\ (which includes an additional check for dealing with directories you have no right to access):

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class RecDir {
    public static void main(String[] args) {
        listFilesAndFilesSubDirectories("c:\\");
    }
    public static void listFilesAndFilesSubDirectories(String directoryName){
        File directory = new File(directoryName);
        //get all the files from a directory
        File[] fList = directory.listFiles();
        if(fList!=null)
            for (File file : fList){
                if (file.isFile()){
                    System.out.print(file.getAbsolutePath());
                    MessageDigest md5=null;
                    try{md5=MessageDigest.getInstance("MD5");}catch(NoSuchAlgorithmException nsae){};
                    try(DigestInputStream dis=new DigestInputStream(new BufferedInputStream(new FileInputStream(file)), md5)){
                        while(dis.read()>=0);
                        System.out.print(" - MD5: ");
                        for(Byte b: md5.digest())
                            System.out.printf("%02x",b);
                        System.out.println();
                    }catch(IOException ioe){
                        System.out.println(" - Error: "+ioe);
                    }
                } else if (file.isDirectory()){
                    listFilesAndFilesSubDirectories(file.getAbsolutePath());
                }
            }
    }
}

I just ran it directly from NetBeans/Eclipse project folder (that is what the hardcoded "." results in), and then it lists various project files in the subdirectories, the .java file itself, etc.

Sign up to request clarification or add additional context in comments.

5 Comments

The code runs without a problem but I see no output in the console.
@SouvannasouckMark Which variant are you testing? Due to the lack of Apache Commons on my PC, I had to assume the referred article used it correctly. However the two snippets with DigestInputStream work for sure, they have been copied here directly from a working test code. Side note: the code legally does not output anything when it is started from an empty folder, or even in a folder hierarchy which does not contain files. Hidden files may not be listed either.
@SouvannasouckMark: added complete code for the last variant, just to make things sure, see under the horizontal separator.
Thanks now It does the MD5 for every file,but only in the project folder.How do i make it to do the MD5 for every file in C:\\?
@SouvannasouckMark see the current version. Just remember that there is a lot of file on a typical c: drive.
1

You can use Files to implement it in the easy way :

public List<String> listFilesAndFilesSubDirectories(String directoryName) throws IOException {
      return Files.walk(Paths.get(directoryName))
        .map(Path::toFile)
        .map(File::getAbsolutePath)
        .collect(Collectors.toList());
}

1 Comment

I need it to be as a string not as a list.But thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.