java
复制代码
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.PosixFilePermission;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
/**
* 文件工具类
* FileUtils
*
* @author glj
* @version 1.0, 2015-3-9
*/
@Slf4j
public class FileUtil {
/**
* 获取文件扩展名
*
* @param fileName 文件名称
* @return
*/
public static String getExtensionName(String fileName) {
if ((fileName != null) && (fileName.length() > 0)) {
int dot = fileName.lastIndexOf('.');
if ((dot > -1) && (dot < (fileName.length() - 1))) {
return fileName.substring(dot + 1);
}
}
return fileName;
}
/**
* 获取不带扩展名的文件名称
*
* @param fileName 文件名称
* @return
*/
public static String getFileNameNoExt(String fileName) {
if ((fileName != null) && (fileName.length() > 0)) {
int dot = fileName.lastIndexOf('.');
if ((dot > -1) && (dot < (fileName.length()))) {
return fileName.substring(0, dot);
}
}
return fileName;
}
/**
* 根据输入流来保存文件信息
*
* @param inputStream 文件输入流
* @param localBasePath 目录
* @param fileName 文件名称
* @return 文件对象
*/
public static File saveFileFromInputStream(InputStream inputStream, String localBasePath, String fileName) throws IOException {
File dir = new File(localBasePath);
if (!dir.exists()) {
boolean dirs = dir.mkdirs();
}
File file = new File(localBasePath + File.separator + fileName);
if (!file.exists()) {
boolean newFile = file.createNewFile();
}
try (FileOutputStream fs = new FileOutputStream(file)) {
byte[] buffer = new byte[1024 * 1024];
int num;
while ((num = inputStream.read(buffer)) != -1) {
fs.write(buffer, 0, num);
fs.flush();
}
} finally {
inputStream.close();
}
return file;
}
/**
* 上传文件
*
* @param stream 文件数据流
* @param filePath 服务器上文件路径
* @return
* @throws IOException
*/
public static boolean uploadFile(InputStream stream, String filePath) throws IOException {
File file = new File(filePath);
//验证所选路径是否存在,不存在,先创建路径
String localBasePath = file.getParentFile().getPath();
File dir = new File(localBasePath);
if (!dir.exists()) {
dir.mkdirs();
}
if (!file.exists()) {
file.createNewFile();
}
FileOutputStream fs = new FileOutputStream(file);
byte[] buffer = new byte[1024 * 1024];
int byteread = 0;
while ((byteread = stream.read(buffer)) != -1) {
fs.write(buffer, 0, byteread);
fs.flush();
}
fs.close();
stream.close();
if (file.exists()) {
return true;
} else {
return false;
}
}
/**
* 删除文件
*
* @param filePath 文件路径
* @return
* @throws IOException
*/
public static boolean removeFile(String filePath) throws IOException {
File file = new File(filePath);
//判断文件是否存在
if (file.exists()) {
//如果存在,则删除该文件
return file.delete();
} else {
//文件不存在,则返回false
return false;
}
}
//删除非任务上传文件夹下面的数据
public static void deleteFile(File oldPath) {
if (oldPath.isDirectory()) {
File[] files = oldPath.listFiles();
for (File file : files) {
deleteFile(file);
}
oldPath.delete();
} else {
oldPath.delete();
}
}
/**
* zipFile
* 将指定文件进行ZIP格式压缩
*
* @param zipFilesPath 带压缩的文件路径列表
* @param fileName 压缩成的目标文件路径
* @return 返回压缩后的文件路径
* @throws IOException 压缩过程中的IO异常
*/
public static String zipFile(List<String> zipFilesPath, String fileName)
throws IOException {
ZipOutputStream zos = new ZipOutputStream(
Files.newOutputStream(Paths.get(fileName)));
ZipEntry ze = null;
byte[] buf = new byte[1024];
int readln = -1;
for (int i = 0; i < zipFilesPath.size(); i++) {
ze = new ZipEntry(zipFilesPath.get(i));
ze.setSize(new File(zipFilesPath.get(i)).length());
ze.setTime(new File(zipFilesPath.get(i)).lastModified());
zos.putNextEntry(ze);
InputStream is = new BufferedInputStream(Files.newInputStream(Paths.get(zipFilesPath.get(i))));
while ((readln = is.read(buf, 0, 1024)) != -1) {
zos.write(buf, 0, 1024);
}
is.close();
}
zos.close();
return fileName;
}
/**
* 复制文件到指定位置
*
* @param sourceFileFullPath 要复制的文件全路径 如D://test//test.txt
* @param targetFileFullPath 复制到目标文件全路径 如D://move//test.txt
* @return 是否复制成功, true:成功;否则失败
*/
public static boolean copyFileToTarget(String sourceFileFullPath, String targetFileFullPath) {
try {
FileUtils.copyFile(new File(sourceFileFullPath), new File(targetFileFullPath));
return true;
} catch (IOException e) {
log.error("copyFileToTarget={}", e.getMessage());
}
return false;
}
/**
* 复制文件夹到指定位置
*
* @param sourceFileFullPath 要复制的文件全路径
* @param targetFileFullPath 复制到目标位置的目录全路径
* @return 是否复制成功, true:成功;否则失败
*/
public static boolean copyDirectoryToTarget(String sourceFileFullPath, String targetFileFullPath) {
try {
FileUtils.copyDirectory(new File(sourceFileFullPath), new File(targetFileFullPath));
return true;
} catch (IOException e) {
System.out.println(e.getMessage());
}
return false;
}
/**
* 移动文件到指定位置
*
* @param sourceFileFullPath 要移动的文件全路径
* @param targetFileFullPath 移动文件到目标位置的目录全路径
* @return 是否复制成功, true:成功;否则失败
*/
public static boolean moveFileToTarget(String sourceFileFullPath, String targetFileFullPath) {
try {
FileUtils.moveFile(new File(sourceFileFullPath), new File(targetFileFullPath));
return true;
} catch (IOException e) {
System.out.println(e.getMessage());
}
return false;
}
/**
* 移动文件夹到指定位置
*
* @param sourceFileFullPath 要移动的文件全路径
* @param targetFileFullPath 移动文件到目标位置的目录全路径
* @return 是否复制成功, true:成功;否则失败
*/
public static boolean moveDirectoryToTarget(String sourceFileFullPath, String targetFileFullPath) {
try {
FileUtils.moveDirectory(new File(sourceFileFullPath), new File(targetFileFullPath));
return true;
} catch (IOException e) {
System.out.println(e.getMessage());
}
return false;
}
/**
* 解压
*
* @param zipFilePath zip文件路径
* @param desDirectory 解压的目标路径
*/
public static boolean unzip(String zipFilePath, String desDirectory) {
File desDir = new File(desDirectory);
if (!desDir.exists()) {
boolean mkdirSuccess = desDir.mkdirs();
if (!mkdirSuccess) {
log.error("创建解压目标文件夹失败");
return false;
}
}
// 读入流
try (ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(zipFilePath))) {
// 遍历每一个文件
ZipEntry zipEntry = zipInputStream.getNextEntry();
while (zipEntry != null) {
String unzipFilePath = desDirectory + File.separator + zipEntry.getName();
if (zipEntry.isDirectory()) {
// 直接创建
mkdir(new File(unzipFilePath));
} else {
File file = new File(unzipFilePath);
// 创建父目录
mkdir(file.getParentFile());
// 写出文件流
BufferedOutputStream bufferedOutputStream =
new BufferedOutputStream(new FileOutputStream(unzipFilePath));
byte[] bytes = new byte[1024];
int readLen;
while ((readLen = zipInputStream.read(bytes)) != -1) {
bufferedOutputStream.write(bytes, 0, readLen);
}
bufferedOutputStream.close();
}
zipInputStream.closeEntry();
zipEntry = zipInputStream.getNextEntry();
}
return true;
} catch (Exception e) {
log.error("解压文件失败");
return false;
}
}
public static void mkdir(File file) {
if (null == file || file.exists()) {
return;
}
boolean b = file.mkdirs();
if (!b) {
log.info("父路径文件夹创建失败");
}
}
/**
* 获取路径下的所有文件/文件夹
*
* @param directoryPath 需要遍历的文件夹路径
* @param isAddDirectory 是否将子文件夹的路径也添加到list集合中
* @return 路径
*/
public static List<String> getAllFile(String directoryPath, boolean isAddDirectory) {
List<String> list = new ArrayList<>();
File baseFile = new File(directoryPath);
if (baseFile.isFile() || !baseFile.exists()) {
return list;
}
File[] files = baseFile.listFiles();
if (files == null) {
return new ArrayList<>();
}
for (File file : files) {
if (file.isDirectory()) {
if (isAddDirectory) {
list.add(file.getAbsolutePath());
}
list.addAll(getAllFile(file.getAbsolutePath(), isAddDirectory));
} else {
list.add(file.getAbsolutePath());
}
}
return list;
}
/**
* 生成zip压缩文件
*
* @param filePaths 文件信息 {"fileName":"222.tif"} {"filePath","E:\\ceshi\\222.tif"};
* @param zipFilePath 压缩路径 "E:\\downloadCESHI\\"+zipName;
* @param keepDirStructure 压缩是否保持原路径结构
*/
public static boolean compress(List<Map<String, String>> filePaths, String zipFilePath, Boolean keepDirStructure) {
byte[] buf = new byte[1024];
File zipFile = new File(zipFilePath);
try {
if (!zipFile.exists()) {
boolean newFileFlag = zipFile.createNewFile();
if (!newFileFlag) {
return false;
}
}
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFile));
for (Map<String, String> filePath : filePaths) {
String relativePath = filePath.get("filePath");
String relativeName = filePath.get("fileName");
if (StringUtils.isEmpty(relativePath)) {
continue;
}
File sourceFile = new File(relativePath);
if (!sourceFile.exists()) {
continue;
}
FileInputStream fis = new FileInputStream(sourceFile);
if (keepDirStructure != null && keepDirStructure) {
zos.putNextEntry(new ZipEntry(relativePath));
} else {
zos.putNextEntry(new ZipEntry(relativeName));
}
int len;
while ((len = fis.read(buf)) > 0) {
zos.write(buf, 0, len);
}
zos.closeEntry();
fis.close();
}
zos.close();
return true;
} catch (Exception e) {
log.error("压缩异常", e);
return false;
}
}
/**
* 生成zip压缩文件
*
* @param directory 待压缩的文件夹
* @param zipFilePath 压缩路径
* @param keepDirStructure 压缩是否保持原路径结构
*/
public static boolean compressDirectory(File directory, String zipFilePath, boolean keepDirStructure) {
if (!directory.isDirectory()) {
log.error("文件不是文件夹 :{}", directory.getName());
return false;
}
File zipFile = new File(zipFilePath);
try {
if (!zipFile.exists()) {
File parentFile = zipFile.getParentFile();
boolean dirs = parentFile.mkdirs();
if (!dirs) {
log.warn("文件夹创建失败 :{}", parentFile.getName());
return false;
}
boolean newFileFlag = zipFile.createNewFile();
if (!newFileFlag) {
return false;
}
}
String name = directory.getName();
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFile));
compress(directory, zos, name, keepDirStructure);
zos.close();
return true;
} catch (Exception e) {
log.error("压缩异常", e);
return false;
}
}
/**
* 递归压缩方法
*
* @param sourceFile 源文件
* @param zos zip输出流
* @param name 压缩后的名称
* @param keepDirStructure 是否保留原来的目录结构,true:保留目录结构;
* false:所有文件跑到压缩包根目录下
*/
private static void compress(File sourceFile, ZipOutputStream zos, String name,
boolean keepDirStructure) throws Exception {
byte[] buf = new byte[1024];
if (sourceFile.isFile()) {
// 向zip输出流中添加一个zip实体,构造器中name为zip实体的文件的名字
zos.putNextEntry(new ZipEntry(name));
// copy文件到zip输出流中
int len;
FileInputStream in = new FileInputStream(sourceFile);
while ((len = in.read(buf)) != -1) {
zos.write(buf, 0, len);
}
// Complete the entry
zos.closeEntry();
in.close();
} else {
File[] listFiles = sourceFile.listFiles();
if (listFiles == null || listFiles.length == 0) {
// 需要保留原来的文件结构时,需要对空文件夹进行处理
if (keepDirStructure) {
// 空文件夹的处理
zos.putNextEntry(new ZipEntry(name + "/"));
// 没有文件,不需要文件的copy
zos.closeEntry();
}
} else {
for (File file : listFiles) {
// 判断是否需要保留原来的文件结构
if (keepDirStructure) {
// 注意:file.getName()前面需要带上父文件夹的名字加一斜杠,
// 不然最后压缩包中就不能保留原来的文件结构,即:所有文件都跑到压缩包根目录下了
compress(file, zos, name + "/" + file.getName(), true);
} else {
compress(file, zos, file.getName(), false);
}
}
}
}
}
public static void deleteDirectory(String filePath) {
if (StringUtils.isEmpty(filePath)) {
log.error("解析生成文件失败");
return;
}
File file = new File(filePath);
try {
FileUtils.deleteDirectory(file);
} catch (IOException e) {
log.error("删除文件目录失败", e);
}
}
public static void deleteDirectory(File file) {
if (file == null) {
log.error("解析生成文件失败");
return;
}
try {
FileUtils.deleteDirectory(file);
} catch (IOException e) {
log.error("删除文件目录失败", e);
}
}
/**
* 将文件对象转换为字符串
*
* @param filePath 文件路径
* @return
*/
public static String readFileToString(String filePath) {
File file = new File(filePath);
if (!file.exists()) {
return null;
}
try {
return FileUtils.readFileToString(file);
} catch (IOException e) {
e.printStackTrace();
log.error("文件对象转换为字符串", e);
return null;
}
}
/**
* 将json数据信息存入相应的文件中
*
* @param filePath 文件路径
* @param fileName 文件名称
* @param content 文件内容
* @return 是否成功
*/
public static String createFile(String filePath, String fileName, String content) {
File dir = new File(filePath);
if (!dir.exists()) {
dir.mkdirs();
}
File file = new File(filePath + File.separator + fileName);
if (!file.exists()) {
try {
file.createNewFile();
} catch (IOException e) {
log.error("文件创建失败", e);
}
}
try (OutputStream outputStream = new FileOutputStream(file.getAbsoluteFile());
OutputStreamWriter out = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8)) {
out.write(content);
out.flush();
} catch (Exception e1) {
log.error("文件创建失败", e1);
return null;
}
return file.getPath();
}
/**
* 删除文件数据
*
* @param filePath 文件路径
* @return 状态
*/
public static boolean deleteFile(String filePath) {
if (StringUtils.isEmpty(filePath)) {
return false;
}
File file = new File(filePath);
return file.delete();
}
/**
* 根据文件全路径生成相应的MD5数值
*
* @param fileFullPath 文件全路径信息
* @return 文件对应的md5
*/
public static String generateFileMd5(String fileFullPath) {
File file = new File(fileFullPath);
if (file.isDirectory()) {
return Md5Utils.calculateFolderMD5(fileFullPath);
}
try (FileInputStream fileInputStream = new FileInputStream(fileFullPath)) {
return DigestUtils.md5Hex(fileInputStream);
} catch (IOException e) {
log.error("DigestUtils.md5Hex error", e);
return null;
}
}
/**
* 字节数组写出到文件
* 字节数组读取到程序中 ByteArrayInputStream
* 程序写出到文件 FileOutputStream
*
* @param src 字节数组
* @param distFilePath 文件存储本地路径
*/
public static boolean toFile(byte[] src, String distFilePath) {
if (src == null || src.length == 0) {
return false;
}
try (InputStream is = new ByteArrayInputStream(src);
OutputStream os = new FileOutputStream(distFilePath);) {
byte[] flush = new byte[1024 * 10];
int len = -1;
while ((len = is.read(flush)) != -1) {
os.write(flush, 0, len);
os.flush();
}
} catch (IOException e) {
log.error("byte[] to file error.", e);
}
File file = new File(distFilePath);
return file.exists();
}
/**
* 修改linux环境下文件权限为755
*
* @param fullFilePath 文件全路径
*/
public static void changeFilePermission755(String fullFilePath) {
File file = new File(fullFilePath);
log.info("{} can 1 file.canExecute()={}", fullFilePath, file.canExecute());
//设置权限
Set<PosixFilePermission> perms = new HashSet<>();
perms.add(PosixFilePermission.OWNER_READ);
perms.add(PosixFilePermission.OWNER_WRITE);
perms.add(PosixFilePermission.OWNER_EXECUTE);
perms.add(PosixFilePermission.GROUP_READ);
perms.add(PosixFilePermission.GROUP_EXECUTE);
perms.add(PosixFilePermission.OTHERS_READ);
perms.add(PosixFilePermission.OTHERS_EXECUTE);
Path path = Paths.get(fullFilePath);
try {
Files.walk(path).forEach(
p -> {
try {
Files.setPosixFilePermissions(p, perms);//修改文件的权限
} catch (Exception e) {
log.error("文件权限修改失败", e);
}
}
);
} catch (IOException e) {
log.error("文件权限修改失败", e);
}
log.info("{} can 2 file.canExecute()={}", fullFilePath, file.canExecute());
}
/**
* 修改linux环境下文件权限为777
*
* @param filePath 文件全路径
*/
public static void changeFilePermission777(String filePath) {
File file = new File(filePath);
log.info("{} can 1 file.canExecute()={}", filePath, file.canExecute());
//设置权限
Set<PosixFilePermission> perms = new HashSet<>();
perms.add(PosixFilePermission.OWNER_READ);
perms.add(PosixFilePermission.OWNER_WRITE);
perms.add(PosixFilePermission.OWNER_EXECUTE);
perms.add(PosixFilePermission.GROUP_READ);
perms.add(PosixFilePermission.GROUP_WRITE);
perms.add(PosixFilePermission.GROUP_EXECUTE);
perms.add(PosixFilePermission.OTHERS_READ);
perms.add(PosixFilePermission.OTHERS_WRITE);
perms.add(PosixFilePermission.OTHERS_EXECUTE);
Path path = Paths.get(filePath);
try {
Files.walk(path).forEach(
p -> {
try {
Files.setPosixFilePermissions(p, perms);//修改文件的权限
} catch (Exception e) {
log.error("文件权限修改失败", e);
}
}
);
} catch (IOException e) {
log.error("文件权限修改失败", e);
}
log.info("{} can 2 file.canExecute()={}", path, file.canExecute());
}
}