CodeGym/Blog Java/Ngẫu nhiên/Tệp Java, Đường dẫn

Tệp Java, Đường dẫn

Xuất bản trong nhóm
CHÀO! Hôm nay chúng ta sẽ nói về cách làm việc với tệp và thư mục. Bạn đã biết cách quản lý nội dung tệp: chúng tôi đã dành rất nhiều bài học cho vấn đề này :) Tôi nghĩ bạn sẽ dễ nhớ một vài lớp được sử dụng cho các mục đích này. Trong bài học hôm nay, chúng ta sẽ nói cụ thể về quản lý tệp: tạo, đổi tên, v.v. Trước Java 7, tất cả các thao tác như vậy được thực hiện bằng lớp Tệp . Bạn có thể đọc về nó ở đây . Nhưng trong Java 7, những người tạo ra ngôn ngữ này đã quyết định thay đổi cách chúng ta làm việc với các tệp và thư mục. Điều này xảy ra vì lớp Tệp có một số nhược điểm. Ví dụ: nó không có phương thức copy() cho phép bạn sao chép tệp từ vị trí này sang vị trí khác (một khả năng dường như rất cần thiết). Ngoài ra, cácLớp tệp có khá nhiều phương thức trả về giá trị boolean . Khi có lỗi, một phương thức như vậy trả về false. Nó không đưa ra một ngoại lệ, khiến cho việc xác định lỗi và chẩn đoán nguyên nhân của chúng trở nên rất khó khăn. Ở vị trí của lớp Tệp đơn lẻ , 3 lớp đã xuất hiện: Đường dẫn , Đường dẫnTệp . Chà, chính xác mà nói, Đường dẫn là một giao diện, không phải là một lớp. Hãy tìm hiểu xem chúng khác nhau như thế nào và tại sao chúng ta cần từng loại. Hãy bắt đầu với cách đơn giản nhất: Đường dẫn .

đường dẫn

Đường dẫn là một lớp rất đơn giản với một phương thức tĩnh duy nhất: get() . Nó được tạo chỉ để lấy đối tượng Đường dẫn từ chuỗi hoặc URI đã truyền. Nó không có chức năng nào khác. Đây là một ví dụ về nó tại nơi làm việc:
import java.nio.file.Path;
import java.nio.file.Paths;

public class Main {

   public static void main(String[] args) {

       Path testFilePath = Paths.get("C:\\Users\\Username\\Desktop\\testFile.txt");
   }
}
Không phải là lớp phức tạp nhất, phải không? :) Chà, chúng ta cũng có loại Đường dẫn này . Hãy tìm hiểu Path là gì và tại sao nó lại cần thiết :)

Con đường

