แสดงรายการไฟล์ทั้งหมดจากไดเร็กทอรีแบบวนซ้ำด้วย Java


86

ฉันมีฟังก์ชันนี้ที่พิมพ์ชื่อของไฟล์ทั้งหมดในไดเร็กทอรีแบบวนซ้ำ ปัญหาคือรหัสของฉันช้ามากเพราะต้องเข้าถึงอุปกรณ์เครือข่ายระยะไกลด้วยการทำซ้ำทุกครั้ง

แผนของฉันคือก่อนอื่นให้โหลดไฟล์ทั้งหมดจากไดเร็กทอรีแบบวนซ้ำจากนั้นไปที่ไฟล์ทั้งหมดด้วย regex เพื่อกรองไฟล์ทั้งหมดที่ฉันไม่ต้องการ ใครมีคำแนะนำที่ดีกว่านี้ไหม

public static printFnames(String sDir){
  File[] faFiles = new File(sDir).listFiles();
  for(File file: faFiles){
    if(file.getName().matches("^(.*?)")){
      System.out.println(file.getAbsolutePath());
    }
    if(file.isDirectory()){
      printFnames(file.getAbsolutePath());
    }
  }
}

นี่เป็นเพียงการทดสอบในภายหลังฉันจะไม่ใช้รหัสแบบนี้ แต่ฉันจะเพิ่มเส้นทางและวันที่แก้ไขของทุกไฟล์ที่ตรงกับ regex ขั้นสูงกับอาร์เรย์


1
... คำถามคืออะไร? คุณกำลังมองหาการตรวจสอบความถูกต้องว่ารหัสนี้ใช้งานได้หรือไม่?
Richard JP Le Guen

ไม่ฉันรู้ว่ารหัสนี้ใช้งานได้ แต่มันช้ามากและรู้สึกว่ามันโง่เข้าถึงระบบไฟล์และรับเนื้อหาสำหรับทุกไดเรกทอรีย่อยแทนที่จะได้รับทุกอย่างพร้อมกัน
Hultner

1
ซ้ำเป็นไปได้ของรายการซ้ำไฟล์ในชวา
Prahalad Gaggar

คำตอบ:


134

สมมติว่านี้เป็นรหัสการผลิตจริงคุณจะเขียนแล้วผมขอแนะนำให้ใช้วิธีการเรียงลำดับของสิ่งนี้ที่ได้รับการแก้ไขแล้ว - Apache Commons IOFileUtils.listFiles()เฉพาะ จัดการไดเรกทอรีที่ซ้อนกันตัวกรอง (ตามชื่อเวลาแก้ไข ฯลฯ )

ตัวอย่างเช่นสำหรับ regex ของคุณ:

Collection files = FileUtils.listFiles(
  dir, 
  new RegexFileFilter("^(.*?)"), 
  DirectoryFileFilter.DIRECTORY
);

การดำเนินการนี้จะค้นหาไฟล์ที่ตรงกับ^(.*?)regex ซ้ำ ๆ โดยส่งคืนผลลัพธ์เป็นคอลเล็กชัน

เป็นที่น่าสังเกตว่าสิ่งนี้จะไม่เร็วไปกว่าการรีดโค้ดของคุณเอง แต่ก็ทำสิ่งเดียวกัน - การลากระบบไฟล์ใน Java นั้นช้า ความแตกต่างคือเวอร์ชัน Apache Commons จะไม่มีบั๊ก


ฉันดูที่นั่นและจากนั้นฉันจะใช้commons.apache.org/io/api-release/index.html?org/apache/commons/…เพื่อรับไฟล์ทั้งหมดจากไดเร็กทอรีและไดเร็กทอรีย่อยจากนั้นค้นหาไฟล์เพื่อให้ ตรงกับนิพจน์ทั่วไปของฉัน หรือว่าฉันผิด?
Hultner

