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;
}
_
[〜#〜] warning [〜#〜]:この方法は、本番環境での使用には十分に堅牢ではありません。 directory.listFiles()
はnull
を返し、NullPointerException
を引き起こす場合があります。また、シンボリックリンクを考慮せず、おそらく他の障害モードがあります。 このメソッド を使用します。
Java-7 nio apiを使用すると、フォルダーサイズの計算をより迅速に行うことができます。
堅牢で例外をスローしない実行可能なサンプルを次に示します。入力できないディレクトリ、またはトラバースに問題があったディレクトリを記録します。シンボリックリンクは無視され、ディレクトリの同時変更は必要以上のトラブルを引き起こしません。
/**
* 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();
}
FileUtils#sizeOfDirectory(File)
from commons-io が必要です。
非ディレクトリが渡された場合、メソッドは例外をスローするため、ファイルがディレクトリであるかどうかを手動で確認する必要があることに注意してください。
[〜#〜] warning [〜#〜]:この方法(commons-io 2.4以降)にはバグがあり、IllegalArgumentException
ディレクトリが同時に変更された場合。
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;
}
Java 8 NIO APIを使用する場合、次のプログラムは、それが置かれているディレクトリのサイズをバイト単位で出力します。
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
オブジェクトに対して汎用的であるため、ファイルに対しても機能します。 注ファイルまたはディレクトリにアクセスできない場合、この場合、パスオブジェクトの返されたsizeは0
。
Java 8の場合、これは正しい方法の1つです。
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 から取得)は、返される長い文字列からユーザーが読み取り可能な文字列を取得する良い方法です。
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];
}
File.length()
( Javadoc )。
これはディレクトリでは機能しないか、動作が保証されていないことに注意してください。
ディレクトリの場合、何が必要ですか?その下のすべてのファイルの合計サイズであれば、File.list()
とFile.isDirectory()
を使用して子を再帰的にウォークし、サイズを合計できます。
File
オブジェクトにはlength
メソッドがあります:
f = new File("your/file/name");
f.length();
ソースコード:
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());
}
linuxでは、ディレクトリをソートする場合はdu -hs * |ソート-h
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;
}
windowsの場合、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;
}
これはテストされており、私の側で適切に機能しています。
ここでStackOverflowで提案されたさまざまなソリューションについて多くの調査と調査を行いました。私は最終的に独自のソリューションを作成することにしました。 APIがフォルダーサイズを取得できない場合にクラッシュしたくないので、私の目的はノースローメカニズムを持つことです。 この方法はマルチスレッドのシナリオには適していません。
まず、ファイルシステムツリーをたどっていく間に、有効なディレクトリを確認したいと思います。
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()のnullチェックに注意してください。 javadocによると、このメソッドはnullを返す可能性があります。
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;
}
}
ケーキのクリーム、リストファイルのサイズを取得するAPI(ルートの下にあるすべてのファイルとフォルダーである可能性があります)。
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;
}