Path , nói chung, là một dạng tương tự được thiết kế lại của lớp File . Nó dễ làm việc hơn nhiều so với File . Đầu tiên , nhiều phương thức tiện ích (tĩnh) đã được loại bỏ và chuyển sang lớp Tệp . Thứ hai , thứ tự được áp đặt trên các giá trị trả về của các phương thức của giao diện Đường dẫn . Trong lớp Tệp , các phương thức trả về Chuỗi hoặc boolean hoặc Tệp . Thật không dễ dàng để tìm ra nó. Ví dụ, có một phương thức getParent() trả về một chuỗi đại diện cho đường dẫn cha của tệp hiện tại. Nhưng cũng có mộtgetParentFile() , trả về cùng một thứ nhưng ở dạng đối tượng Tệp ! Điều này rõ ràng là dư thừa. Theo đó, trong giao diện Đường dẫn , phương thức getParent() và các phương thức khác để làm việc với tệp chỉ cần trả về một đối tượng Đường dẫn . Không có hàng đống tùy chọn — mọi thứ đều dễ dàng và đơn giản. Một số phương pháp hữu ích mà Path có là gì? Dưới đây là một số trong số họ và ví dụ về cách họ làm việc:
  • getFileName() : trả về tên tệp từ đường dẫn;

  • getParent() : trả về thư mục "cha" của đường dẫn hiện tại (nói cách khác, thư mục nằm ngay phía trên cây thư mục);

  • getRoot() : trả về thư mục "root", tức là thư mục ở trên cùng của cây thư mục;

  • startedWith() , endWith() : kiểm tra xem đường dẫn có bắt đầu/kết thúc với đường dẫn đã truyền hay không:

    import java.nio.file.Path;
    import java.nio.file.Paths;
    
    public class Main {
    
       public static void main(String[] args) {
    
           Path testFilePath = Paths.get("C:\\Users\\Username\\Desktop\\testFile.txt");
    
           Path fileName = testFilePath.getFileName();
           System.out.println(fileName);
    
           Path parent = testFilePath.getParent();
           System.out.println(parent);
    
           Path root = testFilePath.getRoot();
           System.out.println(root);
    
           boolean endWithTxt = testFilePath.endsWith("Desktop\\testFile.txt");
           System.out.println(endWithTxt);
    
           boolean startsWithLalala = testFilePath.startsWith("lalalala");
           System.out.println(startsWithLalala);
       }
    }

    Đầu ra bảng điều khiển:

    testFile.txt
    C:\Users\Username\Desktop
    C:\
    true
    false

    Hãy chú ý đến cách thức hoạt động của phương thức endWith() . Nó kiểm tra xem đường dẫn hiện tại có kết thúc bằng đường dẫn đã qua hay không . Cụ thể là nó nằm trong đường dẫn chứ không phải trong chuỗi đã truyền .

    So sánh kết quả của hai cuộc gọi này:

    import java.nio.file.Path;
    import java.nio.file.Paths;
    
    public class Main {
    
       public static void main(String[] args) {
    
           Path testFilePath = Paths.get("C:\\Users\\Username\\Desktop\\testFile.txt");
    
           System.out.println(testFilePath.endsWith("estFile.txt"));
           System.out.println(testFilePath.endsWith("Desktop\\testFile.txt"));
       }
    }

    Đầu ra bảng điều khiển:

    false
    true

    Phương thức endWith() phải được chuyển qua một đường dẫn chính hãng, không chỉ một tập hợp các ký tự: nếu không, kết quả sẽ luôn sai, ngay cả khi đường dẫn hiện tại thực sự kết thúc với chuỗi ký tự đó (như trường hợp của "estFile.txt " trong ví dụ trên).

    Ngoài ra, Path có một nhóm các phương thức giúp đơn giản hóa việc làm việc với các đường dẫn tuyệt đối (đầy đủ) và tương đối .

Hãy xem xét các phương pháp này:
  • boolean isAbsolute() trả về true nếu đường dẫn hiện tại là tuyệt đối:

    import java.nio.file.Path;
    import java.nio.file.Paths;
    
    public class Main {
    
       public static void main(String[] args) {
    
           Path testFilePath = Paths.get("C:\\Users\\Username\\Desktop\\testFile.txt");
    
           System.out.println(testFilePath.isAbsolute());
       }
    }

    Đầu ra bảng điều khiển:

    true
  • Path normalize() : "bình thường hóa" đường dẫn hiện tại, loại bỏ các phần tử không cần thiết khỏi nó. Bạn có thể biết rằng trong các hệ điều hành phổ biến, các ký hiệu "." (thư mục hiện tại) và ".." (thư mục mẹ) thường được sử dụng để chỉ định đường dẫn. Ví dụ: " ./Pictures/dog.jpg " có nghĩa là thư mục hiện tại có thư mục "Pictures", lần lượt thư mục này chứa tệp "dog.jpg".

    Nhìn đây. Nếu một đường dẫn sử dụng "." hoặc ".." xuất hiện trong chương trình của bạn, phương thức normalize() sẽ loại bỏ chúng và tạo ra một đường dẫn không chứa chúng:

    import java.nio.file.Path;
    import java.nio.file.Paths;
    
    public class Main {
    
       public static void main(String[] args) {
    
    
           Path path5 = Paths.get("C:\\Users\\Java\\.\\examples");
    
           System.out.println(path5.normalize());
    
           Path path6 = Paths.get("C:\\Users\\Java\\..\\examples");
           System.out.println(path6.normalize());
       }
    }

    Đầu ra bảng điều khiển:

    C:\Users\Java\examples
    C:\Users\examples
  • Path relativize() : tính toán đường dẫn tương đối giữa đường dẫn hiện tại và đường dẫn đã qua.

    Ví dụ:

    import java.nio.file.Path;
    import java.nio.file.Paths;
    
    public class Main {
    
       public static void main(String[] args) {
    
           Path testFilePath1 = Paths.get("C:\\Users\\Users\\Users\\Users");
           Path testFilePath2 = Paths.get("C:\\Users\\Users\\Users\\Users\\Username\\Desktop\\testFile.txt");
    
           System.out.println(testFilePath1.relativize(testFilePath2));
       }
    }

    Đầu ra bảng điều khiển:

    Username\Desktop\testFile.txt

