Java에서 폴더 또는 파일의 크기를 검색하려면 어떻게해야합니까?
답변
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
. 또한 심볼릭 링크를 고려하지 않으며 다른 오류 모드가있을 수 있습니다. 이 방법 사용 .
답변
java-7 nio api를 사용하면 폴더 크기를 훨씬 빠르게 계산할 수 있습니다.
다음은 강력하고 예외를 발생시키지 않는 실행할 준비가 된 예제입니다. 입력 할 수 없거나 통과하는 데 문제가있는 디렉터리를 기록합니다. Symlink는 무시되며 디렉토리를 동시에 수정해도 필요 이상으로 문제가 발생하지 않습니다.
/**
* 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();
}
답변
commons-ioFileUtils#sizeOfDirectory(File)
에서 필요합니다 .
비 디렉토리가 전달되면 메소드에서 예외가 발생하므로 파일이 디렉토리인지 수동으로 확인해야합니다.
경고 :이 메소드 (commons-io 2.4 기준)에는 버그 IllegalArgumentException
가 있으며 디렉토리가 동시에 수정되면 발생할 수 있습니다 .
답변
Java 8에서
long size = Files.walk(path).mapToLong( p -> p.toFile().length() ).sum();
사용하는 것이 더 좋을 것입니다 Files::size
지도 단계에서 좋지만 확인 된 예외가 발생합니다.
업데이트 :
일부 파일 / 폴더에 액세스 할 수없는 경우 예외가 발생할 수 있음을 알고 있어야합니다. 이 질문 과 Guava를 사용하는 다른 솔루션을 참조하십시오 .
답변
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;
}
답변
를 들어 자바 팔 이 그것을 할 수있는 하나의 올바른 방법은 다음과 같습니다
Files.walk(new File("D:/temp").toPath())
.map(f -> f.toFile())
.filter(f -> f.isFile())
.mapToLong(f -> f.length()).sum()
모든 디렉터리를 필터링하는 것이 중요 합니다. 길이 방법이 디렉터리에 대해 0이 될 수있는 것은 아니기 때문입니다.
적어도이 코드는 Windows 탐색기 자체와 동일한 크기 정보를 제공합니다.
답변
일반적인 파일의 크기를 얻는 가장 좋은 방법은 다음과 같습니다 (디렉토리 및 비 디렉토리에서 작동).
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 에서 가져옴 )는 반환 된 long에서 사용자가 읽을 수있는 문자열을 얻는 좋은 방법입니다.
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];
}