ใช่ปัญหาต้องใช้เวลามากกว่าหนึ่งชั่วโมงในการสแกนโฟลเดอร์และการทำเช่นนั้นทุกครั้งที่ฉันเริ่มโปรแกรมเพื่อตรวจสอบการอัปเดตนั้นน่ารำคาญมาก จะเร็วกว่าไหมถ้าฉันเขียนส่วนนี้ของโปรแกรมด้วยภาษา C และส่วนที่เหลือใน Java และถ้าเป็นเช่นนั้นจะมีความแตกต่างอย่างมีนัยสำคัญหรือไม่ ตอนนี้ฉันเปลี่ยนรหัสในบรรทัด if isdir และเพิ่มเพื่อให้ไดเร็กทอรีต้องตรงกับ regex เพื่อรวมอยู่ในการค้นหา ฉันเห็นว่าในตัวอย่างของคุณระบุว่า DirectoryFileFilter.DIRECTORY ฉันเดาว่าฉันมีตัวกรอง regex อยู่ที่นั่น
Hultner

1
การเขียนโดยใช้การโทรแบบเนทีฟจะทำให้เร็วขึ้นอย่างแน่นอน - FindFirstFile / FineNextFile ช่วยให้คุณค้นหาแอตทริบิวต์ของไฟล์โดยไม่ต้องโทรแยกต่างหากซึ่งอาจมีผลกระทบอย่างมากต่อเครือข่ายเวลาแฝงที่สูงขึ้น แนวทางของ Java ในเรื่องนี้ไม่มีประสิทธิภาพอย่างมาก
Kevin Day

5
@ hanzallah-afgan: ทั้งคำถามและคำตอบมีอายุมากกว่า 5 ปี มีการเผยแพร่ Java ที่สำคัญสองครั้งในช่วงเวลาที่ผ่านมาดังนั้นคุณอาจไม่ต้องการตรวจสอบคุณลักษณะใหม่ ๆ เช่น Java 7 NIO
Hultner

4
ใช้เพียง FileUtils ถ้าคุณมีความตระหนักและยอมรับตีประสิทธิภาพ: github.com/brettryan/io-recurse-tests ทางเลือกดั้งเดิมของ java8 ให้สัญกรณ์ที่สั้นและมีประสิทธิภาพมากขึ้นเช่น:Files.walk(Paths.get("/etc")).filter(Files::isRegularFile).collect(Collectors.toList())
ccpizza

66

ใน Java 8 เป็น 1 ซับFiles.find()โดยมีความลึกขนาดใหญ่โดยพลการ (เช่น999) และBasicFileAttributesของisRegularFile()

public static printFnames(String sDir) {
    Files.find(Paths.get(sDir), 999, (p, bfa) -> bfa.isRegularFile()).forEach(System.out::println);
}

หากต้องการเพิ่มการกรองเพิ่มเติมให้ปรับปรุงแลมด้าตัวอย่างเช่นไฟล์ jpg ทั้งหมดที่แก้ไขในช่วง 24 ชั่วโมงที่ผ่านมา:

(p, bfa) -> bfa.isRegularFile()
  && p.getFileName().toString().matches(".*\\.jpg")
  && bfa.lastModifiedTime().toMillis() > System.currentMillis() - 86400000

3
ฉันขอแนะนำให้ใช้วิธีการไฟล์เหล่านั้นซึ่งส่งคืนสตรีมในบล็อกการลองใช้ทรัพยากรเสมอมิฉะนั้นคุณจะเปิดทรัพยากรไว้เสมอ
riccardo.tasso

การดำเนินการของเทอร์มินัลไม่เรียกปิดสตรีมเองหรือ
Dragas

@Dragas ใช่ ผู้บริโภคของฉันเป็นเพียงตัวอย่างง่ายๆ ในชีวิตจริงคุณจะทำสิ่งที่มีประโยชน์มากกว่านี้
โบฮีเมียน

27

นี่เป็นวิธีการเรียกซ้ำที่ง่ายมากในการรับไฟล์ทั้งหมดจากรูทที่กำหนด

ใช้คลาส Java 7 NIO Path

