Java 如何删除同名但扩展名不同的重复文件?

Java 如何删除同名但扩展名不同的重复文件?,java,duplicates,Java,Duplicates,我在一个目录中有大量的图像。一些图像的问题在于,它们具有相同名称但不同扩展名的副本,例如image1.jpg、image1.jpg、image1.png,它们都是相同的图像,名称相同但扩展名不同。如何使用Java查找和删除这些重复项?有很多工具可以找到副本,但我找不到任何工具或脚本来解决这个特定问题。任何帮助都将不胜感激 将所有文件读入某种类型的列表中: List<File> filesInFolder = Files.walk(Paths.get("\\path\\to\\fold

我在一个目录中有大量的图像。一些图像的问题在于,它们具有相同名称但不同扩展名的副本,例如image1.jpg、image1.jpg、image1.png,它们都是相同的图像,名称相同但扩展名不同。如何使用Java查找和删除这些重复项?有很多工具可以找到副本,但我找不到任何工具或脚本来解决这个特定问题。任何帮助都将不胜感激

将所有文件读入某种类型的
列表中:

List<File> filesInFolder = Files.walk(Paths.get("\\path\\to\\folder"))
        .filter(Files::isRegularFile)
        .map(Path::toFile)
        .collect(Collectors.toList());

您可以根据自己的具体需要进行调整。

imho实现这一点的唯一方法是创建一个助手类:

    public class FileUtil {
    String fileName;
    File file;
    boolean delete = true;


    public FileUtil(String fileName, File file) {
        super();
        this.fileName = fileName.substring(0, fileName.indexOf("."));
        this.file = file;
    }

    public String getFileName() {
        return fileName;
    }
    public void setFileName(String fileName) {
        this.fileName = fileName;
    }
    public File getFile() {
        return file;
    }
    public void setFile(File file) {
        this.file = file;
    }
    public boolean isDelete() {
        return delete;
    }
    public void setDelete(boolean delete) {
        this.delete = delete;
    }

    @Override
    public String toString() {
        return "FileUtil [fileName=" + fileName + ", file=" + file + ", delete=" + delete + "]";
    }

}
然后,您可以使用此选项收集和删除您的项目:

try (Stream<Path> paths = Files.walk(Paths.get("c:/yourPath/"))) {
        List<FileUtil> listUtil = new ArrayList<FileUtil>();

        paths
            .filter(Files::isRegularFile)
            .map(filePath -> filePath.toFile())
            .collect(Collectors.toList())
            .forEach(file -> listUtil.add(new FileUtil(file.getName(), file)));

        Map<String, List<FileUtil>> collect = listUtil.stream()
                .collect(Collectors.groupingBy(FileUtil::getFileName));

        for(String key : collect.keySet() ) {
            List<FileUtil> list = collect.get(key);
            if(list.size() > 1) {
                list.stream().findFirst().ifPresent(f -> f.setDelete(false));

                list.stream()
                    .filter(fileUtil -> fileUtil.isDelete())
                    .forEach(fileUtil -> fileUtil.getFile().delete());
            }
        }


    } catch (IOException e) {
        e.printStackTrace();
    } 
try(Stream path=Files.walk(path.get(“c:/yourPath/”)){
List listUtil=new ArrayList();
路径
.filter(文件::isRegularFile)
.map(文件路径->文件路径.toFile())
.collect(收集器.toList())
.forEach(file->listUtil.add(newfileutil(file.getName(),file)));
Map collect=listUtil.stream()
.collect(Collectors.groupingBy(FileUtil::getFileName));
for(字符串键:collect.keySet()){
列表=collect.get(键);
如果(list.size()>1){
list.stream().findFirst().ifPresent(f->f.setDelete(false));
list.stream()
.filter(fileUtil->fileUtil.isDelete())
.forEach(fileUtil->fileUtil.getFile().delete());
}
}
}捕获(IOE异常){
e、 printStackTrace();
} 
通过这种方式,我保留了一个随机项,如果您愿意,您可以修改该类以仅保留您想要的扩展名,例如.png

我希望这有帮助:)

这里是: 本例实现了一个
,通过仅提供包含图像的文件夹/目录的路径来自动删除重复图像(显示其他可用选项以及如何利用Java中的OO功能的不同想法)


您确定此代码不会删除所有扩展名为.jpeg的文件吗?事实上,每个.jpeg文件都不是重复的,只有一些是重复的。但是,当我想删除jpeg并保留jpg副本时,程序会删除jpg文件而保留jpeg。如何实现这一点?您可以修改最后一部分,
list.stream().findFirst().ifPresent(f->f.setDelete(false)),并根据您的需要进行编辑。在这里,您可以“标记”要删除的文件。您可以很容易地更改逻辑,其中只有一些文件是重复的,这使得手动查找和删除它们非常繁琐,每个文件都不是重复的(可能是误解导致了对该问题的否决票)。您提供的脚本将按照文件类型对目录中的文件进行排序,选择并删除所有jpg图像。我甚至不需要一个java程序,手动操作非常简单。这段代码将删除所有没有以jpg结尾的代码。我同意手动操作很容易,除非您有500k文件,否则手动操作会成为一个问题。所以,您要查找具有相同名称和不同扩展名的所有文件,并且只保留其中一个,是吗?如果是这样,那是哪一个?好的,我会保留以jpg结尾的文件,删除以jpeg结尾的文件。我没有时间写代码答案,所以只要找到所有与另一个文件同名的文件(不包括扩展名)并将其放入新列表中即可。然后使用新列表中我的答案中的流。如果你被卡住了,我以后可能会写一个答案。使用
Set
Override
方法
equals()
提供你自己的逻辑。。一旦你找到一个重复的,删除它!
try (Stream<Path> paths = Files.walk(Paths.get("c:/yourPath/"))) {
        List<FileUtil> listUtil = new ArrayList<FileUtil>();

        paths
            .filter(Files::isRegularFile)
            .map(filePath -> filePath.toFile())
            .collect(Collectors.toList())
            .forEach(file -> listUtil.add(new FileUtil(file.getName(), file)));

        Map<String, List<FileUtil>> collect = listUtil.stream()
                .collect(Collectors.groupingBy(FileUtil::getFileName));

        for(String key : collect.keySet() ) {
            List<FileUtil> list = collect.get(key);
            if(list.size() > 1) {
                list.stream().findFirst().ifPresent(f -> f.setDelete(false));

                list.stream()
                    .filter(fileUtil -> fileUtil.isDelete())
                    .forEach(fileUtil -> fileUtil.getFile().delete());
            }
        }


    } catch (IOException e) {
        e.printStackTrace();
    } 
import java.io.File;
import java.util.HashSet;
import java.util.Set;

public class DuplicateRemover {

    // inner class to represent an image
    class Image{
        String path; // the absolute path of image file as a String

        // constructor
        public Image(String path) {
            this.path = path;
        }       

        @Override
        public boolean equals(Object o) {
            if(o instanceof Image){
                // if both base names are equal -> delete the old one
                if(getBaseName(this.path).equals(getBaseName(((Image)o).path))){
                    File file = new File(this.path);
                    return file.delete();
                }
            }
            return false;
        }

        @Override
        public int hashCode() {
            return 0; // in this case, only "equals()" method is considered for duplicate check
         } 

         /**
          * This method to get the Base name of the image from the path
          * @param fileName
          * @return
          */
        private String getBaseName(String fileName) {
            int index = fileName.lastIndexOf('.'); 
            if (index == -1) { return fileName; } 
            else { return fileName.substring(0, index); }
         }
    }


    Set<Image> images; // a set of image files

    //constructor
    public DuplicateRemover(){
        images = new HashSet<>();
    } 

    /**
     * Get the all the images from the given folder
     * and loop through all files to add them to the images set
     * @param dirPath
     */
    public void run(String dirPath){
        File dir = new File(dirPath);
        File[] listOfImages = dir.listFiles(); 
        for (File f : listOfImages){
            if (f.isFile()) { 
                images.add(new Image(f.getAbsolutePath()));
            }
        }
    }


    //TEST
    public static void main(String[] args) {
        String dirPath = "C:\\Users\\Yahya Almardeny\\Desktop\\folder";
        /* dir contains: {image1.png, image1.jpeg, image1.jpg, image2.png}       */
        DuplicateRemover dr = new DuplicateRemover();
        // the images set will delete any duplicate image from the folder
        // according to the logic we provided in the "equals()" method
        dr.run(dirPath); 

        // print what images left in the folder
        for(Image image : dr.images) {
            System.out.println(image.path);
        }

        //Note that you can use the set for further manipulation if you have in later
    }

}
C:\Users\Yahya Almardeny\Desktop\folder\image1.jpeg
C:\Users\Yahya Almardeny\Desktop\folder\image2.png