Souvannasouck Mark
Souvannasouck Mark

Reputation: 33

Get filepath as string in java

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.

Upvotes: 0

Views: 1539

Answers (2)

tevemadar
tevemadar

Reputation: 13225

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.

Upvotes: 1

Daniel Taub
Daniel Taub

Reputation: 5399

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

Upvotes: 1

Related Questions