Danh sách đầy đủ các phương thức Đường dẫn khá dài. Bạn có thể tìm thấy tất cả chúng trong tài liệu của Oracle . Bây giờ chúng ta sẽ chuyển sang xem xét Files .

Các tập tin

Tệp là một lớp tiện ích chứa các phương thức tĩnh được lấy từ lớp Tệp . Tệp có thể so sánh với Mảng hoặc Bộ sưu tập . Sự khác biệt là nó hoạt động với tệp chứ không phải mảng hay bộ sưu tập :) Nó tập trung vào việc quản lý tệp và thư mục. Sử dụng các phương thức tĩnh của lớp Files , chúng ta có thể tạo, xóa và di chuyển các tệp và thư mục. Các thao tác này được thực hiện bằng cách sử dụng các phương thức createFile() (đối với thư mục, createDirectory() ), move() delete() . Đây là cách sử dụng chúng:
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;

public class Main {

   public static void main(String[] args) throws IOException {

       // Create a file
       Path testFile1 = Files.createFile(Paths.get("C:\\Users\\Username\\Desktop\\testFile111.txt"));
       System.out.println("Was the file created successfully?");
       System.out.println(Files.exists(Paths.get("C:\\Users\\Username\\Desktop\\testFile111.txt")));

       // Create a directory
       Path testDirectory = Files.createDirectory(Paths.get("C:\\Users\\Username\\Desktop\\testDirectory"));
       System.out.println("Was the directory created successfully?");
       System.out.println(Files.exists(Paths.get("C:\\Users\\Username\\Desktop\\testDirectory")));

       // Move the file from the desktop to the testDirectory directory. When you move a folder, you need to indicate its name in the folder!
       testFile1 = Files.move(testFile1, Paths.get("C:\\Users\\Username\\Desktop\\testDirectory\\testFile111.txt"), REPLACE_EXISTING);

       System.out.println("Did our file remain on the desktop?");
       System.out.println(Files.exists(Paths.get("C:\\Users\\Username\\Desktop\\testFile111.txt")));

       System.out.println("Has our file been moved to testDirectory?");
       System.out.println(Files.exists(Paths.get("C:\\Users\\Username\\Desktop\\testDirectory\\testFile111.txt")));

       // Delete a file
       Files.delete(testFile1);
       System.out.println("Does the file still exist?");
       System.out.println(Files.exists(Paths.get("C:\\Users\\Username\\Desktop\\testDirectory\\testFile111.txt")));
   }
}
Ở đây, trước tiên chúng ta tạo một tệp ( Phương thức Files.createFile() ) trên màn hình nền. Sau đó, chúng tôi tạo một thư mục ở cùng một vị trí ( Phương thức Files.createDirectory() ). Sau đó, chúng tôi di chuyển tệp ( Phương thức Files.move() ) từ màn hình nền sang thư mục mới này và cuối cùng chúng tôi xóa tệp ( Phương thức Files.delete() ). Đầu ra bảng điều khiển:
Was the file created successfully?
true
Was the directory created successfully?
true
Did our file remain on the desktop?
false
Has our file been moved to testDirectory?
true
Does the file still exist?
false
Ghi chú:giống như các phương thức của Pathgiao diện, nhiều phương thức của Fileslớp trả về mộtPath đối tượng. Hầu hết các phương thức của Fileslớp cũng lấy Pathđối tượng làm đầu vào. Ở đây, Paths.get()phương pháp này sẽ là trợ lý trung thành của bạn — hãy tận dụng nó thật tốt. Điều gì khác là thú vị trong Files? Điều mà lớp cũ Filethực sự thiếu là một copy()phương pháp! Chúng ta đã nói về nó ở phần đầu của bài học này. Bây giờ là lúc để đáp ứng nó!
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;

public class Main {

