Sử dụng File.listFiles với FileNameExtensionFilter


82

Tôi muốn nhận danh sách các tệp có phần mở rộng cụ thể trong một thư mục. Trong API (Java 6), tôi thấy một phương pháp File.listFiles(FileFilter)sẽ thực hiện điều này.

Vì tôi cần một tiện ích mở rộng cụ thể, tôi đã tạo một FileNameExtensionFilter. Tuy nhiên, tôi gặp lỗi biên dịch khi sử dụng listFilesvới điều này. Tôi cho rằng kể từ đó FileNameExtensionFilter implements FileFilter, tôi sẽ có thể làm được điều này. Mã sau:

FileNameExtensionFilter filter = new FileNameExtensionFilter("text only","txt");
String dir  = "/users/blah/dirname";
File f[] = (new File(dir)).listFiles(filter);

Dòng cuối cùng hiển thị lỗi biên dịch:

phương thức listFiles (FileNameFilter) trong loại Tệp không áp dụng cho các đối số thuộc loại FileNameExtensionFilter

Tôi đang cố gắng sử dụng listFiles(FileFilter), không phải listFiles(FileNameFilter). Tại sao trình biên dịch không nhận ra điều này?

Điều này hoạt động nếu tôi viết mở rộng bộ lọc tiện ích mở rộng của riêng mình FileFilter. Tôi muốn sử dụng FileNameExtensionFilterhơn là viết của riêng tôi. Tôi đang làm gì sai?


Trước hết, bạn cần có "txt" làm đối số thứ nhất và "chỉ văn bản" là đối số thứ hai.
tôm hùm1234

Câu trả lời:


182

Các FileNameExtensionFilterlớp học được thiết kế cho Swing được sử dụng trong một JFileChooser.

Hãy thử sử dụng FilenameFilterthay thế. Ví dụ:

File dir = new File("/users/blah/dirname");
File[] files = dir.listFiles(new FilenameFilter() {
    public boolean accept(File dir, String name) {
        return name.toLowerCase().endsWith(".txt");
    }
});

37

Cú pháp One-liner trong java 8:

pdfTestDir.listFiles((dir, name) -> name.toLowerCase().endsWith(".txt"));

7
Bạn có thể bỏ qua dấu ngoặc nhọn và trở lại:pdfTestDir.listFiles((dir, name) -> name.toLowerCase().endsWith(".txt"));
Gabor Szarnyas

Một giải pháp khác:Files.list(Paths.get("your/path")).filter(path -> path.toString().endsWith(".txt")).collect(Collectors.toList());
CeePlusPlus

28

Có lý do cụ thể nào mà bạn muốn sử dụng FileNameExtensionFilterkhông? Tôi biết điều này hoạt động ..

private File[] getNewTextFiles() {
    return dir.listFiles(new FilenameFilter() {
        @Override
        public boolean accept(File dir, String name) {
            return name.toLowerCase().endsWith(".txt");
        }
    });
}

1

Duh .... listFiles yêu cầu java.io.FileFilter. FileNameExtensionFilter mở rộng javax.swing.filechooser.FileFilter. Tôi đã giải quyết vấn đề của mình bằng cách triển khai một phiên bản của java.io.FileFilter

Chỉnh sửa: Tôi đã sử dụng một cái gì đó tương tự như câu trả lời của @ cFreiner. Tôi đang cố gắng sử dụng một phương pháp Java API thay vì viết triển khai của riêng mình, đó là lý do tại sao tôi cố gắng sử dụng FileNameExtensionFilter. Tôi có nhiều FileChoosers trong ứng dụng của mình và đã sử dụng FileNameExtensionFilters cho việc đó và tôi nhầm tưởng rằng nó cũng đang mở rộng java.io.FileFilter.


1

Đây là thứ mà tôi vừa nhanh chóng thực hiện và nó sẽ hoạt động tốt hơn nhiều so với File.getName (). EndWith (". Xxxx");

import java.io.File;
import java.io.FileFilter;

public class ExtensionsFilter implements FileFilter 
{
    private char[][] extensions;

    private ExtensionsFilter(String[] extensions)
    {
        int length = extensions.length;
        this.extensions = new char[length][];
        for (String s : extensions)
        {
            this.extensions[--length] = s.toCharArray();
        }
    }

    @Override
    public boolean accept(File file)
    {
        char[] path = file.getPath().toCharArray();
        for (char[] extension : extensions)
        {
            if (extension.length > path.length)
            {
                continue;
            }
            int pStart = path.length - 1;
            int eStart = extension.length - 1;
            boolean success = true;
            for (int i = 0; i <= eStart; i++)
            {
                if ((path[pStart - i] | 0x20) != (extension[eStart - i] | 0x20))
                {
                    success = false;
                    break;
                }
            }
            if (success)
                return true;
        }
        return false;
    }
}

Đây là một ví dụ cho các định dạng hình ảnh khác nhau.

private static final ExtensionsFilter IMAGE_FILTER = 
      new ExtensionsFilter(new String[] {".png", ".jpg", ".bmp"});

10
Tốt, nhưng câu thần chú mới của tôi là giữ mọi thứ đơn giản trừ khi chúng cần phức tạp hơn, nghĩa là, sử dụng các phương thức / lớp API Java trừ khi tôi thực sự phải viết riêng.
Anu

@JeremyTrifilo Tại sao bạn thực hiện đường dẫn [pStart - i] | 0x20 trong mã?
Sohil

1
Tại sao phải phát minh lại bánh xe?
james.garriss

Các | 20 dành cho các biến thể Chữ hoa và Chữ thường. Nó buộc thêm 32 vào chữ cái khiến nó trở thành chữ thường để kiểm tra. Vì vậy, bạn có thể lưu một tệp dưới dạng Example.PnG hoặc Example.pNg và nó vẫn sẽ nhận nó. Tôi thường không làm lại những thứ như thế này, nhưng tôi làm điều đó bởi vì đó là một việc học tuyệt vời nếu bạn có thể hiểu cách những thứ này hoạt động và có thể làm gì để cải thiện chúng. Tuy nhiên, tôi hiểu ý bạn là nó thừa cho trường hợp này vì hiệu suất tăng là tối thiểu và không cần phải nhanh.
Jeremy Trifilo

1

Với java lambdas (có sẵn kể từ java 8), bạn chỉ cần chuyển đổi javax.swing.filechooser.FileFilterthành java.io.FileFiltermột dòng.

javax.swing.filechooser.FileFilter swingFilter = new FileNameExtensionFilter("jpeg files", "jpeg");
java.io.FileFilter ioFilter = file -> swingFilter.accept(file);
new File("myDirectory").listFiles(ioFilter);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.