फ़ोल्डर या फ़ाइल का आकार प्राप्त करें


105

मैं जावा में फ़ोल्डर या फ़ाइल का आकार कैसे प्राप्त कर सकता हूं?


समान लेकिन दक्षता पर ध्यान देने के साथ: stackoverflow.com/questions/116574/…
Ciro Santilli 郝海东 efficiency efficiency efficiency 病

यदि आप एंड्रॉइड पर होते हैं तो एक बार देखें StatFs। यह फ़ाइल सिस्टम आँकड़ों का उपयोग करता है और पुनरावर्ती विधियों की तुलना में लगभग 1000x तेज़ है, जो हमारी आवश्यकताओं के लिए अनुपयोगी थे। हमारा कार्यान्वयन यहाँ पाया जा सकता है: stackoverflow.com/a/58418639/293280
जोशुआ पिंटर

जवाबों:


191
java.io.File file = new java.io.File("myfile.txt");
file.length();

यह फ़ाइल की लंबाई बाइट्स में देता है या 0यदि फ़ाइल मौजूद नहीं है। किसी फ़ोल्डर का आकार प्राप्त करने का कोई अंतर्निहित तरीका नहीं है, आपको निर्देशिका ट्री को पुनरावर्ती रूप से चलना होगा ( listFiles()किसी फ़ाइल ऑब्जेक्ट की विधि का उपयोग करके जो निर्देशिका का प्रतिनिधित्व करता है) और अपने लिए निर्देशिका आकार को संचित करता है:

public static long folderSize(File directory) {
    long length = 0;
    for (File file : directory.listFiles()) {
        if (file.isFile())
            length += file.length();
        else
            length += folderSize(file);
    }
    return length;
}

चेतावनी : यह विधि उत्पादन के उपयोग के लिए पर्याप्त रूप से मजबूत नहीं है। directory.listFiles()वापसी nullऔर एक कारण हो सकता है NullPointerException। इसके अलावा, यह सहानुभूति पर विचार नहीं करता है और संभवतः अन्य विफलता मोड हैं। इस विधि का उपयोग करें


11
यदि आप इसे सी: रूट निर्देशिका में विंडोज मशीन पर चलाते हैं तो सावधान रहें; वहां एक सिस्टम फाइल है जो (java.io.File के अनुसार) न तो फाइल है और न ही डायरेक्टरी है। आप जाँच कर सकते हैं कि फ़ाइल वास्तव में निर्देशिका है, यह जाँचने के लिए और-क्लॉज़ बदलना चाहते हैं।
पॉल क्लैफाम

2
पैरामीटर की जांच करने के लिए सरल परिवर्तन यह देखने के लिए कि क्या यह विधि की शुरुआत में एक निर्देशिका नहीं है और लंबाई लौटाता है तो पुनरावृत्ति सरल है - बस उसी विधि में स्वयं को कॉल जोड़ें और फिर इसके बजाय फ़ाइल संदर्भ में पास करने का समर्थन करता है एक निर्देशिका के रूप में अच्छी तरह से।
केविन ब्रॉक

3
यदि आप जावा 7 या उच्चतर का उपयोग करते हैं, तो उत्तर stackoverflow.com/a/19877372/40064 का उपयोग करें यह बहुत तेज है।
Wim Deblauwe

1
यह सहानुभूति से भ्रमित हो जाएगा। NullPointerExceptionयदि निर्देशिका समवर्ती रूप से संशोधित है , तो भी, यह फेंक सकता है।
हांग्जो डबिन्सकी २।

43

जावा -7 एनआईओआई का उपयोग करके, फ़ोल्डर के आकार की गणना करके बहुत तेज किया जा सकता है।

