栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

20220626Java 获取本地win10照片信息分辨率检查损坏图片移动删除文件

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

20220626Java 获取本地win10照片信息分辨率检查损坏图片移动删除文件

文本仅为了,日常记录操作记录步骤,方便后期使用能找到

涉及:

读取本地文件夹目录信息,文件信息

校验图片文件是否损坏   ImageReader

文件的移动  file.renameTo()

文件的删除  file.delete()

写文件保存到本地  FileWriter

背景:

使用了10多年电脑,各种出去游玩拍的照片图片,10W+以上,常年累月换了多台电脑,文件拷过来拷过去,近期发现部分图片文件损坏了,无法打开。本文记录获取图片信息,校验文件是否损坏,移动损坏文件到指定文件夹,删除损坏文件。

步骤:

获取图片信息:文件名称,上一级文件夹,文件后缀格式,文件创建时间,文件大小zise,文件分辨率(宽x高),校验文件是否损坏,移动损坏文件到指定文件夹,删除损坏文件

获取图片信息:

  File dirFile = new File(filepath);
//            当前路径下的所有文件夹、文件存放到一个文件数组
//        System.out.println(Dir(dirFile));
        //获取文件路径存放到一个数据中 文件绝对路径
        DirAll(dirFile);


// 设置一个全局动态数组,来存放文件路径
// 主要遍历文件夹,包含所有子文件夹、文件的情况时,用到递归,所以要这样设置
public static ArrayList dirAllStrArr = new ArrayList<>();

public static void DirAll(File dirFile) {
    if (dirFile.exists()) {
        File[] files = dirFile.listFiles();
        if (files != null) {
            for (File file : files) {
                // 如果遇到文件夹则递归调用。
                if (file.isDirectory()) {
                    // 递归调用
                    DirAll(file);
                } else {
                    // 如果遇到文件夹则放入数组
                    if (dirFile.getPath().endsWith(File.separator)) {
                        dirAllStrArr.add(dirFile.getPath() + file.getName());
                    } else {
                        dirAllStrArr.add(dirFile.getPath() + File.separator
                                + file.getName());
                    }
                }
            }
        }
    }
}

获取图片尺寸分辨率

方法1--最简单 支持常见图片格式

//获取本地图片大小(尺寸)

File picture=new File(s);

BufferedImage sourceImg= null;

try {

sourceImg = ImageIO.read(new FileInputStream(picture));

obj.put("Width",sourceImg.getWidth());

obj.put("Height",sourceImg.getHeight());

} catch (IOException e) {

e.printStackTrace();

}

方法2 支持常见图片格式

getImageSizeByBufferedImage(s);


public static void getImageSizeByBufferedImage(String src) {
    long beginTime = new Date().getTime();
    File file = new File(src);
    FileInputStream is = null;
    try {
        is = new FileInputStream(file);
    }
    catch (FileNotFoundException e2) {
        e2.printStackTrace();
    }
    BufferedImage sourceImg = null;
    try {
        sourceImg = javax.imageio.ImageIO.read(is);
        System.out.println("width:" + sourceImg.getWidth());
        System.out.println("height:" + sourceImg.getHeight());
    }
    catch (IOException e1) {
        e1.printStackTrace();
    }
    long endTime = new Date().getTime();
    System.out.println("使用[BufferedImage]获取图片尺寸耗时:[" + (endTime - beginTime)+"]ms");
}

方法3 只支持jpg格式其他图片格式报错


public static void getImageSizeByImageReader(String src) {
    long beginTime = new Date().getTime();
    File file = new File(src);
    try {
        Iterator readers = ImageIO.getImageReadersByFormatName("jpg");
        ImageReader reader = (ImageReader) readers.next();
        ImageInputStream iis = ImageIO.createImageInputStream(file);
        reader.setInput(iis, true);

        System.out.println("width:" + reader.getWidth(0));
        System.out.println("height:" + reader.getHeight(0));
    }
    catch (IOException e) {
        e.printStackTrace();
    }
    long endTime = new Date().getTime();
    System.out.println("使用[ImageReader]获取图片尺寸耗时:[" + (endTime - beginTime)+"]ms");
}

获取图片是否损坏 true-正常,false-损坏

实际使用后总结记录:

.web、.png、格式,不支持。正常文件会误判为 false--损坏,需人工手动判断删除文件。

