先新建一个枚举FileType(这一步可有可无,只是为了分辨文件类型)
public enum FileType {
// 未知
UNKNOWN,
// 压缩文件
ZIP, RAR, _7Z, TAR, GZ, TAR_GZ, BZ2, TAR_BZ2,
// 位图文件
BMP, PNG, JPG, JPEG,
// 矢量图文件
SVG,
// 影音文件
AVI, MP4, MP3, AAR, OGG, WAV, WAVE
}
下面是工具类FileUtils
import com.mlog.enums.FileType;
import org.apache.commons.compress.archivers.sevenz.SevenZArchiveEntry;
import org.apache.commons.compress.archivers.sevenz.SevenZFile;
import org.apache.commons.compress.compressors.bzip2.BZip2CompressorInputStream;
import org.apache.tools.tar.TarEntry;
import org.apache.tools.tar.TarInputStream;
import java.io.*;
import java.nio.file.Files;
import java.util.zip.GZIPInputStream;
public class FileUtils {
/**
* 获取文件真实类型
* 这里是通过文件头信息来判断什么类型的。其他文件的头文件信息,这里就不展示了。如果有需要,可以拿文件来跑跑,看看headHex是啥值就行了。
*
* @param file 要获取类型的文件。
* @return 文件类型枚举。
*/
public static FileType getFileType(File file) {
FileInputStream inputStream = null;
try {
inputStream = new FileInputStream(file);
byte[] head = new byte[4];
if (-1 == inputStream.read(head)) {
return FileType.UNKNOWN;
}
int headHex = 0;
for (byte b : head) {
headHex <<= 8;
headHex |= b;
}
switch (headHex) {
case 0x504B0304:
return FileType.ZIP;
case 0x776f7264:
return FileType.TAR;
case -0x51:
return FileType._7Z;
case 0x425a6839:
return FileType.BZ2;
case -0x74f7f8:
return FileType.GZ;
case 0x52617221:
return FileType.RAR;
default:
return FileType.UNKNOWN;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (inputStream != null) {
inputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return FileType.UNKNOWN;
}
/**
* 构建目录
*
* @param outputDir 输出目录
* @param subDir 子目录
*/
private static void createDirectory(String outputDir, String subDir) {
File file = new File(outputDir);
if (!(subDir == null || subDir.trim().equals(""))) {//子目录不为空
file = new File(outputDir + File.separator + subDir);
}
if (!file.exists()) {
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
file.mkdirs();
}
}
/**
* 解压缩tar文件
*
* @param file 压缩包文件
* @param targetPath 目标文件夹
* @param delete 解压后是否删除原压缩包文件
*/
private static void decompressTar(File file, String targetPath, boolean delete) {
FileInputStream fis = null;
OutputStream fos = null;
TarInputStream tarInputStream = null;
try {
fis = new FileInputStream(file);
tarInputStream = new TarInputStream(fis, 1024 * 2);
// 创建输出目录
createDirectory(targetPath, null);
TarEntry entry = null;
while (true) {
entry = tarInputStream.getNextEntry();
if (entry == null) {
break;
}
if (entry.isDirectory()) {
createDirectory(targetPath, entry.getName()); // 创建子目录
} else {
fos = new FileOutputStream(new File(targetPath + File.separator + entry.getName()));
int count;
byte data[] = new byte[2048];
while ((count = tarInputStream.read(data)) != -1) {
fos.write(data, 0, count);
}
fos.flush();
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fis != null) {
fis.close();
}
if (fos != null) {
fos.close();
}
if (tarInputStream != null) {
tarInputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
// 有一点需要注意的是:方法参数传了一个是否需要删除原压缩包的参数,如果需要删除的话,必须!必须!必须!等到流关闭了之后才能删除,不然是删不掉的。也可以在该方法的调用者那里删,这样就可以不用传这个参数了。
// bz2文件解压
// 解压bz2文件我这里是用的Apache的commons.compress工具来解压,先下载jar包:commons-compress-1.9.jar,(1.8的貌似有问题,我就换成了1.9)
/**
* 解压缩bz2文件
*
* @param file 压缩包文件
* @param targetPath 目标文件夹
* @param delete 解压后是否删除原压缩包文件
*/
public static void decompressBZ2(File file, String targetPath, boolean delete) {
FileInputStream fis = null;
OutputStream fos = null;
BZip2CompressorInputStream bis = null;
String suffix = ".bz2";
try {
fis = new FileInputStream(file);
bis = new BZip2CompressorInputStream(fis);
// 创建输出目录
createDirectory(targetPath, null);
File tempFile = new File(targetPath + File.separator + file.getName().replace(suffix, ""));
fos = Files.newOutputStream(tempFile.toPath());
int count;
byte[] data = new byte[2048];
while ((count = bis.read(data)) != -1) {
fos.write(data, 0, count);
}
fos.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fis != null) {
fis.close();
}
if (fos != null) {
fos.close();
}
if (bis != null) {
bis.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
// tar.bz2文件解压
/**
* 解压缩tar.bz2文件
*
* @param file 压缩包文件
* @param targetPath 目标文件夹
* @param delete 解压后是否删除原压缩包文件
*/
public static void decompressTarBz2(File file, String targetPath, boolean delete) {
FileInputStream fis = null;
OutputStream fos = null;
BZip2CompressorInputStream bis = null;
TarInputStream tis = null;
try {
fis = new FileInputStream(file);
bis = new BZip2CompressorInputStream(fis);
tis = new TarInputStream(bis, 1024 * 2);
// 创建输出目录
createDirectory(targetPath, null);
TarEntry entry;
while ((entry = tis.getNextEntry()) != null) {
if (entry.isDirectory()) {
createDirectory(targetPath, entry.getName()); // 创建子目录
} else {
fos = new FileOutputStream(new File(targetPath + File.separator + entry.getName()));
int count;
byte data[] = new byte[2048];
while ((count = tis.read(data)) != -1) {
fos.write(data, 0, count);
}
fos.flush();
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fis != null) {
fis.close();
}
if (fos != null) {
fos.close();
}
if (bis != null) {
bis.close();
}
if (tis != null) {
tis.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
//tar.gz文件解压
/**
* 解压缩tar.gz文件
*
* @param file 压缩包文件
* @param targetPath 目标文件夹
* @param delete 解压后是否删除原压缩包文件
*/
private static void decompressTarGz(File file, String targetPath, boolean delete) {
FileInputStream fileInputStream = null;
BufferedInputStream bufferedInputStream = null;
GZIPInputStream gzipIn = null;
TarInputStream tarIn = null;
OutputStream out = null;
try {
fileInputStream = new FileInputStream(file);
bufferedInputStream = new BufferedInputStream(fileInputStream);
gzipIn = new GZIPInputStream(bufferedInputStream);
tarIn = new TarInputStream(gzipIn, 1024 * 2);
// 创建输出目录
createDirectory(targetPath, null);
TarEntry entry = null;
while ((entry = tarIn.getNextEntry()) != null) {
if (entry.isDirectory()) { // 是目录
createDirectory(targetPath, entry.getName()); // 创建子目录
} else { // 是文件
File tempFIle = new File(targetPath + File.separator + entry.getName());
createDirectory(tempFIle.getParent() + File.separator, null);
out = new FileOutputStream(tempFIle);
int len = 0;
byte[] b = new byte[2048];
while ((len = tarIn.read(b)) != -1) {
out.write(b, 0, len);
}
out.flush();
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
if (tarIn != null) {
tarIn.close();
}
if (gzipIn != null) {
gzipIn.close();
}
if (bufferedInputStream != null) {
bufferedInputStream.close();
}
if (fileInputStream != null) {
fileInputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
//gz文件解压
/**
* 解压缩gz文件
*
* @param file 压缩包文件
* @param targetPath 目标文件夹
* @param delete 解压后是否删除原压缩包文件
*/
private static void decompressGz(File file, String targetPath, boolean delete) {
FileInputStream fileInputStream = null;
GZIPInputStream gzipIn = null;
OutputStream out = null;
String suffix = ".gz";
try {
fileInputStream = new FileInputStream(file);
gzipIn = new GZIPInputStream(fileInputStream);
// 创建输出目录
createDirectory(targetPath, null);
File tempFile = new File(targetPath + File.separator + file.getName().replace(suffix, ""));
out = new FileOutputStream(tempFile);
int count;
byte data[] = new byte[2048];
while ((count = gzipIn.read(data)) != -1) {
out.write(data, 0, count);
}
out.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
out.close();
}
if (gzipIn != null) {
gzipIn.close();
}
if (fileInputStream != null) {
fileInputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
// 7z文件解压
/**
* 解压缩7z文件
*
* @param file 压缩包文件
* @param targetPath 目标文件夹
* @param delete 解压后是否删除原压缩包文件
*/
private static void decompress7Z(File file, String targetPath, boolean delete) {
SevenZFile sevenZFile = null;
OutputStream outputStream = null;
try {
sevenZFile = new SevenZFile(file);
// 创建输出目录
createDirectory(targetPath, null);
SevenZArchiveEntry entry;
while ((entry = sevenZFile.getNextEntry()) != null) {
if (entry.isDirectory()) {
createDirectory(targetPath, entry.getName()); // 创建子目录
} else {
outputStream = new FileOutputStream(new File(targetPath + File.separator + entry.getName()));
int len = 0;
byte[] b = new byte[2048];
while ((len = sevenZFile.read(b)) != -1) {
outputStream.write(b, 0, len);
}
outputStream.flush();
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (sevenZFile != null) {
sevenZFile.close();
}
if (outputStream != null) {
outputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}