यहाँ एक उदाहरण है कि मजबूत है और एक अपवाद फेंक नहीं होगा चलाने के लिए तैयार है। यह उन निर्देशिकाओं को लॉग करेगा, जो इसमें प्रवेश नहीं कर सकती हैं या उन्हें ट्रैवर्स करने में परेशानी हो सकती है। Symlinks को अनदेखा किया जाता है, और निर्देशिका के समवर्ती संशोधन से आवश्यकता से अधिक परेशानी नहीं होगी।

/**
 * Attempts to calculate the size of a file or directory.
 * 
 * <p>
 * Since the operation is non-atomic, the returned value may be inaccurate.
 * However, this method is quick and does its best.
 */
public static long size(Path path) {

    final AtomicLong size = new AtomicLong(0);

    try {
        Files.walkFileTree(path, new SimpleFileVisitor<Path>() {
            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {

                size.addAndGet(attrs.size());
                return FileVisitResult.CONTINUE;
            }

            @Override
            public FileVisitResult visitFileFailed(Path file, IOException exc) {

                System.out.println("skipped: " + file + " (" + exc + ")");
                // Skip folders that can't be traversed
                return FileVisitResult.CONTINUE;
            }

            @Override
            public FileVisitResult postVisitDirectory(Path dir, IOException exc) {

                if (exc != null)
                    System.out.println("had trouble traversing: " + dir + " (" + exc + ")");
                // Ignore errors traversing a folder
                return FileVisitResult.CONTINUE;
            }
        });
    } catch (IOException e) {
        throw new AssertionError("walkFileTree will not throw IOException if the FileVisitor does not");
    }

    return size.get();
}

क्या एंड्रॉइड डेवलपमेंट पर इसके लिए कोई समकक्ष है?
एंड्रॉइड डेवलपर

क्या AtomicLongसिर्फ उपयोग करने के बजाय एक कारण है long?
लुकास श्मेलिज़ेसेन

अनाम वर्ग से एक्सेस करने पर वैरिएबल को अंतिम रूप देना होता है
Aksel Willgert

1
मैंने JMH का उपयोग करते हुए एक बेंचमार्क किया और यह NIO एपीआई विधि कॉमन्स-आईओओ कोड की तुलना में लगभग 4 से 5 गुना तेज है (कुल 180229 फाइलों के लिए कई सबफ़ोल्डर के साथ एक फ़ोल्डर पर परीक्षण किया गया)। कॉमन्स IO को 15 सेकंड लगे, NIO को 5 सेकंड लगे।
विम डेलाउवे

3
यह दृष्टिकोण सबसे मजबूत है। यह सहानुभूति, समवर्ती संशोधन, सुरक्षा अपवादों, दोनों फ़ाइलों और निर्देशिकाओं के साथ काम करता है, आदि के साथ काम करता है। यह बहुत बुरा Filesहै यह सीधे समर्थन नहीं करता है!
हांग्जो डबलिनस्की

38

आपको कॉमन्स-आईओ की जरूरत FileUtils#sizeOfDirectory(File)है ।

ध्यान दें कि आपको मैन्युअल रूप से जांचने की आवश्यकता होगी कि क्या फ़ाइल एक निर्देशिका है क्योंकि विधि एक अपवाद को फेंकता है यदि एक गैर-निर्देशिका इसे पारित की जाती है।

चेतावनी : यह विधि (कॉमन्स-आईओ 2.4 के रूप में) में एक बग है और IllegalArgumentExceptionयदि निर्देशिका समवर्ती रूप से संशोधित है तो इसे फेंक सकते हैं ।


तो क्या होता है जब फ़ाइल एक निर्देशिका नहीं होती है? जब यह मौजूद नहीं है? आदि - कितने भयानक डॉक्स
Mr_and_Mrs_D

@Mr_and_Mrs_D - checkDirectory(directory);चेक के बाद लाइनों को कॉपी और पेस्ट करें। बस यह सुनिश्चित करें कि File.listFilesबच्चे हों। Refs : FileUtils.sizeOfDirectory () , File.listFiles ()
श्री पॉलीविर

