แสดงรายการไฟล์ซ้ำใน Java


258

ฉันจะแสดงรายการไฟล์ทั้งหมดซ้ำในไดเรกทอรีใน Java ซ้ำได้อย่างไร เฟรมเวิร์กมียูทิลิตีใด ๆ หรือไม่?

ฉันเห็นการใช้งานแฮ็คจำนวนมาก แต่ไม่มีจากกรอบหรือnio


2
ฉันเพิ่งเสร็จสิ้นผลการทดสอบที่ให้การทดสอบประสิทธิภาพสำหรับคำตอบมากมาย คำตอบที่ใช้ NIO นั้นน่าประหลาดใจมากทำงานได้ดีที่สุด คำตอบทั่วไปคือคำตอบที่ชัดเจนที่สุดว่าเป็นนักแสดงที่มีความยาวมากกว่าสองเท่า
Brett Ryan

2
Java8: Files.walk?
Benj

คำตอบ:


327

Java 8 จัดเตรียมสตรีมที่ดีเพื่อประมวลผลไฟล์ทั้งหมดในแผนผัง

Files.walk(Paths.get(path))
        .filter(Files::isRegularFile)
        .forEach(System.out::println);

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

UPDATE : ฉันอาจชี้ให้เห็นว่ายังมีFiles.findซึ่งใช้BiPredicateซึ่งอาจมีประสิทธิภาพมากกว่าหากคุณต้องการตรวจสอบคุณสมบัติของไฟล์

Files.find(Paths.get(path),
           Integer.MAX_VALUE,
           (filePath, fileAttr) -> fileAttr.isRegularFile())
        .forEach(System.out::println);

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

การทดสอบ : ตามที่ร้องขอฉันได้ให้การเปรียบเทียบประสิทธิภาพของคำตอบมากมาย ตรวจสอบโครงการ Github ซึ่งมีผลและกรณีทดสอบ


6
หนึ่งในตัวอย่างเหล่านั้นที่สามารถแสดงความมหัศจรรย์ของการเขียนโปรแกรมการทำงานแม้กระทั่งสำหรับผู้เริ่มต้น
จอห์นนี่

2
ประสิทธิภาพของสิ่งนี้เปรียบเทียบกับ pre-java 8 method อย่างไร? การสำรวจเส้นทางไดเรกทอรีปัจจุบันของฉันช้าเกินไปและฉันกำลังค้นหาสิ่งที่จะเร่งความเร็ว
Sridhar Sarnobat

1
ฉันเขียนการทดสอบบางอย่างที่มีตัวแปรส่วนใหญ่ในคำตอบที่ให้ไว้ จนถึงตอนนี้ดูเหมือนว่าการใช้Files.walkกับกระแสข้อมูลแบบขนานที่ดีที่สุดตามมาด้วยFiles.walkFileTreeซึ่งจะช้าลงเพียงเล็กน้อยเท่านั้น คำตอบที่ได้รับการยอมรับโดยใช้คอมมอนส์ - io คือการทดสอบของฉันช้าที่สุดถึง 4 เท่า
Brett Ryan

1
@BrettRyan ผมพยายามแก้ปัญหาของคุณ Exception in thread "main" java.io.UncheckedIOException: java.nio.file.AccessDeniedExceptionแต่ฉันได้รับการยกเว้น ฉันจะแก้ไขให้ถูกต้องได้อย่างไร
Kachna

5
ฉันจะรับรายการไฟล์จริงจากสิ่งนี้ได้อย่างไร
yeliha

159

FileUtilsมีiterateFilesและlistFilesวิธีการ ลองพวกเขา (จากคอมมอนส์ - io )

แก้ไข: คุณสามารถตรวจสอบที่นี่สำหรับเกณฑ์มาตรฐานของวิธีการที่แตกต่างกัน ดูเหมือนว่าวิธีการคอมมอนส์ - io ช้าดังนั้นให้เลือกวิธีที่เร็วกว่าจากที่นี่ (ถ้ามันสำคัญ)


40
FYI / TLDR: หากคุณต้องการแสดงรายการไฟล์ทั้งหมดแบบเรียกซ้ำโดยไม่มีการกรองให้ทำFileUtils.listFiles(dir, TrueFileFilter.INSTANCE, TrueFileFilter.INSTANCE)ที่ใดdirคือวัตถุไฟล์ที่ชี้ไปยังไดเรกทอรีฐาน
andronikus