   public static void main(String[] args) throws IOException {

       // Create a file
       Path testFile1 = Files.createFile(Paths.get("C:\\Users\\Username\\Desktop\\testFile111.txt"));
       System.out.println("Was the file created successfully?");
       System.out.println(Files.exists(Paths.get("C:\\Users\\Username\\Desktop\\testFile111.txt")));

       // Create a directory
       Path testDirectory2 = Files.createDirectory(Paths.get("C:\\Users\\Username\\Desktop\\testDirectory2"));
       System.out.println("Was the directory created successfully?");
       System.out.println(Files.exists(Paths.get("C:\\Users\\Username\\Desktop\\testDirectory2")));

       // Copy the file from the desktop to the testDirectory2 directory.
       testFile1 = Files.copy(testFile1, Paths.get("C:\\Users\\Username\\Desktop\\testDirectory2\\testFile111.txt"), REPLACE_EXISTING);

       System.out.println("Did our file remain on the desktop?");
       System.out.println(Files.exists(Paths.get("C:\\Users\\Username\\Desktop\\testFile111.txt")));

       System.out.println("Was our file copied to testDirectory?");
       System.out.println(Files.exists(Paths.get("C:\\Users\\Username\\Desktop\\testDirectory2\\testFile111.txt")));
   }
}
Đầu ra bảng điều khiển:
Was the file created successfully?
true
Was the directory created successfully?
true
Did our file remain on the desktop?
true
Was our file copied to testDirectory?
true
Bây giờ bạn đã biết cách sao chép tệp theo chương trình! :) Tất nhiên, Fileslớp không chỉ cho phép bạn quản lý tệp mà còn làm việc với nội dung của tệp. Nó có write()phương thức ghi dữ liệu vào một tệp và cả 3 phương thức đọc dữ liệu: read(), readAllBytes(), và readAllLines() Chúng tôi sẽ nói chi tiết về phương thức cuối cùng. Tại sao cái đó? Bởi vì nó có một kiểu trả về rất thú vị: List<String>! Nghĩa là, nó trả về cho chúng ta một danh sách tất cả các dòng trong tệp. Tất nhiên, điều này giúp làm việc với nội dung tệp rất thuận tiện, vì toàn bộ tệp, từng dòng, chẳng hạn, có thể được hiển thị trên bảng điều khiển bằng một vòng lặp thông thường for:
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;

import static java.nio.charset.StandardCharsets.UTF_8;

public class Main {

   public static void main(String[] args) throws IOException {

       List<String> lines = Files.readAllLines(Paths.get("C:\\Users\\Username\\Desktop\\pushkin.txt"), UTF_8);

       for (String s: lines) {
           System.out.println(s);
       }
   }
}
Đầu ra bảng điều khiển:
I still recall the wondrous moment:
When you appeared before my sight,
As though a brief and fleeting omen,
Pure phantom in enchanting light.
Siêu tiện lợi! :) Khả năng này xuất hiện trong Java 7. Stream API xuất hiện trong Java 8. Nó bổ sung một số yếu tố lập trình chức năng cho Java. Bao gồm khả năng xử lý tập tin phong phú hơn. Hãy tưởng tượng rằng chúng ta có nhiệm vụ sau: tìm tất cả các dòng bắt đầu bằng từ "As", chuyển đổi chúng thành CHỮ HOA và hiển thị chúng trên bảng điều khiển. Giải pháp sử dụng Fileslớp trông như thế nào trong Java 7? Một cái gì đó như thế này:
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

import static java.nio.charset.StandardCharsets.UTF_8;

public class Main {