3
बग IO-449 देखें । यह तरीका फेंक देगा IllegalArgumentExceptionयदि निर्देशिका पुनरावृत्ति करते समय निर्देशिका को संशोधित करती है।
अलेक्सांद्र डबिन्सकी २ '

आउच !!! यह बेकार है ... हाँ, यह फ़ाइलों को सूचीबद्ध करता है और फिर अगर कोड हटाते समय कोई हटा दिया जाता है, तो यह फेंकता है।
डीन हिलर

19

जावा 8 में:

long size = Files.walk(path).mapToLong( p -> p.toFile().length() ).sum();

यह Files::sizeनक्शे के चरण में उपयोग करने के लिए अच्छा होगा, लेकिन यह एक जाँच अपवाद को फेंकता है।

अद्यतन:
आपको यह भी पता होना चाहिए कि यह अपवाद को फेंक सकता है यदि कुछ फाइलें / फ़ोल्डर सुलभ नहीं हैं। इस सवाल और अमरूद के उपयोग से एक और समाधान देखें ।


1
मैं किसी चीज़ को देख रहा था, और मैं प्रश्न में कोड के साथ समाप्त हो गया: stackoverflow.com/questions/22867286/… , जैसा कि आप देख रहे हैं कि त्रुटि से निपटने का एक और पहलू भी समस्या पैदा कर रहा है।
अक्सेल विलगर्ट

@AkselWillgert धन्यवाद, यह दुर्भाग्यपूर्ण है और मैंने जवाब अपडेट कर दिया है। अब अमरूद का उपयोग करने जा stackoverflow.com/a/24757556/1180621
Andrejs

10
public static long getFolderSize(File dir) {
    long size = 0;
    for (File file : dir.listFiles()) {
        if (file.isFile()) {
            System.out.println(file.getName() + " " + file.length());
            size += file.length();
        }
        else
            size += getFolderSize(file);
    }
    return size;
}

1
@ अपने कोड को पुनरावृत्ति कॉल में एक साधारण फिक्स करने की आवश्यकता है, आपको आकार को मौजूदा आकार में जोड़ना चाहिए न कि इसे असाइन करना चाहिए। size += getFolderSize(file);
तेजा कंतमनेनी

@ तीजा: इशारा करने के लिए शुक्रिया, लेकिन बदलाव अगर इस बयान में भी होगा
विशाल

कभी-कभी एक बढ़ते फ़ोल्डर पर (एक और थ्रेड फ़ाइलों और फ़ोल्डरों को डाउनलोड कर रहा है और उसी समय मैं फ़ोल्डर आकार को प्रगति के रूप में प्रिंट कर रहा हूं) यह "के लिए लाइन में nullpointerexception देता है (फ़ाइल फ़ाइल: dir.listFiles ()) {"। कुछ फ़ाइलें एक जीवित फ़ोल्डर पर जल्दी से दिखाई और गायब हो जाती हैं। इसलिए मैंने लूप के लिए dir.listFiles () रिटर्न वैल्यू के लिए एक शून्य चेक जोड़ा ।
csonuryilmaz

File.listFiles () javadoc से: "यदि निर्देशिका खाली है, तो सरणी खाली हो जाएगी। यदि यह सार पथनाम एक निर्देशिका को निरूपित नहीं करता है, या यदि I / O त्रुटि होती है, तो रिक्त हो जाता है।" गतिशील रूप से बदलते फ़ोल्डर पर फ़ोल्डर का आकार प्राप्त करते समय उपरोक्त टिप्पणी उपयोगी होती है।
csonuryilmaz

7

के लिए जावा 8 यह यह करने के लिए एक सही तरीका है:

Files.walk(new File("D:/temp").toPath())
                .map(f -> f.toFile())
                .filter(f -> f.isFile())
                .mapToLong(f -> f.length()).sum()

सभी निर्देशिकाओं को फ़िल्टर करना महत्वपूर्ण है , क्योंकि लंबाई विधि निर्देशिकाओं के लिए 0 होने की गारंटी नहीं है।