2
คุณอาจต้องการพิจารณาใช้listFilesAndDirs()เนื่องจากlistFiles()จะไม่ส่งคืนโฟลเดอร์ว่าง
schnatterer

1
@ MikeFHay ดูรหัส FileUtils ฉันคิดว่าคงเป็นFileUtils.listFiles(dir, true, true)เช่นนั้น ใช้FileUtils.listFiles(dir, null, true)จะโยนข้อยกเว้นในขณะที่FileUtils.listFiles(dir, true, null)จะแสดงรายการไฟล์ทั้งหมดโดยไม่ต้องดูในไดเรกทอรีย่อย
ocramot

ห้องสมุดพื้นเมืองของ JDK เป็นอย่างไร? ฉันสามารถใช้สิ่งนี้ได้ง่าย แต่ฉันจะเป็นแค่ C&P จากที่อื่น
Christian Bongiorno

1
ฉันกำลังทำการทดสอบกัน แต่จนถึงตอนนี้ดูเหมือนว่าจะทำงานได้ช้ากว่าการใช้ JDK8 หรือ JDK7 ทางเลือก 4 เท่า Symlinks ยังพิสูจน์ว่าเป็นปัญหาด้วยวิธีนี้โดยเฉพาะอย่างยิ่งที่พวกเขาเชื่อมโยงไปยังไดเรกทอรีที่สูงขึ้นในต้นไม้ซึ่งทำให้วิธีที่จะไม่กลับมานี้สามารถหลีกเลี่ยงได้โดยการจัดการตัวกรอง แต่โชคไม่ดีที่ symlink เอง ไฟล์.
Brett Ryan

138

// พร้อมที่จะวิ่ง

import java.io.File;

public class Filewalker {

    public void walk( String path ) {

        File root = new File( path );
        File[] list = root.listFiles();

        if (list == null) return;

        for ( File f : list ) {
            if ( f.isDirectory() ) {
                walk( f.getAbsolutePath() );
                System.out.println( "Dir:" + f.getAbsoluteFile() );
            }
            else {
                System.out.println( "File:" + f.getAbsoluteFile() );
            }
        }
    }

    public static void main(String[] args) {
        Filewalker fw = new Filewalker();
        fw.walk("c:\\" );
    }

}

9
เพียงแค่ระวังว่าสำหรับการเชื่อมโยงสัญลักษณ์ที่ชี้ไปที่เส้นทางที่สูงขึ้นในลำดับชั้นของเส้นทางจะทำให้วิธีการที่ไม่สิ้นสุด พิจารณาเส้นทางที่มี symlink -> .ที่ชี้ไปยัง
Brett Ryan

2
นี่เป็นเพียงการใช้งานที่ไม่ดีของ Files.walkFileTree ฉันขอแนะนำให้คนอื่นดู FIles.walkFileTree แทนที่จะพยายามม้วนมันด้วยตัวคุณเอง ... มันจัดการปัญหาที่แน่นอน @BrettRyan
Tyler Nichols

ขอบคุณสำหรับการรวมการนำเข้า java.io.File; ตัวอย่างจำนวนมากลืมที่จะรวมสิ่งที่เนมสเปซหรือแม้กระทั่งสิ่งที่ประเภทข้อมูลทำให้ตัวอย่างเป็นจุดเริ่มต้นในการเดินทางของการค้นพบ นี่คือตัวอย่างนี้พร้อมใช้งาน ขอบคุณ
barrypicker

พา ธ อาจแตกต่างกันไปขึ้นอยู่กับไฟล์ของ Filewalker การใช้งาน"/", "./"หรือ"../"ไดเรกทอรีรากไดเรกทอรีการทำงานปัจจุบันและไดเรกทอรีแม่ตามลำดับ
โมเสส Kirathe

67

Java 7 จะต้องมีFiles.walkFileTree :

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

ขณะนี้มีบทช่วยสอนของ Oracleทั้งหมดเกี่ยวกับคำถามนี้


