文本仅为了,日常记录操作记录步骤,方便后期使用能找到
涉及:
读取本地文件夹目录信息,文件信息
校验图片文件是否损坏 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
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
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
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
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
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
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
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
private static void testGetfilename2(String filepath) {
ArrayList
getAllFileName(filepath, listFileName);
for (String name : listFileName) {
System.out.println(name);
}
}
public static void getAllFileName(String path, ArrayList
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;
}
}