कम से कम यह कोड उसी आकार की जानकारी देता है जैसे कि विंडोज एक्सप्लोरर खुद करता है।


4

यहां सामान्य फ़ाइल का आकार प्राप्त करने का सबसे अच्छा तरीका है (निर्देशिका और गैर-निर्देशिका के लिए काम करता है):

public static long getSize(File file) {
    long size;
    if (file.isDirectory()) {
        size = 0;
        for (File child : file.listFiles()) {
            size += getSize(child);
        }
    } else {
        size = file.length();
    }
    return size;
}

संपादित करें: ध्यान दें कि यह संभवतः एक समय लेने वाली कार्रवाई होने वाली है। इसे UI थ्रेड पर न चलाएं।

इसके अलावा, यहां ( https://stackoverflow.com/a/5599842/1696171 से लिया गया ) उपयोगकर्ता के पढ़ने योग्य स्ट्रिंग को लंबे समय से वापस लाने का एक अच्छा तरीका है:

public static String getReadableSize(long size) {
    if(size <= 0) return "0";
    final String[] units = new String[] { "B", "KB", "MB", "GB", "TB" };
    int digitGroups = (int) (Math.log10(size)/Math.log10(1024));
    return new DecimalFormat("#,##0.#").format(size/Math.pow(1024, digitGroups))
            + " " + units[digitGroups];
}

4

यदि आप जावा 8 एनआईओ एपीआई का उपयोग करना चाहते हैं , तो निम्न प्रोग्राम उस निर्देशिका के आकार, बाइट्स में प्रिंट करेगा, जिसमें यह स्थित है।

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

public class PathSize {

    public static void main(String[] args) {
        Path path = Paths.get(".");
        long size = calculateSize(path);
        System.out.println(size);
    }

    /**
     * Returns the size, in bytes, of the specified <tt>path</tt>. If the given
     * path is a regular file, trivially its size is returned. Else the path is
     * a directory and its contents are recursively explored, returning the
     * total sum of all files within the directory.
     * <p>
     * If an I/O exception occurs, it is suppressed within this method and
     * <tt>0</tt> is returned as the size of the specified <tt>path</tt>.
     * 
     * @param path path whose size is to be returned
     * @return size of the specified path
     */
    public static long calculateSize(Path path) {
        try {
            if (Files.isRegularFile(path)) {
                return Files.size(path);
            }

            return Files.list(path).mapToLong(PathSize::calculateSize).sum();
        } catch (IOException e) {
            return 0L;
        }
    }

}

calculateSizeविधि के लिए सार्वभौमिक है Pathवस्तुओं, तो यह भी फ़ाइलों के लिए काम करता है। ध्यान दें कि यदि कोई फ़ाइल या निर्देशिका अप्राप्य है, तो इस स्थिति में पथ ऑब्जेक्ट का लौटा हुआ आकार होगा 0


3

File.length()( जावदोक )।

ध्यान दें कि यह निर्देशिकाओं के लिए काम नहीं करता है, या काम करने की गारंटी नहीं है।

एक निर्देशिका के लिए, आप क्या चाहते हैं? यदि यह कुल आकार है की सभी फाइलों को इसे नीचे, आप पुनरावर्ती का उपयोग कर बच्चों चल सकता है File.list()और File.isDirectory()और उनके आकार योग।


3

Fileवस्तु एक है lengthविधि:

f = new File("your/file/name");
f.length();

3
  • Android और Java के लिए काम करता है
  • दोनों फ़ोल्डर और फ़ाइलों के लिए काम करता है
  • जहाँ आवश्यक हो, सभी जगह अशक्त सूचक के लिए जाँच
  • इग्नोरेस प्रतीकात्मक लिंक उर्फ शॉर्टकट
  • उत्पादन तैयार!

सोर्स कोड:

   public long fileSize(File root) {
        if(root == null){
            return 0;
        }
        if(root.isFile()){
            return root.length();
        }
        try {
            if(isSymlink(root)){
                return 0;
            }
        } catch (IOException e) {
            e.printStackTrace();
            return 0;
        }

        long length = 0;
        File[] files = root.listFiles();
        if(files == null){
            return 0;
        }
        for (File file : files) {
            length += fileSize(file);
        }

        return length;
    }

    private static boolean isSymlink(File file) throws IOException {
        File canon;
        if (file.getParent() == null) {
            canon = file;
        } else {
            File canonDir = file.getParentFile().getCanonicalFile();
            canon = new File(canonDir, file.getName());
        }
        return !canon.getCanonicalFile().equals(canon.getAbsoluteFile());
    }

1

विंडोज़ के लिए, java.io का उपयोग करके यह पुनरावर्ती कार्य उपयोगी है।

    public static long folderSize(File directory) {
    long length = 0;

    if (directory.isFile())
         length += directory.length();
    else{
        for (File file : directory.listFiles()) {
             if (file.isFile())
                 length += file.length();
             else
                 length += folderSize(file);
        }
    }

    return length;
}

यह मेरे अंत पर परीक्षण और ठीक से काम कर रहा है।


1

मैंने परीक्षण किया है du -c <folderpath>और nio.Files या पुनरावर्तन की तुलना में तेजी से 2x है

private static long getFolderSize(File folder){
  if (folder != null && folder.exists() && folder.canRead()){
    try {
      Process p = new ProcessBuilder("du","-c",folder.getAbsolutePath()).start();
      BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream()));
      String total = "";
      for (String line; null != (line = r.readLine());)
        total = line;
      r.close();
      p.waitFor();
      if (total.length() > 0 && total.endsWith("total"))
        return Long.parseLong(total.split("\\s+")[0]) * 1024;
    } catch (Exception ex) {
      ex.printStackTrace();
    }
  }
  return -1;
}