   public static void main(String[] args) throws IOException {

       List<String> lines = Files.readAllLines(Paths.get("C:\\Users\\Username\\Desktop\\pushkin.txt"), UTF_8);

       List<String> result = new ArrayList<>();

       for (String s: lines) {
           if (s.startsWith("As")) {
               String upper = s.toUpperCase();
               result.add(upper);
           }
       }

       for (String s: result) {
           System.out.println(s);
       }
   }
}
Đầu ra bảng điều khiển:
AS THOUGH A BRIEF AND FLEETING OMEN,
PURE PHANTOM IN ENCHANTING LIGHT.
Nhiệm vụ đã hoàn thành, nhưng bạn có nghĩ rằng đối với một nhiệm vụ đơn giản như vậy, mã của chúng tôi hóa ra lại hơi... dài dòng không? Sử dụng API luồng của Java 8, giải pháp trông thanh lịch hơn nhiều:
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Main {

   public static void main(String[] args) throws IOException {

       Stream<String> stream = Files.lines(Paths.get("C:\\Users\\Username\\Desktop\\pushkin.txt"));

       List<String> result  = stream
               .filter(line -> line.startsWith("As"))
               .map(String::toUpperCase)
               .collect(Collectors.toList());
       result.forEach(System.out::println);
   }
}
Chúng tôi đã đạt được kết quả tương tự, nhưng với ít mã hơn nhiều! Hơn nữa, không ai có thể nói rằng chúng tôi đã mất "khả năng đọc". Tôi nghĩ bạn có thể dễ dàng nhận xét về chức năng của đoạn mã này, ngay cả khi không quen thuộc với Stream API. Nói tóm lại, Luồng là một chuỗi các phần tử, qua đó bạn có thể thực hiện các thao tác khác nhau. Chúng ta lấy một đối tượng Stream từ Files.lines()phương thức, sau đó áp dụng 3 hàm cho nó:
  1. Chúng tôi sử dụng filter()phương pháp để chỉ chọn những dòng từ tệp bắt đầu bằng "As".

  2. Chúng tôi duyệt qua tất cả các dòng đã chọn bằng map()phương pháp này và chuyển đổi từng dòng thành HOA.

  3. Chúng tôi sử dụng collect()phương pháp này để tập hợp tất cả các dòng nhận được thành tệp List.

Chúng tôi nhận được cùng một đầu ra:
AS THOUGH A BRIEF AND FLEETING OMEN,
PURE PHANTOM IN ENCHANTING LIGHT.
Bây giờ chúng ta hãy quay trở lại vấn đề chính của chúng ta, đó là các tệp :) Khả năng cuối cùng mà chúng ta sẽ xem xét hôm nay là duyệt qua một cây tệp . Trong các hệ điều hành hiện đại, cấu trúc tệp thường trông giống như một cái cây: nó có gốc và có các nhánh, có thể có các nhánh khác, v.v. Gốc và nhánh là các thư mục. Ví dụ: thư mục " С:// " có thể là thư mục gốc. Nó bao gồm hai nhánh: " C://Downloads " và " C://Users ". Mỗi nhánh này có hai nhánh: " C://Downloads/Pictures ", " C://Downloads/Video ", " C://Users/JohnSmith ", " C://Users/Pudge2005". Và các nhánh này lần lượt có các nhánh khác, v.v. và đây là lý do tại sao chúng ta gọi nó là cây. Trên Linux, cấu trúc tương tự, nhưng thư mục / là thư mục gốc. Bây giờ hãy tưởng tượng rằng chúng ta cần bắt đầu từ thưTệp, Đường dẫn - 2 mục gốc , duyệt qua tất cả các thư mục và thư mục con của nó, đồng thời tìm các tệp có một số nội dung cụ thể. Chúng tôi sẽ tìm kiếm các tệp có dòng "Đây là tệp chúng tôi cần!" Chúng tôi sẽ chọn thư mục "testFolder", nằm trên máy tính để bàn, làm thư mục gốc. Đây là nội dung của nó: Tệp, Đường dẫn - 3Các thư mục cấp 1-a và cấp 1-b cũng chứa các thư mục: Tệp, Đường dẫn - 4Tệp, Đường dẫn - 5Không có thư mục nào trong các "thư mục cấp hai" này, chỉ có các tệp riêng lẻ: Tệp, Đường dẫn - 6Tệp, Đường dẫn - 73 tệp có nội dung chúng tôi cần được đặt tên giải thích một cách có chủ ý: FileWeNeed1.txt, FileWeNeed2.txt, FileWeNeed3.txt. Đây chính xác là những tệp chúng ta cần tìm bằng Java. Chung ta se lam như thê nao? Một phương pháp rất hiệu quả để duyệt qua cây tệp sẽ hỗ trợ chúng ta: Files.walkFileTree (). Đây là những gì chúng ta cần làm. Đầu tiên, chúng ta cần một tệp FileVisitor. FileVisitorlà một giao diện đặc biệt, trong đó mô tả các phương pháp duyệt cây tệp. Cụ thể, đó là nơi chúng tôi sẽ đặt logic để đọc nội dung của tệp và kiểm tra xem tệp đó có chứa văn bản chúng tôi cần hay không. Đây là FileVisitorgiao diện của chúng tôi:
import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.List;