private List<String> getFileNames(List<String> fileNames, Path dir) {
    try(DirectoryStream<Path> stream = Files.newDirectoryStream(dir)) {
        for (Path path : stream) {
            if(path.toFile().isDirectory()) {
                getFileNames(fileNames, path);
            } else {
                fileNames.add(path.toAbsolutePath().toString());
                System.out.println(path.getFileName());
            }
        }
    } catch(IOException e) {
        e.printStackTrace();
    }
    return fileNames;
} 

18

ด้วย Java 7 วิธีที่เร็วกว่าในการเดินผ่านไดเร็กทอรีทรีได้รับการแนะนำด้วยฟังก์ชันPathsและFilesฟังก์ชัน มันเร็วกว่าวิธี "เก่า" Fileมาก

นี่จะเป็นรหัสสำหรับเดินผ่านและตรวจสอบชื่อพา ธ ด้วยนิพจน์ทั่วไป:

public final void test() throws IOException, InterruptedException {
    final Path rootDir = Paths.get("path to your directory where the walk starts");

    // Walk thru mainDir directory
    Files.walkFileTree(rootDir, new FileVisitor<Path>() {
        // First (minor) speed up. Compile regular expression pattern only one time.
        private Pattern pattern = Pattern.compile("^(.*?)");

        @Override
        public FileVisitResult preVisitDirectory(Path path,
                BasicFileAttributes atts) throws IOException {

            boolean matches = pattern.matcher(path.toString()).matches();

            // TODO: Put here your business logic when matches equals true/false

            return (matches)? FileVisitResult.CONTINUE:FileVisitResult.SKIP_SUBTREE;
        }

        @Override
        public FileVisitResult visitFile(Path path, BasicFileAttributes mainAtts)
                throws IOException {

            boolean matches = pattern.matcher(path.toString()).matches();

            // TODO: Put here your business logic when matches equals true/false

            return FileVisitResult.CONTINUE;
        }

        @Override
        public FileVisitResult postVisitDirectory(Path path,
                IOException exc) throws IOException {
            // TODO Auto-generated method stub
            return FileVisitResult.CONTINUE;
        }

        @Override
        public FileVisitResult visitFileFailed(Path path, IOException exc)
                throws IOException {
            exc.printStackTrace();

            // If the root directory has failed it makes no sense to continue
            return path.equals(rootDir)? FileVisitResult.TERMINATE:FileVisitResult.CONTINUE;
        }
    });
}

5
คำตอบที่ดี :) มีคลาสที่ใช้งานเรียกว่า "SimpleFileVisitor" หากคุณไม่ต้องการ fucntions ที่ใช้งานทั้งหมดคุณสามารถแทนที่ฟังก์ชันที่จำเป็นได้
GalDude33

13

วิธีที่รวดเร็วในการรับเนื้อหาของไดเร็กทอรีโดยใช้ Java 7 NIO:

import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.FileSystems;
import java.nio.file.Path;

...

Path dir = FileSystems.getDefault().getPath( filePath );
DirectoryStream<Path> stream = Files.newDirectoryStream( dir );
for (Path path : stream) {
   System.out.println( path.getFileName() );
}
stream.close();

3
ดี แต่ได้รับไฟล์สำหรับไดเร็กทอรีเดียวเท่านั้น หากคุณต้องการดูไดเรกทอรีย่อยทั้งหมดให้ดูคำตอบอื่นของฉัน
Dan

3
Files.newDirectoryStreamสามารถโยน IOException ฉันขอแนะนำให้ตัดบรรทัดนั้นใน Java7 try-with-statement เพื่อให้สตรีมถูกปิดเสมอสำหรับคุณ (ยกเว้นหรือไม่โดยไม่ต้องใช้ a finally) ดูเพิ่มเติมได้ที่นี่: stackoverflow.com/questions/17739362/…
Greg

12

