简体   繁体   中英

Java - list of subdirectories and files within a path + size?

For example, if I have a directory on my computer, c:\\test that contains the following directories and files:

C:\\test\\foo\\a.dat (100kb)

C:\\test\\foo\\b.dat (200kb)

C:\\test\\foo\\another_dir\\jim.dat (500kb)

C:\\test\\bar\\ball.jpg (5kb)

C:\\test\\bar\\sam\\sam1.jpg (100kb)

C:\\test\\bar\\sam\\sam2.jpg (300kb)

C:\\test\\somefile.dat (700kb)

Running the command java ClassName c:\\test I want to have the output like that, sorting by size from largest to smallest ?:

DIR C:\\TEST\\FOO 800KB

FILE C:\\TEST\\SOMEFILE.DAT 700KB

DIR C:\\TEST\\BAR 405KB

Path startPath = Paths.get("C:\\test");
Files.walkFileTree(startPath, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
    System.out.println("Dir: " + dir.toString() + " "+getFolderSize(path()));
return FileVisitResult.CONTINUE;
}

@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
System.out.println("File: " + file.toString());    
return FileVisitResult.CONTINUE;
}

@Override
public FileVisitResult visitFileFailed(Path file, IOException e) {
return FileVisitResult.CONTINUE;
}
});

} catch (IOException e) {
e.printStackTrace();
}       

so far I got this part which can produce the output of all of the files and directories (which is not what I want) and without the size ? anybody with a help what to do next ?

THX!

I think you want something like this (output in bytes):

import java.io.File;

public class FileSearcher {

    public static void main(String[] args) {

        File f = new File("C:\\test");
        FileSearcher.search(f);
    }

    public static void search(File f) {
        if(null == f) {
            return;
        }
        System.out.print("| " + f.getAbsolutePath());
        if(f.isFile()) {
            System.out.print(" (" +  f.length() + ")");
        } else if(f.isDirectory()) {
            File[] children = f.listFiles();
            if(null != children) {
                for(File c : children) {
                    search(c);
                }
            }
        }
        System.out.println("");
    }
}

Oh and if you happen to care about the human-friendly file sizes, something like this will convert them for you (just change f.length() to friendlyFileSize(f.length()):

public static String friendlyFileSize(long size) {
    String unit = "bytes";
    if(size > 1024) {
        size = size / 1024; 
        unit = "kb";
    }

    if(size > 1024) {
        size = size / 1024; 
        unit = "mb";
    }

    if(size > 1024) {
        size = size / 1024; 
        unit = "gb";
    }
    return size + " " + unit;
}

This solution sorts the results by size from largest to smallest using the format <file-path> (<file-size>kb)

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

class du { 
    static class Pair {
        private String path;
        private Long size;
        public Pair(String path, Long size) { 
            this.path = path;
            this.size = size;
        }
        public String getPath() {
            return path;
        }
        public Long getSize() {
            return size;
        }
    }

    private static void diskUsage(File file, List<Pair> results) throws IOException {
        if (file.isDirectory()) {
            String[] subFolderPaths = file.list();
            for (String path : subFolderPaths) { 
                diskUsage(new File(path), results);
            }
        } else {
            results.add(new Pair(file.getAbsolutePath(), file.length()));
        }
    }

    public static void main(String... args) throws IOException {
        if (args.length != 1) {
            throw new IllegalArgumentException("Usage: du <folder-path>");
        }
        File folder = new File(args[0]);
        if (folder.isDirectory()) {
            List<Pair> results = new ArrayList<du.Pair>();
            diskUsage(folder, results);

            Collections.sort(results, new Comparator<Pair>() {
                @Override
                public int compare(Pair o1, Pair o2) {
                    return Long.compare(o2.getSize(), o1.getSize());
                }
            }); 

            for (Pair p : results) { 
                System.out.printf("%s (%dkb)\n", p.getPath(), p.getSize() / 1024);    
            }
        } else {
            System.out.printf("%s (%dkb)\n", folder.getAbsolutePath(), folder.length() / 1024);
        }
    }
}

You can iterate through each file in folder and call file.size() to get the size of file in bytes. Keep summing it up and you will have the entire folder size.

For sorting, you can keep the file-name and size in a HashMap and then use a custom comparator to sort out the entire dictionary using Collections.sort

   import  java.io.File;
   import  java.util.ArrayList;
   import  java.util.Collection;
   import  java.util.Iterator;
   import  java.util.List;
   import  java.util.TreeMap;
   import  org.apache.commons.io.FileUtils;
/**
   <P>java SizeOrderAllFilesInDirXmpl</P>
 **/
public class SizeOrderAllFilesInDirXmpl  {
   public static final void main(String[] igno_red)  {
      File fDir = (new File("R:\\code\\xbn\\"));
      Collection<File> cllf = FileUtils.listFiles(fDir, (new String[]{"java"}), true);

      //Add all files to a Map, keyed by size.
      //It's actually a map of lists-of-files, to
      //allow multiple files that happen to have the
      //same length.

      TreeMap<Long,List<File>> tmFilesBySize = new TreeMap<Long,List<File>>();
      Iterator<File> itrf = cllf.iterator();
      while(itrf.hasNext())  {
         File f = itrf.next();
         Long LLen = f.length();
         if(!tmFilesBySize.containsKey(LLen))  {
            ArrayList<File> alf = new ArrayList<File>();
            alf.add(f);
            tmFilesBySize.put(LLen, alf);
         }  else  {
            tmFilesBySize.get(LLen).add(f);
         }
      }

      //Iterate backwards by key through the map. For each
      //List<File>, iterate through the files, printing out
      //its size and path.

      ArrayList<Long> alSize = new ArrayList<Long>(tmFilesBySize.keySet());
      for(int i=alSize.size() - 1; i >= 0; i--)  {
         itrf = tmFilesBySize.get(alSize.get(i)).iterator();
         while(itrf.hasNext())  {
            File f = itrf.next();
            System.out.println(f.length() + ": " + f.getPath());
         }
      }
   }
}

Output:

44271: R:\code\xbn\number\vx\XIFLengthInRange.java
39318: R:\code\xbn\text\ConsecutiveDups.java
34747: R:\code\xbn\z\iw\list\ify\IWListify.java
32224: R:\code\xbn\array\NonPArrayFromPrimitiveUtil.java
32130: R:\code\xbn\list\ify\earray\NewListifyPableArray.java
31842: R:\code\xbn\array\WrapperArrayUtil.java
30142: R:\code\xbn\text\regex\RegexReplacer.java
30129: R:\code\xbn\list\ListUtil.java
29116: R:\code\xbn\xcfu\XCFUCmdLineParams.java
27940: R:\code\xbn\array\helper\NewPrimitiveArrayHelper.java
27417: R:\code\xbn\z\iw\java\util\IWCollection.java
26807: R:\code\xbn\text\ProcessEscapedECs.java
...and so on...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM