Làm cách nào tôi có thể nhận được kích thước của tệp hoặc thư mục bằng cách sử dụng NIO mới trong java 7?Nhận kích thước tệp/thư mục bằng cách sử dụng Java 7 new IO
Trả lời
Sử dụng Files.size(Path)
để lấy kích thước của tệp.
Đối với kích thước của một thư mục (nghĩa là kích thước của tất cả các tệp chứa trong thư mục), bạn vẫn cần phải recurse theo cách thủ công, theo như tôi biết.
MutableLong size = new MutableLong();
Files.walkFileTree(directoryPath, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
size.add(attrs.size());
}
}
Điều này sẽ tính toán kích thước của tất cả các tệp trong một thư mục. Tuy nhiên, lưu ý rằng tất cả các tệp trong thư mục cần phải là tệp thông thường, vì API chỉ định phương thức kích thước của BasicFileAttributes:
"Kích thước tệp không phải là tệp thông thường được triển khai cụ thể và do đó không xác định."
Nếu bạn vấp phải tệp không được kiểm soát, bạn sẽ có hoặc không bao gồm kích thước tệp hoặc trả về một số kích thước không xác định. Bạn có thể kiểm tra xem tệp có thường xuyên với
BasicFileAttributes.isRegularFile()
Câu trả lời hay, và đối với bất cứ ai tự hỏi các lớp Mutable * cho nguyên thủy là một phần của apache.commons.lang – Nicholi
Đây là ví dụ sẵn sàng chạy cũng sẽ bỏ qua và không thể nhập thư mục. Nó sử dụng java.util.concurrent.atomic.AtomicLong
để tích lũy trạng thái.
public static void main(String[] args) throws IOException {
Path path = Paths.get("c:/");
long size = getSize(path);
System.out.println("size=" + size);
}
static long getSize(Path startPath) throws IOException {
final AtomicLong size = new AtomicLong(0);
Files.walkFileTree(startPath, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file,
BasicFileAttributes attrs) throws IOException {
size.addAndGet(attrs.size());
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult visitFileFailed(Path file, IOException exc)
throws IOException {
// Skip folders that can't be traversed
System.out.println("skipped: " + file + "e=" + exc);
return FileVisitResult.CONTINUE;
}
});
return size.get();
}
Tự hỏi tại sao 'AtomicLong' lại cần thiết? Tại sao không chỉ là một 'long'? Có điều gì đó song hành về [walkFileTree] không (http://docs.oracle.com/javase/7/docs/api/java/nio/file/Files.html#walkFileTree%28java.nio.file.Path,%20java. util.Set,% 20int,% 20java.nio.file.FileVisitor% 29)? – peterh
tbh, tôi chỉ viết lại câu trả lời khác mà không sử dụng 3pp (MutableLong). Nhưng tôi nghĩ rằng biến phải là "cuối cùng" để được truy cập từ lớp ẩn danh bên trong. AtomicLong cho phép. –
Phương thức 'postVisitDirectory' cũng có thể được ghi đè lên. Không cần đánh dấu tham chiếu 'size' là cuối cùng ở đây vì nó không bị thay đổi trong lớp ẩn danh bên trong. Chỉ có nội dung (giá trị) của nó được thay đổi. Một mảng dài (với một phần tử duy nhất) có thể được sử dụng thay cho AtomicLong. – Stephan
Có gì sai với cách cũ? Trừ khi có hỗ trợ cho kích thước thư mục đệ quy ngay bây giờ. Lanhung? – Thilo
Tôi đã nghe nó nhanh hơn rất nhiều. và tôi muốn thử điều đó. – clamp
Tôi phải tự hỏi làm thế nào nó có thể được nhanh hơn .. – Thilo