อินเทอร์เฟซของ Java สำหรับอ่านเนื้อหาโฟลเดอร์ระบบไฟล์ไม่ค่อยมีประสิทธิภาพ (ตามที่คุณค้นพบ) JDK 7 แก้ไขปัญหานี้ด้วยอินเทอร์เฟซใหม่ทั้งหมดสำหรับสิ่งนี้ซึ่งควรนำประสิทธิภาพระดับเนทีฟมาสู่การดำเนินการประเภทนี้

ปัญหาหลักคือ Java ทำการเรียกระบบเนทีฟสำหรับทุกไฟล์ ในอินเทอร์เฟซที่มีเวลาแฝงต่ำนี่ไม่ใช่ข้อตกลงที่ใหญ่ แต่ในเครือข่ายที่มีเวลาแฝงในระดับปานกลางจะเพิ่มขึ้นอย่างแท้จริง หากคุณกำหนดรายละเอียดอัลกอริทึมของคุณด้านบนคุณจะพบว่าเวลาส่วนใหญ่ใช้ไปกับการโทร isDirectory () ที่น่ารำคาญนั่นเป็นเพราะคุณต้องเดินทางไปกลับสำหรับการโทรไปยัง isDirectory () ทุกครั้ง ระบบปฏิบัติการที่ทันสมัยส่วนใหญ่สามารถให้ข้อมูลประเภทนี้ได้เมื่อมีการร้องขอรายการไฟล์ / โฟลเดอร์ในตอนแรก (ตรงข้ามกับการค้นหาเส้นทางไฟล์แต่ละไฟล์สำหรับคุณสมบัติของมัน)

หากคุณไม่สามารถรอ JDK7 ได้กลยุทธ์หนึ่งในการจัดการกับเวลาในการตอบสนองนี้คือการใช้งานแบบมัลติเธรดและใช้ ExecutorService ที่มีจำนวนเธรดสูงสุดเพื่อดำเนินการเรียกซ้ำของคุณ มันไม่ดีมาก (คุณต้องจัดการกับการล็อกโครงสร้างข้อมูลเอาต์พุตของคุณ) แต่มันจะเร็วกว่าการทำเธรดเดียวนี้มาก

ในการอภิปรายทั้งหมดของคุณเกี่ยวกับสิ่งเหล่านี้ฉันขอแนะนำให้คุณเปรียบเทียบกับสิ่งที่ดีที่สุดที่คุณสามารถทำได้โดยใช้โค้ดเนทีฟ (หรือแม้แต่สคริปต์บรรทัดคำสั่งที่ทำสิ่งเดียวกันโดยประมาณ) การบอกว่าใช้เวลาหนึ่งชั่วโมงในการสำรวจโครงสร้างเครือข่ายไม่ได้มีความหมายมากนัก บอกเราว่าคุณสามารถทำได้ใน 7 วินาที แต่ต้องใช้เวลาหนึ่งชั่วโมงใน Java จะได้รับความสนใจจากผู้คน


3
ตอนนี้ Java 7 มีตัวอย่างวิธีการใช้งานใน Java 7 จะเป็นประโยชน์ หรืออย่างน้อยลิงค์ หรือชื่อคลาสเพื่อค้นหาใน google. - นี่คือ« stackoverflow »และไม่ใช่«ตามทฤษฎี cs » ;-)
Martin

3
มาดูกันดีกว่า ... โพสต์เดิมของฉันคือในเดือนมีนาคม 2010 ... ตอนนี้เป็นเดือนมกราคม 2012 ... และฉันเพิ่งตรวจสอบประวัติคลังอุปกรณ์ของฉันและฉันไม่เห็นว่าตัวเองมีไทม์แมชชีนในเดือนมีนาคม '10 ดังนั้นฉันคิดว่าฉันคงมีเหตุผลที่จะตอบโดยไม่ต้องยกตัวอย่างที่ชัดเจน ;-)
Kevin Day


7

สิ่งนี้จะใช้งานได้ดี ... และเป็นแบบวนซ้ำ

File root = new File("ROOT PATH");
for ( File file : root.listFiles())
{
    getFilesRecursive(file);
}