其他非图片格式不支持,zip,doc,rar,mp4等非图片格式会误判为 false--损坏


public static boolean verifyImage(InputStream inputStream) {
    try (ImageInputStream iis = ImageIO.createImageInputStream(inputStream)) {
        Iterator iter = ImageIO.getImageReaders(iis);
        if (!iter.hasNext()) {
            System.out.print("No readers found!");
            return false;
        }
        ImageReader reader = iter.next();
        reader.setInput(iis, true);
        int width = reader.getWidth(0);
        //读取完整文件,速度太慢
        //BufferedImage image = ImageIO.read(inputStream);
        //int width = image.getWidth();
        return true;
    } catch (Exception e) {
        System.out.print(e.getMessage());
        return false;
    }
}

删除损坏文件--小心使用 删除文件回收站找不到 不可恢复

删除文件前需先关闭文件流,否则文件删除失败

 private static void badFileDelete(String deFilename) {

        File file = new File(deFilename);

        if (file.delete()) {

            System.out.println("删除成功!");

        } else {

            System.out.println("删除失败!");

        }

    }

移动损坏文件

检测损坏的文件到 error暂存文件夹,手动确认是否删除文件,查看具体哪些文件图片损坏了

 //移动损坏文件 代替删除文件,后面手动确认是否删除文件