0
public long folderSize (String directory)
    {
        File curDir = new File(directory);
        long length = 0;
        for(File f : curDir.listFiles())
        {
            if(f.isDirectory())
            {               
                 for ( File child : f.listFiles()) 
                 {
                     length = length + child.length();
                 }

                System.out.println("Directory: " + f.getName() + " " + length + "kb");
            }
            else
            {
                length = f.length();
                System.out.println("File: " + f.getName() + " " + length + "kb");
            }
            length = 0;
        }
        return length;
    }

0

StackOverflow में प्रस्तावित कई शोधों और विभिन्न समाधानों को देखने के बाद। मैंने आखिरकार अपना समाधान लिखने का फैसला किया। मेरा उद्देश्य नो-थ्रो मैकेनिज्म है क्योंकि अगर एपीआई फ़ोल्डर का आकार लाने में असमर्थ है तो मैं क्रैश नहीं करना चाहता। यह विधि बहु-थ्रेडेड परिदृश्य के लिए उपयुक्त नहीं है।

सबसे पहले मैं फाइल सिस्टम ट्री को नीचे करते हुए वैध निर्देशिकाओं के लिए जाँच करना चाहता हूँ।

private static boolean isValidDir(File dir){
    if (dir != null && dir.exists() && dir.isDirectory()){
        return true;
    }else{
        return false;
    }
}

दूसरे मैं नहीं चाहता कि मेरे पुनरावर्ती कॉल को सीमलिंक (सॉफ्टलिंक) में जाएं और आकार को कुल एग्रीगेट में शामिल करें।

public static boolean isSymlink(File file) throws IOException {
    File canon;
    if (file.getParent() == null) {
        canon = file;
    } else {
        canon = new File(file.getParentFile().getCanonicalFile(),
                file.getName());
    }
    return !canon.getCanonicalFile().equals(canon.getAbsoluteFile());
}