private static void getFilesRecursive(File pFile)
{
    for(File files : pFile.listFiles())
    {
        if(files.isDirectory())
        {
            getFilesRecursive(files);
        }
        else
        {
            // do your thing 
            // you can either save in HashMap and use it as
            // per your requirement
        }
    }
}

1
คำตอบที่ดีหากคุณต้องการบางสิ่งที่ใช้งานได้กับ java <7
ssimm

3

ผมชอบ FileUtils เวอร์ชันนี้เป็นการส่วนตัว นี่คือตัวอย่างที่ค้นหา mp3s หรือ flacs ทั้งหมดในไดเร็กทอรีหรือไดเร็กทอรีย่อยใด ๆ :

String[] types = {"mp3", "flac"};
Collection<File> files2 = FileUtils.listFiles(/path/to/your/dir, types , true);

3

วิธีนี้จะทำงานได้ดี

public void displayAll(File path){      
    if(path.isFile()){
        System.out.println(path.getName());
    }else{
        System.out.println(path.getName());         
        File files[] = path.listFiles();
        for(File dirOrFile: files){
            displayAll(dirOrFile);
        }
    }
}


ยินดีต้อนรับสู่ StackOverflow Mam คุณช่วยอธิบายได้ไหมว่าคำตอบของคุณคือการปรับปรุงหรือทางเลือกสำหรับคำตอบที่มีอยู่มากมายได้อย่างไร
Lilienthal

1

ฟังก์ชันนี้อาจจะแสดงรายการชื่อไฟล์และพา ธ ทั้งหมดจากไดเร็กทอรีและไดเร็กทอรีย่อย

public void listFile(String pathname) {
    File f = new File(pathname);
    File[] listfiles = f.listFiles();
    for (int i = 0; i < listfiles.length; i++) {
        if (listfiles[i].isDirectory()) {
            File[] internalFile = listfiles[i].listFiles();
            for (int j = 0; j < internalFile.length; j++) {
                System.out.println(internalFile[j]);
                if (internalFile[j].isDirectory()) {
                    String name = internalFile[j].getAbsolutePath();
                    listFile(name);
                }

            }
        } else {
            System.out.println(listfiles[i]);
        }

    }

}

1
ตัวอย่างนี้ไม่ได้คำนึงถึงข้อเท็จจริงที่ว่า listFiles () วิธีการสามารถและจะคืนค่าว่าง docs.oracle.com/javase/7/docs/api/java/io/File.html#listFiles ()
Matt Jones

1

จาวา 8

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

        Path start = Paths.get("C:\\data\\");
        try (Stream<Path> stream = Files.walk(start, Integer.MAX_VALUE)) {
            List<String> collect = stream
                .map(String::valueOf)
                .sorted()
                .collect(Collectors.toList());

            collect.forEach(System.out::println);
        }


    }

0

รู้สึกเหมือนว่ามันโง่เข้าถึงระบบไฟล์และรับเนื้อหาสำหรับทุกไดเรกทอรีย่อยแทนที่จะได้รับทุกอย่างพร้อมกัน

ความรู้สึกของคุณผิด นั่นคือวิธีการทำงานของระบบไฟล์ ไม่มีวิธีที่เร็วกว่านี้ (ยกเว้นเมื่อคุณต้องทำสิ่งนี้ซ้ำ ๆ หรือสำหรับรูปแบบที่แตกต่างกันคุณสามารถแคชเส้นทางไฟล์ทั้งหมดในหน่วยความจำได้ แต่คุณต้องจัดการกับการทำให้แคชไม่ถูกต้องเช่นจะเกิดอะไรขึ้นเมื่อไฟล์ถูกเพิ่ม / ลบ / เปลี่ยนชื่อในขณะที่ แอปทำงาน)