และมันไม่เคยแจ้งให้ทราบเมื่อสิ้นสุดการเดิน
Farid

25

ไม่จำเป็นต้องใช้ไลบรารีภายนอก
ส่งกลับคอลเลกชันเพื่อให้คุณสามารถทำสิ่งที่คุณต้องการกับมันหลังจากการโทร

public static Collection<File> listFileTree(File dir) {
    Set<File> fileTree = new HashSet<File>();
    if(dir==null||dir.listFiles()==null){
        return fileTree;
    }
    for (File entry : dir.listFiles()) {
        if (entry.isFile()) fileTree.add(entry);
        else fileTree.addAll(listFileTree(entry));
    }
    return fileTree;
}

เรียบง่ายและสะอาด
Leo

17

ฉันจะไปกับสิ่งที่ชอบ:

public void list(File file) {
    System.out.println(file.getName());
    File[] children = file.listFiles();
    for (File child : children) {
        list(child);
    }
}

System.out.println อยู่ที่นั่นเพื่อระบุว่าจะทำอะไรกับไฟล์ ไม่จำเป็นต้องแยกความแตกต่างระหว่างไฟล์และไดเรกทอรีเนื่องจากไฟล์ปกติจะมีศูนย์ย่อย


6
จากเอกสารของlistFiles():“ ถ้าชื่อพา ธ นามธรรมนี้ไม่แสดงถึงไดเรกทอรีวิธีนี้จะส่งกลับnull
hfs

การปรับปรุงชุดพับลิกสาธารณะแบบผันแปร <File> listFileTree (ไฟล์ dir) {ถ้า (null == dir ||! dir.isDirectory ()) {return Collections.emptyList (); } ชุดสุดท้าย <File> fileTree = new HashSet <File> (); สำหรับ (รายการไฟล์: dir.listFiles ()) {if (entry.isFile ()) {fileTree.add (รายการ); } else {fileTree.addAll (listFileTree (รายการ)); }} คืน fileTree; }
Ben

สำหรับฉันนี่เป็นคำตอบที่กระชับที่สุดที่เรียกซ้ำ
WillieT

14

ฉันชอบใช้คิวมากกว่าการสอบถามซ้ำสำหรับการสำรวจแบบง่าย ๆ :

List<File> allFiles = new ArrayList<File>();
Queue<File> dirs = new LinkedList<File>();
dirs.add(new File("/start/dir/"));
while (!dirs.isEmpty()) {
  for (File f : dirs.poll().listFiles()) {
    if (f.isDirectory()) {
      dirs.add(f);
    } else if (f.isFile()) {
      allFiles.add(f);
    }
  }
}

แต่อัลกอริทึมของคุณไม่สามารถพิมพ์ด้วยเอาต์พุตที่เยื้อง ไฟล์และไฟล์ยุ่งเหยิง ทางออกใด ๆ
Wei

12

เพียงแค่เขียนมันเองโดยใช้การเรียกซ้ำง่าย ๆ :

public List<File> addFiles(List<File> files, File dir)
{
    if (files == null)
        files = new LinkedList<File>();

    if (!dir.isDirectory())
    {
        files.add(dir);
        return files;
    }

    for (File file : dir.listFiles())
        addFiles(files, file);
    return files;
}

1
กรุณา! ให้ผู้เรียกเริ่มต้นรายการไฟล์เพื่อไม่ต้องตรวจสอบค่าว่างในแต่ละครั้ง ถ้าคุณต้องการสร้างวิธีที่สอง (สาธารณะ) ที่สร้างรายการเรียกวิธีการภายในนี้และส่งกลับรายการทั้งหมด
helios

1
อะไรก็ตาม การตรวจสอบเป็นโมฆะไม่แพงมากความสะดวกสบาย + ความชอบส่วนตัวฉันคิดว่าเขาจะได้รับคะแนน
pstanton

คุณช่วยอธิบายเพิ่มเติมเล็กน้อยได้ไหม?
จันทร์ที่

8

ฉันคิดว่าสิ่งนี้ควรทำงาน:

File dir = new File(dirname);
String[] files = dir.list();

วิธีนี้คุณมีไฟล์และ dirs ตอนนี้ใช้การเรียกซ้ำและทำเช่นเดียวกันสำหรับ dirs ( FileคลาสมีisDirectory()เมธอด)