अंत में मेरी पुनरावृत्ति आधारित कार्यान्वयन निर्दिष्ट निर्देशिका के आकार को लाने के लिए। Dir.listFiles () के लिए अशक्त चेक को देखें। Javadoc के अनुसार एक संभावना है कि यह विधि शून्य वापस आ सकती है।

public static long getDirSize(File dir){
    if (!isValidDir(dir))
        return 0L;
    File[] files = dir.listFiles();
    //Guard for null pointer exception on files
    if (files == null){
        return 0L;
    }else{
        long size = 0L;
        for(File file : files){
            if (file.isFile()){
                size += file.length();
            }else{
                try{
                    if (!isSymlink(file)) size += getDirSize(file);
                }catch (IOException ioe){
                    //digest exception
                }
            }
        }
        return size;
    }
}

केक पर कुछ क्रीम, सूची फ़ाइलों का आकार प्राप्त करने के लिए एपीआई (रूट के तहत सभी फाइलें और फ़ोल्डर हो सकता है)।

public static long getDirSize(List<File> files){
    long size = 0L;
    for(File file : files){
        if (file.isDirectory()){
            size += getDirSize(file);
        } else {
            size += file.length();
        }
    }
    return size;
}

0

linux में अगर आप डायरेक्टरी को क्रमबद्ध करना चाहते हैं तो du -hs * | सॉर्ट -ह


0

आप Apache Commons IOफ़ोल्डर का आकार आसानी से खोजने के लिए उपयोग कर सकते हैं।

यदि आप मावेन पर हैं, तो कृपया अपनी pom.xmlफ़ाइल में निम्न निर्भरता जोड़ें ।

<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.6</version>
</dependency>

यदि मावेन का प्रशंसक नहीं है, तो निम्न जार डाउनलोड करें और इसे वर्ग पथ में जोड़ें।

https://repo1.maven.org/maven2/commons-io/commons-io/2.6/commons-io-2.6.jar

public long getFolderSize() {

    File folder = new File("src/test/resources");
    long size = FileUtils.sizeOfDirectory(folder);

    return size; // in bytes
}

कॉमन्स IO के माध्यम से फ़ाइल का आकार प्राप्त करने के लिए,

File file = new File("ADD YOUR PATH TO FILE");

long fileSize = FileUtils.sizeOf(file);

System.out.println(fileSize); // bytes

यह भी प्राप्त करने योग्य है Google Guava

मावेन के लिए, निम्नलिखित जोड़ें:

<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>28.1-jre</version>
</dependency>

यदि मावेन का उपयोग नहीं कर रहा है, तो निम्न को वर्ग पथ में जोड़ें

https://repo1.maven.org/maven2/com/google/guava/guava/28.1-jre/guava-28.1-jre.jar

public long getFolderSizeViaGuava() {
        File folder = new File("src/test/resources");
        Iterable<File> files = Files.fileTreeTraverser()
                .breadthFirstTraversal(folder);
        long size = StreamSupport.stream(files.spliterator(), false)
                .filter(f -> f.isFile())
                .mapToLong(File::length).sum();

        return  size;
    }

फ़ाइल का आकार पाने के लिए,

 File file = new File("PATH TO YOUR FILE");
 long s  = file.length();
 System.out.println(s);

0
private static long getFolderSize(Path folder) {
        try {
            return Files.walk(folder)
                      .filter(p -> p.toFile().isFile())
                      .mapToLong(p -> p.toFile().length())
                      .sum();
        } catch (IOException e) {
            e.printStackTrace();
            return 0L;
        }

यद्यपि आपका कोड अच्छा लग रहा है, मुझे यकीन नहीं है कि यह अन्य उत्तरों में कुछ भी जोड़ता है। यदि ऐसा होता है, तो कृपया अपने उत्तर को समझाने के लिए संपादित करें।
अगस्त

यह कोड के कम लाइनों में समान काम करने का सिर्फ एक अद्यतन संस्करण है।
जसकरन सिंह
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.