สิ่งนี้คือฉันต้องการโหลดไฟล์ทุกประเภทที่มีรูปแบบชื่อที่แน่นอนลงในไลบรารีซึ่งจะนำเสนอต่อผู้ใช้และทุกครั้งที่แอปเริ่มต้นไลบรารีควรได้รับการอัปเดต แต่ต้องใช้เวลาตลอดไปในการอัปเดตไลบรารี ทางออกเดียวที่ฉันได้รับคือเรียกใช้การอัปเดตในพื้นหลัง แต่ก็ยังน่ารำคาญที่ต้องใช้เวลานานจนกว่าไฟล์ใหม่จะโหลดทั้งหมด จะต้องมีวิธีที่ดีกว่านี้ หรืออย่างน้อยวิธีที่ดีกว่าในการอัปเดตฐานข้อมูล มันรู้สึกโง่มากที่ต้องผ่านไฟล์ทั้งหมดที่มีอยู่แล้ว มีวิธีค้นหาเฉพาะการอัปเดตอย่างรวดเร็ว
Hultner

@Hultner: Java 7 จะรวมสิ่งอำนวยความสะดวกสำหรับการรับแจ้งการอัปเดตระบบไฟล์ แต่จะยังคงใช้งานได้ในขณะที่แอปกำลังทำงานอยู่เท่านั้นดังนั้นหากคุณไม่ต้องการให้บริการพื้นหลังทำงานตลอดเวลาก็จะไม่ช่วย อาจมีปัญหาพิเศษเกี่ยวกับการแชร์เครือข่ายตามที่ Kevin อธิบาย แต่ตราบใดที่คุณต้องพึ่งพาการสแกนผ่านแผนผังไดเรกทอรีทั้งหมดไม่มีวิธีใดที่ดีไปกว่านี้
Michael Borgwardt

บางทีคุณอาจสร้างไฟล์ดัชนีบางไฟล์ หากมีวิธีตรวจสอบขนาดไดเร็กทอรีคุณสามารถสแกนหาไฟล์ใหม่เมื่อขนาดเปลี่ยนไป
James P.

@ เจมส์: ไม่มีวิธีตรวจสอบขนาดไดเร็กทอรี ขนาดของไดเร็กทอรีได้มาจากการรับขนาดสำหรับแต่ละไฟล์และเพิ่มขึ้นในระบบไฟล์ทั้งหมดที่ฉันทราบ จริงๆแล้วคำถาม "ไดเร็กทอรีนี้มีขนาดเท่าใด" ไม่จำเป็นต้องมีเหตุผลเลยหากคุณพิจารณาฮาร์ดลิงก์
Michael Borgwardt

คุณถูก. ฉันยังรู้สึกว่าการแคชและ / หรือการพิมพ์ลายนิ้วมืออาจทำให้กระบวนการเร็วขึ้น
James P.

0

เพียงเพื่อให้คุณทราบว่า isDirectory () เป็นวิธีที่ค่อนข้างช้า ฉันพบว่ามันค่อนข้างช้าในเบราว์เซอร์ไฟล์ของฉัน ฉันจะหาไลบรารีเพื่อแทนที่ด้วยโค้ดเนทีฟ


0

วิธีที่มีประสิทธิภาพมากกว่าที่ฉันพบในการจัดการกับโฟลเดอร์และไฟล์นับล้านคือการจับรายชื่อไดเร็กทอรีผ่านคำสั่ง DOS ในบางไฟล์และแยกวิเคราะห์ เมื่อคุณแยกวิเคราะห์ข้อมูลแล้วคุณสามารถทำการวิเคราะห์และคำนวณสถิติได้


0
import java.io.*;

public class MultiFolderReading {

public void checkNoOfFiles (String filename) throws IOException {

    File dir=new File(filename);
    File files[]=dir.listFiles();//files array stores the list of files

 for(int i=0;i<files.length;i++)
    {
        if(files[i].isFile()) //check whether files[i] is file or directory
        {
            System.out.println("File::"+files[i].getName());
            System.out.println();

        }
        else if(files[i].isDirectory())
        {
            System.out.println("Directory::"+files[i].getName());
            System.out.println();
            checkNoOfFiles(files[i].getAbsolutePath());
        }
    }
}

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

    MultiFolderReading mf=new MultiFolderReading();
    String str="E:\\file"; 
    mf.checkNoOfFiles(str);
   }
}