8

ด้วย Java 7 คุณสามารถใช้คลาสต่อไปนี้:

import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;

public class MyFileIterator extends SimpleFileVisitor<Path>
{
    public MyFileIterator(String path) throws Exception
    {
        Files.walkFileTree(Paths.get(path), this);
    }

    @Override
    public FileVisitResult visitFile(Path file,
            BasicFileAttributes attributes) throws IOException
    {
        System.out.println("File: " + file);
        return FileVisitResult.CONTINUE;
    }

    @Override
    public FileVisitResult preVisitDirectory(Path dir,
            BasicFileAttributes attributes) throws IOException
    {
        System.out.println("Dir: " + dir);
        return FileVisitResult.CONTINUE;
    }
}

7

ใน Java 8 ตอนนี้เราสามารถใช้ยูทิลิตี Files เพื่อเดินแผนผังไฟล์ ง่ายมาก.

Files.walk(root.toPath())
      .filter(path -> !Files.isDirectory(path))
      .forEach(path -> System.out.println(path));

7

รหัสนี้พร้อมที่จะเรียกใช้

public static void main(String... args) {
    File[] files = new File("D:/").listFiles();
    if (files != null) 
       getFiles(files);
}

public static void getFiles(File[] files) {
    for (File file : files) {
        if (file.isDirectory()) {
            getFiles(file.listFiles());
        } else {
            System.out.println("File: " + file);
        }
    }
}

4

นอกเหนือจากการสำรวจเส้นทางแบบวนซ้ำสามารถใช้วิธีการของผู้เยี่ยมชมได้เช่นกัน

โค้ดด้านล่างใช้วิธีตามผู้เยี่ยมชมสำหรับการสำรวจเส้นทางคาดว่าการป้อนข้อมูลไปยังโปรแกรมเป็นไดเรกทอรีรูทการสำรวจ

public interface Visitor {
    void visit(DirElement d);
    void visit(FileElement f);
}

public abstract class Element {
    protected File rootPath;
    abstract void accept(Visitor v);

    @Override
    public String toString() {
        return rootPath.getAbsolutePath();
    }
}

public class FileElement extends Element {
    FileElement(final String path) {
        rootPath = new File(path);
    }

    @Override
    void accept(final Visitor v) {
        v.visit(this);
    }
}

public class DirElement extends Element implements Iterable<Element> {
    private final List<Element> elemList;
    DirElement(final String path) {
        elemList = new ArrayList<Element>();
        rootPath = new File(path);
        for (File f : rootPath.listFiles()) {
            if (f.isDirectory()) {
                elemList.add(new DirElement(f.getAbsolutePath()));
            } else if (f.isFile()) {
                elemList.add(new FileElement(f.getAbsolutePath()));
            }
        }
    }

    @Override
    void accept(final Visitor v) {
        v.visit(this);
    }

    public Iterator<Element> iterator() {
        return elemList.iterator();
    }
}

public class ElementWalker {
    private final String rootDir;
    ElementWalker(final String dir) {
        rootDir = dir;
    }

    private void traverse() {
        Element d = new DirElement(rootDir);
        d.accept(new Walker());
    }

    public static void main(final String[] args) {
        ElementWalker t = new ElementWalker("C:\\temp");
        t.traverse();
    }

    private class Walker implements Visitor {
        public void visit(final DirElement d) {
            System.out.println(d);
            for(Element e:d) {
                e.accept(this);
            }
        }

        public void visit(final FileElement f) {
            System.out.println(f);
        }
    }
}

3

คุณสามารถใช้รหัสด้านล่างเพื่อรับรายการไฟล์ของโฟลเดอร์เฉพาะหรือไดเรกทอรีซ้ำ

public static void main(String args[]) {

        recusiveList("D:");

    }

    public static void recursiveList(String path) {

        File f = new File(path);
        File[] fl = f.listFiles();
        for (int i = 0; i < fl.length; i++) {
            if (fl[i].isDirectory() && !fl[i].isHidden()) {
                System.out.println(fl[i].getAbsolutePath());
                recusiveList(fl[i].getAbsolutePath());
            } else {
                System.out.println(fl[i].getName());
            }
        }
    }