//    startPath ---当前文件 完整路径
//    endPath---移动后文件夹


    private static void moveDadFileTolocal(String startPath, String endPath, String fileName) {
//        File.separator 的作用相当于 ' '。1、在window中的分隔符是 

        String filePath = startPath;//原始文件名称
        String newendPath = endPath + "\" + fileName;//新文件名称
//        System.out.println(filePath);
//        System.out.println(newendPath);
        File file = new File(filePath);
        //方法一
//        boolean b = file.renameTo(new File(newendPath));
//        System.out.println(b);
        //方法2 使用apache的FileUtils工具
        try {
            FileUtils.moveFile(file, new File(newendPath));
            System.out.println("success");
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

执行结果:

False--文件损坏,success--文件移动到 error文件夹成功

 

 损坏文件信息保存到本地:

//文件量较大 损坏的文件信息 保存到本地 txt文件中 Content 写入的内容 filepath 保存文件路径
String txtfilepath = "D:\testfile\20220623photossize\20220626图片文件信息.txt";
boolean b = filechaseWrite(arr.toString(), txtfilepath);


public static boolean filechaseWrite(String Content, String filepath) {
    boolean flag = false;
    try {
        FileWriter fw = new FileWriter(filepath, true);
        fw.write(Content);
        fw.flush();
        fw.close();
        flag = true;
    } catch (Exception e) {
        // e.printStackTrace();
    }
    return flag;
}

 损坏的文件 共计337张图片文件损坏

完整代码:

package main;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.io.FileUtils;

import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Iterator;

public class readFilePhotosSize2 {
    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        //1、读取指定目录下所有文件夹及文件文成
        //2、所有文件名称和后缀名

        //20220626 新增多线程处理数据
        String filepath;
        filepath = "D:\testfile\20220623photossize";
 
        //读取指定目录下文件信息 包含文件名称 文件路径
        String renameInfo = readFilepathInfo(filepath);

        useTime(start);//耗时
    }

    //读取指定目录下文件信息 包含文件名称 文件路径
    private static String readFilepathInfo(String filepath) {
        File dirFile = new File(filepath);
//            当前路径下的所有文件夹、文件存放到一个文件数组
//        System.out.println(Dir(dirFile));
        //获取文件路径存放到一个数据中 文件绝对路径
        DirAll(dirFile);

//        System.out.println(dirAllStrArr);
        //记录成功失败数量
        int s_num = 0;
        int allFileTotal = dirAllStrArr.size();
        System.out.println(allFileTotal);
        //解析数组获取所有文件的路径
        System.out.println("=============解析数组获取所有文件的路径====================");
//        for (int i = 0; i < dirAllStrArr.size(); i++) {
        JSONArray arr = new JSONArray();
        JSONObject obj = null;//存放损坏的图片信息
        for (String s : dirAllStrArr) {
            s_num++;
//            if (s_num == 100) {
//                break;
//            }
            obj = new JSONObject();
            File f = new File(s);
            String folder_Fullname = f.getParent();
            String folder_name = folder_Fullname.substring(folder_Fullname.lastIndexOf("\") + 1);
            //修改文件名称 新文件名称规则:上一级目录名称+文件名称
            //获取文件名称 文件名称 后缀名
            String file_Fullname = s.substring(s.lastIndexOf("\") + 1);
            String file_name = file_Fullname.substring(0, file_Fullname.lastIndexOf("."));
            String file_lastname = s.substring(s.lastIndexOf(".") + 1);

            //修改名称后新文件名称(上一级目录名称+文件名称)    新文件路径
            String file_newName = folder_name + file_Fullname;
            String file_newFullName = folder_Fullname + "\" + folder_name + file_Fullname;

            System.out.println("共计:" + allFileTotal + ",第:" + s_num + ",文件名称:" + file_Fullname);

//            System.out.println("文件完整路径 fileFullname:" + s);
//            System.out.println("文件完整名称 file_Fullname:" + file_Fullname);
//            获取本地图片大小(尺寸)

            try {
                InputStream in = new FileInputStream(s);
                boolean phflag = verifyImage(in);// true--正常  false --损坏
                obj.put("phflag", phflag);
                System.out.println(phflag);
                if (!phflag) {
                    obj.put("fileFullname", s);
                    obj.put("file_Fullname", file_Fullname);

                    arr.add(obj);
                    in.close();

                    String endPath = "D:\testfile\20220623photossize\errorphotos";//移动到指定文件夹
                    String filename = s_num+file_Fullname;//防止文件名称重复 新文件名称加序号
                    moveDadFileTolocal(s, endPath, filename);//移动损坏文件 代替删除文件,后面手动确认是否删除文件


                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
//        System.out.print(arr);
        //文件量较大 损坏的文件信息 保存到本地 txt文件中 Content 写入的内容 filepath 保存文件路径
        String txtfilepath = "D:\testfile\20220623photossize\20220626图片文件信息.txt";
        boolean b = filechaseWrite(arr.toString(), txtfilepath);
        System.out.println("损坏图片信息是否成功保存到本地:" + b);
        return "执行完成";
    }
    //移动损坏文件 代替删除文件,后面手动确认是否删除文件
//    startPath ---当前文件 完整路径
//    endPath---移动后文件夹


    private static void moveDadFileTolocal(String startPath, String endPath, String fileName) {
//        File.separator 的作用相当于 ' '。1、在window中的分隔符是 

        String filePath = startPath;//原始文件名称
        String newendPath = endPath + "\" + fileName;//新文件名称
//        System.out.println(filePath);
//        System.out.println(newendPath);
        File file = new File(filePath);
        //方法一
//        boolean b = file.renameTo(new File(newendPath));
//        System.out.println(b);
        //方法2 使用apache的FileUtils工具
        try {
            FileUtils.moveFile(file, new File(newendPath));
            System.out.println("success");
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    private static void badFileDelete(String deFilename) {
        File file = new File(deFilename);
        if (file.delete()) {
            System.out.println("删除成功!");
        } else {
            System.out.println("删除失败!");
        }

    }

    //    检查文件是否存在
    private static void checkFileExists(String filename) {
        File file = new File(filename);
        //判断文件是否存在
        if (file.exists()) {
            System.out.println("文件已经存在,无需再次创建!");
        } else {
            System.out.println("文件创建失败!");
        }
    }

    
    public static void getImageSizeByBufferedImage(String src) {
        long beginTime = new Date().getTime();
        File file = new File(src);
        FileInputStream is = null;
        try {
            is = new FileInputStream(file);
        } catch (FileNotFoundException e2) {
            e2.printStackTrace();
        }
        BufferedImage sourceImg = null;
        try {
            sourceImg = ImageIO.read(is);
            System.out.println("width:" + sourceImg.getWidth());
            System.out.println("height:" + sourceImg.getHeight());
        } catch (IOException e1) {
            e1.printStackTrace();
        }
        long endTime = new Date().getTime();
        System.out.println("使用[BufferedImage]获取图片尺寸耗时:[" + (endTime - beginTime) + "]ms");
    }

    
    public static void getImageSizeByImageReader(String src) {
        long beginTime = new Date().getTime();
        File file = new File(src);
        try {
            Iterator readers = ImageIO.getImageReadersByFormatName("jpg");
            ImageReader reader = (ImageReader) readers.next();
            ImageInputStream iis = ImageIO.createImageInputStream(file);
            reader.setInput(iis, true);

            System.out.println("width:" + reader.getWidth(0));
            System.out.println("height:" + reader.getHeight(0));
        } catch (IOException e) {
            e.printStackTrace();
        }
        long endTime = new Date().getTime();
        System.out.println("使用[ImageReader]获取图片尺寸耗时:[" + (endTime - beginTime) + "]ms");
    }

    
    public static boolean verifyImage(InputStream inputStream) {
        try (ImageInputStream iis = ImageIO.createImageInputStream(inputStream)) {
            Iterator iter = ImageIO.getImageReaders(iis);
            if (!iter.hasNext()) {
                System.out.print("No readers found!");
                return false;
            }
            ImageReader reader = iter.next();
            reader.setInput(iis, true);
            int width = reader.getWidth(0);
            //读取完整文件,速度太慢
            //BufferedImage image = ImageIO.read(inputStream);
            //int width = image.getWidth();
            return true;
        } catch (Exception e) {
            System.out.print(e.getMessage());
            return false;
        }
    }

    // 设置一个全局动态数组,来存放文件路径
    // 主要遍历文件夹,包含所有子文件夹、文件的情况时,用到递归,所以要这样设置
    public static ArrayList dirAllStrArr = new ArrayList<>();

    public static void DirAll(File dirFile) {
        if (dirFile.exists()) {
            File[] files = dirFile.listFiles();
            if (files != null) {
                for (File file : files) {
                    // 如果遇到文件夹则递归调用。
                    if (file.isDirectory()) {
                        // 递归调用
                        DirAll(file);
                    } else {
                        // 如果遇到文件夹则放入数组
                        if (dirFile.getPath().endsWith(File.separator)) {
                            dirAllStrArr.add(dirFile.getPath() + file.getName());
                        } else {
                            dirAllStrArr.add(dirFile.getPath() + File.separator
                                    + file.getName());
                        }
                    }
                }
            }
        }
    }


    public static ArrayList Dir(File dirFile) {
        ArrayList dirStrArr = new ArrayList<>();
        if (dirFile.exists()) {
            // 直接取出利用listFiles()把当前路径下的所有文件夹、文件存放到一个文件数组
            File[] files = dirFile.listFiles();
            if (files != null) {
                for (File file : files) {
                    // 如果传递过来的参数dirFile是以文件分隔符,也就是/或者结尾,则如此构造
                    if (dirFile.getPath().endsWith(File.separator)) {
                        dirStrArr.add(dirFile.getPath() + file.getName());
                    } else {
                        // 否则,如果没有文件分隔符,则补上一个文件分隔符,再加上文件名,才是路径
                        dirStrArr.add(dirFile.getPath() + File.separator
                                + file.getName());
                    }
                }
            }
        }
        return dirStrArr;
    }

    //    getAllFileName (String path, ArrayList fileName)是包括当前文件及其子文件的文件名。
    private static void testGetfilename2(String filepath) {
        ArrayList listFileName = new ArrayList<>();
        getAllFileName(filepath, listFileName);
        for (String name : listFileName) {
            System.out.println(name);
        }
    }

    public static void getAllFileName(String path, ArrayList fileName) {
        File file = new File(path);
        File[] files = file.listFiles();
        String[] names = file.list();
        if (names != null)
            fileName.addAll(Arrays.asList(names));
        if (files != null) {
            for (File a : files) {
                if (a.isDirectory()) {
                    getAllFileName(a.getAbsolutePath(), fileName);
                }
            }
        }
    }
    //计算执行耗时
    private static void useTime(long start) {
        long finish = System.currentTimeMillis();
        long timeElapsed = finish - start;
        System.out.println("耗时:" + timeElapsed + ",耗时:" + timeElapsed / 1000F + "秒");
    }

    
    public static boolean filechaseWrite(String Content, String filepath) {
        boolean flag = false;
        try {
            FileWriter fw = new FileWriter(filepath, true);
            fw.write(Content);
            fw.flush();
            fw.close();
            flag = true;
        } catch (Exception e) {
            //
            e.printStackTrace();
        }
        return flag;
    }
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/995837.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号