กรุณาเพิ่มคำอธิบายด้วย
d4Rk

0

ใน Guava คุณไม่จำเป็นต้องรอให้คอลเล็กชันส่งคืนให้คุณ แต่สามารถทำซ้ำไฟล์ได้ เป็นเรื่องง่ายที่จะจินตนาการถึงIDoSomethingWithThisFileอินเทอร์เฟซในลายเซ็นของฟังก์ชันด้านล่าง:

public static void collectFilesInDir(File dir) {
    TreeTraverser<File> traverser = Files.fileTreeTraverser();
    FluentIterable<File> filesInPostOrder = traverser.preOrderTraversal(dir);
    for (File f: filesInPostOrder)
        System.out.printf("File: %s\n", f.getPath());
}

TreeTraverserยังช่วยให้คุณสามารถข้ามรูปแบบการเดินทางต่างๆ


0
public class GetFilesRecursive {
    public static List <String> getFilesRecursively(File dir){
        List <String> ls = new ArrayList<String>();
        for (File fObj : dir.listFiles()) {
            if(fObj.isDirectory()) {
                ls.add(String.valueOf(fObj));
                ls.addAll(getFilesRecursively(fObj));               
            } else {
                ls.add(String.valueOf(fObj));       
            }
        }

        return ls;
    }
    public static List <String> getListOfFiles(String fullPathDir) {
        List <String> ls = new ArrayList<String> ();
        File f = new File(fullPathDir);
        if (f.exists()) {
            if(f.isDirectory()) {
                ls.add(String.valueOf(f));
                ls.addAll(getFilesRecursively(f));
            }
        } else {
            ls.add(fullPathDir);
        }
        return ls;
    }

    public static void main(String[] args) {
        List <String> ls = getListOfFiles("/Users/srinivasab/Documents");
        for (String file:ls) {
            System.out.println(file);
        }
        System.out.println(ls.size());
    }
}

0

รหัสที่ปรับให้เหมาะสมอื่น ๆ

import java.io.File;
import java.util.ArrayList;
import java.util.List;

public class GetFilesRecursive {
    public static List <String> getFilesRecursively(File dir){
        List <String> ls = new ArrayList<String>();
        if (dir.isDirectory())
            for (File fObj : dir.listFiles()) {
                if(fObj.isDirectory()) {
                    ls.add(String.valueOf(fObj));
                    ls.addAll(getFilesRecursively(fObj));               
                } else {
                    ls.add(String.valueOf(fObj));       
                }
            }
        else
            ls.add(String.valueOf(dir));

        return ls;
    }

    public static void main(String[] args) {
        List <String> ls = getFilesRecursively(new File("/Users/srinivasab/Documents"));
        for (String file:ls) {
            System.out.println(file);
        }
        System.out.println(ls.size());
    }
}

กรุณาช่วยเพิ่มคำตอบพร้อมคำอธิบายโดยละเอียดได้ไหม สิ่งนี้จะเป็นประโยชน์มากสำหรับการทำความเข้าใจ ขอขอบคุณ!
vezunchik

0

อีกหนึ่งตัวอย่างของการแสดงรายการไฟล์และไดเร็กทอรีโดยใช้ Java 8 filter

public static void main(String[] args) {

System.out.println("Files!!");
        try {
            Files.walk(Paths.get("."))
                    .filter(Files::isRegularFile)
                    .filter(c ->
                            c.getFileName().toString().substring(c.getFileName().toString().length()-4).contains(".jpg")
                            ||
                            c.getFileName().toString().substring(c.getFileName().toString().length()-5).contains(".jpeg")
                    )
                    .forEach(System.out::println);

        } catch (IOException e) {
        System.out.println("No jpeg or jpg files");
        }

        System.out.println("\nDirectories!!\n");
        try {
            Files.walk(Paths.get("."))
                    .filter(Files::isDirectory)
                    .forEach(System.out::println);

        } catch (IOException e) {
            System.out.println("No Jpeg files");
        }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.