2

คำตอบที่ได้รับการยอมรับเป็นสิ่งที่ดี แต่มันหยุดลงเมื่อคุณต้องการที่จะทำ IO ภายในแลมบ์ดา

นี่คือสิ่งที่คุณสามารถทำได้ถ้าการกระทำของคุณประกาศ IOExceptions

คุณสามารถปฏิบัติต่อสตรีมที่กรองเป็นIterableและจากนั้นดำเนินการของคุณในลูปปกติสำหรับแต่ละวง วิธีนี้คุณไม่ต้องจัดการกับข้อยกเว้นภายในแลมบ์ดา

try (Stream<Path> pathStream = Files.walk(Paths.get(path))
        .filter(Files::isRegularFile)) {

    for (Path file : (Iterable<Path>) pathStream::iterator) {
        // something that throws IOException
        Files.copy(file, System.out);
    }
}

พบเคล็ดลับที่นี่: https://stackoverflow.com/a/32668807/1207791


1

BFS แบบไม่เรียกซ้ำพร้อมรายการเดียว (ตัวอย่างที่เจาะจงคือการค้นหาไฟล์ * .eml):

    final FileFilter filter = new FileFilter() {
        @Override
        public boolean accept(File file) {
            return file.isDirectory() || file.getName().endsWith(".eml");
        }
    };

    // BFS recursive search
    List<File> queue = new LinkedList<File>();
    queue.addAll(Arrays.asList(dir.listFiles(filter)));

    for (ListIterator<File> itr = queue.listIterator(); itr.hasNext();) {
        File file = itr.next();
        if (file.isDirectory()) {
            itr.remove();
            for (File f: file.listFiles(filter)) itr.add(f);
        }
    }

1

รุ่นของฉัน (แน่นอนฉันสามารถใช้ built-in walk ใน Java 8 ;-)):

public static List<File> findFilesIn(File rootDir, Predicate<File> predicate) {
        ArrayList<File> collected = new ArrayList<>();
        walk(rootDir, predicate, collected);
        return collected;
    }

    private static void walk(File dir, Predicate<File> filterFunction, List<File> collected) {
        Stream.of(listOnlyWhenDirectory(dir))
                .forEach(file -> walk(file, filterFunction, addAndReturn(collected, file, filterFunction)));
    }

    private static File[] listOnlyWhenDirectory(File dir) {
        return dir.isDirectory() ? dir.listFiles() : new File[]{};
    }

    private static List<File> addAndReturn(List<File> files, File toAdd, Predicate<File> filterFunction) {
        if (filterFunction.test(toAdd)) {
            files.add(toAdd);
        }
        return files;
    }

1

นี่เป็นวิธีแก้ปัญหาที่เรียบง่าย แต่ใช้งานได้อย่างสมบูรณ์แบบโดยใช้recursion:

public static List<Path> listFiles(String rootDirectory)
{
    List<Path> files = new ArrayList<>();
    listFiles(rootDirectory, files);

    return files;
}

private static void listFiles(String path, List<Path> collectedFiles)
{
    File root = new File(path);
    File[] files = root.listFiles();

    if (files == null)
    {
        return;
    }

    for (File file : files)
    {
        if (file.isDirectory())
        {
            listFiles(file.getAbsolutePath(), collectedFiles);
        } else
        {
            collectedFiles.add(file.toPath());
        }
    }
}

1
    private void fillFilesRecursively(File file, List<File> resultFiles) {
        if (file.isFile()) {
            resultFiles.add(file);
        } else {
            for (File child : file.listFiles()) {
                fillFilesRecursively(child, resultFiles);
            }
        }
    }

1

ฉันมากับสิ่งนี้สำหรับการพิมพ์ไฟล์ / ชื่อไฟล์ทั้งหมดซ้ำ

private static void printAllFiles(String filePath,File folder) {
    if(filePath==null) {
        return;
    }
    File[] files = folder.listFiles();
    for(File element : files) {
        if(element.isDirectory()) {
            printAllFiles(filePath,element);
        } else {
            System.out.println(" FileName "+ element.getName());
        }
    }
}

0