public class MyFileVisitor extends SimpleFileVisitor<Path> {

   @Override
   public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {

       List<String> lines = Files.readAllLines(file);
       for (String s: lines) {
           if (s.contains("This is the file we need")) {
               System.out.println("We found a file we need!");
               System.out.println(file.toAbsolutePath());
               break;
           }
       }

       return FileVisitResult.CONTINUE;
   }
}
Trong trường hợp này, lớp của chúng tôi kế thừa SimpleFileVisitor. Đây là một lớp thực hiện FileVisitor, trong đó chúng ta chỉ cần ghi đè lên một phương thức: visitFile(). Ở đây chúng tôi xác định những gì cần phải được thực hiện với mỗi tệp trong mỗi thư mục. Nếu bạn cần logic phức tạp hơn để duyệt qua cấu trúc tệp, bạn nên viết triển khai FileVisitor. Bạn sẽ cần triển khai thêm 3 phương thức trong lớp đó:
  • preVisitDirectory(): logic để thực hiện trước khi vào một thư mục;

  • visitFileFailed(): logic để thực thi nếu không thể truy cập tệp (không có quyền truy cập hoặc vì lý do khác);

  • postVisitDirectory(): logic để thực thi sau khi vào một thư mục.

Chúng tôi không cần bất kỳ logic nào như vậy được thực thi, vì vậy chúng tôi ổn với SimpleFileVisitor. Logic bên trong visitFile()phương thức khá đơn giản: đọc tất cả các dòng trong tệp, kiểm tra xem chúng có chứa nội dung chúng ta cần hay không và nếu có, hãy in đường dẫn tuyệt đối trên bàn điều khiển. Dòng duy nhất có thể gây khó khăn cho bạn là dòng này:
return FileVisitResult.CONTINUE;
Thật ra, điều này rất đơn giản. Ở đây chúng tôi chỉ đơn giản mô tả những gì chương trình sẽ làm sau khi tệp được truy cập và tất cả các hoạt động cần thiết đã được thực hiện. Trong trường hợp của chúng tôi, chúng tôi muốn tiếp tục duyệt qua cây, vì vậy chúng tôi chọn CONTINUEtùy chọn này. Tuy nhiên, cách khác, chúng ta có thể có một mục tiêu khác: thay vì tìm tất cả các tệp có chứa "Đây là tệp chúng tôi cần", chỉ tìm một tệp như vậy . Sau đó, chương trình sẽ chấm dứt. Trong trường hợp này, mã của chúng ta sẽ trông giống hệt nhau, nhưng thay vì ngắt, sẽ có:
return FileVisitResult.TERMINATE;
Chà, hãy chạy mã của chúng ta và xem nó có hoạt động không.
import java.io.IOException;
import java.nio.file.*;

public class Main {

   public static void main(String[] args) throws IOException {

       Files.walkFileTree(Paths.get("C:\\Users\\Username\\Desktop\\testFolder"), new MyFileVisitor());
   }
}
Đầu ra bảng điều khiển:
We found a file we need!
C:\Users\Username\Desktop\testFolder\FileWeNeed1.txt
We found a file we need!
C:\Users\Username\Desktop\testFolder\level1-a\level2-a-a\FileWeNeed2.txt
We found a file we need!
C:\Users\Username\Desktop\testFolder\level1-b\level2-b-b\FileWeNeed3.txt
Xuất sắc! Nó đã làm việc! :) Bạn cũng có thể chấp nhận thử thách nhỏ này: thay thế SimpleFileVisitorbằng phương thức thông thường FileVisitor, ghi đè cả 4 phương thức và đưa ra mục đích của riêng bạn cho chương trình. Ví dụ: bạn có thể viết một chương trình ghi lại tất cả các hành động của nó: hiển thị tên của tệp hoặc thư mục trước hoặc sau khi nhập chúng. Đó là tất cả cho bây giờ. Hẹn sớm gặp lại! :)
Bình luận
  • Phổ biến
  • Mới
Bạn phải đăng nhập để đăng nhận xet
Trang này chưa có bất kỳ bình luận nào