ตัวอย่างเอาต์พุตไฟล์ * .csv ในไดเร็กทอรีการค้นหาแบบเรียกซ้ำไดเร็กทอรีย่อยโดยใช้ Files.find () จาก java.nio:

String path = "C:/Daten/ibiss/ferret/";
    logger.debug("Path:" + path);
    try (Stream<Path> fileList = Files.find(Paths.get(path), Integer.MAX_VALUE,
            (filePath, fileAttr) -> fileAttr.isRegularFile() && filePath.toString().endsWith("csv"))) {
        List<String> someThingNew = fileList.sorted().map(String::valueOf).collect(Collectors.toList());
        for (String t : someThingNew) {
            t.toString();
            logger.debug("Filename:" + t);
        }

    }

การโพสต์ตัวอย่างนี้เนื่องจากฉันมีปัญหาในการทำความเข้าใจวิธีส่งพารามิเตอร์ชื่อไฟล์ในตัวอย่าง # 1 ที่ได้รับจาก Bryan โดยใช้ foreach ใน Stream-result -

หวังว่านี่จะช่วยได้


0

Kotlin มีFileTreeWalkจุดประสงค์นี้ ตัวอย่างเช่น:

dataDir.walkTopDown().filter { !it.isDirectory }.joinToString("\n") {
   "${it.toRelativeString(dataDir)}: ${it.length()}"
}

จะสร้างรายการข้อความของไฟล์ที่ไม่ใช่ไดเร็กทอรีทั้งหมดภายใต้รูทที่กำหนดหนึ่งไฟล์ต่อบรรทัดที่มีพา ธ ที่สัมพันธ์กับรูทและความยาว


0

อีกวิธีหนึ่งที่คุณสามารถทำได้แม้ว่าจะมีใครให้ Java 8 walk

ไฟล์นี้จะให้ไฟล์ทั้งหมดซ้ำ

  private Stream<File> files(File file) {
    return file.isDirectory()
            ? Arrays.stream(file.listFiles()).flatMap(this::files)
            : Stream.of(file);
}

-1

ตามคำตอบ stacker นี่คือโซลูชันที่ทำงานใน JSP โดยไม่มีไลบรารีภายนอกดังนั้นคุณจึงสามารถวางมันไว้เกือบทุกที่บนเซิร์ฟเวอร์ของคุณ:

<!DOCTYPE html>
<%@ page session="false" %>
<%@ page import="java.util.*" %>
<%@ page import="java.io.*" %>
<%@ page contentType="text/html; charset=UTF-8" %>

<%!
    public List<String> files = new ArrayList<String>();
    /**
        Fills files array with all sub-files.
    */
    public void walk( File root ) {
        File[] list = root.listFiles();

        if (list == null) return;

        for ( File f : list ) {
            if ( f.isDirectory() ) {
                walk( f );
            }
            else {
                files.add(f.getAbsolutePath());
            }
        }
    }
%>
<%
    files.clear();
    File jsp = new File(request.getRealPath(request.getServletPath()));
    File dir = jsp.getParentFile();
    walk(dir);
    String prefixPath = dir.getAbsolutePath() + "/";
%>

จากนั้นคุณก็ทำสิ่งที่ชอบ:

    <ul>
        <% for (String file : files) { %>
            <% if (file.matches(".+\\.(apk|ipa|mobileprovision)")) { %>
                <li><%=file.replace(prefixPath, "")%></li>
            <% } %>
        <% } %>
    </ul>

1
แม้ว่ามันอาจใช้งานได้ แต่คำถามเกี่ยวกับการเรียกดูไฟล์ไม่ใช่การแสดงผลไฟล์ที่เรียกดู ดีกว่าเปิดเผยอัลกอริทึมของคุณเช่นนี้ไม่ใช่วิธีปฏิบัติที่แนะนำในการฝังตรรกะทางธุรกิจภายใน JSP
ซามูเอลเคอร์รีน

ขึ้นอยู่กับว่าคุณกำลังทำอะไร ในแอปพลิเคชันขนาดองค์กรคุณมีสิทธิ์อย่างแท้จริง หากคุณต้องการเพียงสิ่งนี้ในการส่งไปยังรายชื่อแบบสแตนด์อโลนที่เรียบง่ายนี่เป็นสิ่งที่ดีมาก
Nux
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.