文件拆分与压缩,文件处理工具类+压缩文件工具类
1.创建、拆分、压缩
² NNN是从001依次增长的;
² 接口文件为.gz格式压缩;
² 文件小于等于10M,超过10M的进行拆分;
FILE_SIZE :
private static int FILE_SIZE = 10 * 1024 * 1024;
private static String localFilePath= "E:/test/";
builder :
StringBuilder builder = new StringBuilder(); builder.append("1|").append(date).append("|0").append("\r\n");
//删除本地路径下所有文件 FileUtils.deleteChildrenDir(new File(localFilePath)); //创建临时文件并写入 String tempFileName = FILE_NAME_PREFIX + date + "_BOSSZZZ_C"; File tempFile = new File(localFilePath, tempFileName); log.info("文件所在的本地路径:" + tempFile.getCanonicalPath()); FileUtils.writeFile(builder,tempFile); //拆分文件 FileUtils.divide(tempFile, FILE_SIZE); //压缩 File file = new File(localFilePath); File[] tempList = file.listFiles(); for (int i = 0; i < tempList.length; i++) { if(("unl").equals(FileUtils.getFileExt(tempList[i].getName()))){ FileOutputStream fos = new FileOutputStream(new File(tempList[i].getCanonicalPath() + ".gz")); ZipUtils.toZip(tempList[i].getCanonicalPath(), fos, true); log.info("压缩文件所在的本地路径:" + tempList[i].getCanonicalPath()+".gz"); }else { tempList[i].delete(); } }
package com.ztesoft.iotcmp.util; import java.io.*; import java.net.MalformedURLException; import java.net.URL; public class FileUtils {/** * 写入指定文件 * * @param builder * @param File * @return */ public static void writeFile(StringBuilder builder,File File) throws Exception{ FileWriter fileWriter = new FileWriter(File); fileWriter.write(builder.toString()); fileWriter.close(); }/** * 删除文件夹下面的子文件夹 * * @param dir * @throws IOException */ public static void deleteChildrenDir(File dir) throws IOException { if (dir.isFile()) throw new IOException("IOException -> BadInputException: not a directory."); File[] files = dir.listFiles(); if (files != null) { for (int i = 0; i < files.length; i++) { File file = files[i]; if (file.isFile()) { file.delete(); } else { deleteDir(file); } } } } /** * 文件拆分并删除原文件 * 拆分后文件路径为file原路径 * 拆分后文件名:[文件名NNN] NNN是从001依次增长 * */ public static void divide(File file, long size) throws Exception { if (!file.exists() || (!file.isFile())) { throw new Exception("指定文件不存在!"); } // 获得被分割文件父文件,将来被分割成的小文件便存在这个目录下 File parentFile = file.getParentFile(); // 取得文件的大小 long fileLength = file.length(); System.out.println("文件大小:" + fileLength + " 字节"); if (size <= 0) { size = fileLength / 2; } // 取得被分割后的小文件的数目 int num = (fileLength % size != 0) ? (int) (fileLength / size + 1) : (int) (fileLength / size); // 存放被分割后的小文件名 String[] fileNames = new String[num]; // 输入文件流,即被分割的文件 FileInputStream in = new FileInputStream(file); // 读输入文件流的开始和结束下标 long end = 0; int begin = 0; // 根据要分割的数目输出文件 for (int i = 0; i < num; i++) { // 对于前num - 1个小文件,大小都为指定的size String numFileStr = String.format("%03d",i+1); File outFile = new File(parentFile, file.getName() + numFileStr + ".unl"); // 构建小文件的输出流 FileOutputStream out = new FileOutputStream(outFile); // 将结束下标后移size end += size; end = (end > fileLength) ? fileLength : end; // 从输入流中读取字节存储到输出流中 for (; begin < end; begin++) { out.write(in.read()); } out.close(); fileNames[i] = outFile.getAbsolutePath(); } file.delete(); in.close(); } }
public class ZipUtils { private static final ZSmartLogger logger = ZSmartLogger.getLogger(ZipUtils.class); private static final int BUFFER_SIZE = 2 * 1024; /** * 压缩成ZIP * @param srcDir 压缩文件夹路径 * @param out 压缩文件输出流 * @param KeepDirStructure 是否保留原来的目录结构,true:保留目录结构; * false:所有文件跑到压缩包根目录下(注意:不保留目录结构可能会出现同名文件,会压缩失败) * @throws RuntimeException 压缩失败会抛出运行时异常 */ public static void toZip(String srcDir, OutputStream out, boolean KeepDirStructure) throws RuntimeException{ long start = System.currentTimeMillis(); ZipOutputStream zos = null ; try { zos = new ZipOutputStream(out); File sourceFile = new File(srcDir); compress(sourceFile,zos,sourceFile.getName(),KeepDirStructure); long end = System.currentTimeMillis(); logger.info("压缩完成,耗时:{}ms",(end - start)); } catch (Exception e) { throw new RuntimeException("zip error from ZipUtils",e); }finally{ if(zos != null){ try { zos.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
2.文件处理工具类
package com.ztesoft.iotcmp.util; import java.io.*; import java.net.MalformedURLException; import java.net.URL; public class FileUtils { /** * 读取文件内容 * * @param is * @return */ public static String readFile(InputStream is) { BufferedReader br = null; StringBuffer sb = new StringBuffer(); try { br = new BufferedReader(new InputStreamReader(is, "UTF-8")); String readLine = null; while ((readLine = br.readLine()) != null) { sb.append(readLine); } } catch (Exception e) { e.printStackTrace(); } finally { try { br.close(); is.close(); } catch (IOException e) { e.printStackTrace(); } } return sb.toString(); } /** * 写入指定文件 * * @param builder * @param File * @return */ public static void writeFile(StringBuilder builder,File File) throws Exception{ FileWriter fileWriter = new FileWriter(File); fileWriter.write(builder.toString()); fileWriter.close(); } /** * 判断指定的文件是否存在。 * * @param fileName * @return */ public static boolean isFileExist(String fileName) { return new File(fileName).isFile(); } /** * 创建指定的目录。 如果指定的目录的父目录不存在则创建其目录书上所有需要的父目录。 * 注意:可能会在返回false的时候创建部分父目录。 * * @param file * @return */ public static boolean makeDirectory(File file) { File parent = file.getParentFile(); if (parent != null) { return parent.mkdirs(); } return false; } /** * 返回文件的URL地址。 * * @param file * @return * @throws MalformedURLException */ public static URL getURL(File file) throws MalformedURLException { String fileURL = "file:/" + file.getAbsolutePath(); URL url = new URL(fileURL); return url; } /** * 从文件路径得到文件名。 * * @param filePath * @return */ public static String getFileName(String filePath) { File file = new File(filePath); return file.getName(); } /** * 从文件名得到文件绝对路径。 * * @param fileName * @return */ public static String getFilePath(String fileName) { File file = new File(fileName); return file.getAbsolutePath(); } /** * 将DOS/Windows格式的路径转换为UNIX/Linux格式的路径。 * * @param filePath * @return */ public static String toUNIXpath(String filePath) { return filePath.replace("", "/"); } /** * 从文件名得到UNIX风格的文件绝对路径。 * * @param fileName * @return */ public static String getUNIXfilePath(String fileName) { File file = new File(fileName); return toUNIXpath(file.getAbsolutePath()); } /** * 得到文件后缀名 * * @param fileName * @return */ public static String getFileExt(String fileName) { int point = fileName.lastIndexOf('.'); int length = fileName.length(); if (point == -1 || point == length - 1) { return ""; } else { return fileName.substring(point + 1, length); } } /** * 得到文件的名字部分。 实际上就是路径中的最后一个路径分隔符后的部分。 * * @param fileName * @return */ public static String getNamePart(String fileName) { int point = getPathLastIndex(fileName); int length = fileName.length(); if (point == -1) { return fileName; } else if (point == length - 1) { int secondPoint = getPathLastIndex(fileName, point - 1); if (secondPoint == -1) { if (length == 1) { return fileName; } else { return fileName.substring(0, point); } } else { return fileName.substring(secondPoint + 1, point); } } else { return fileName.substring(point + 1); } } /** * 得到文件名中的父路径部分。 对两种路径分隔符都有效。 不存在时返回""。 * 如果文件名是以路径分隔符结尾的则不考虑该分隔符,例如"/path/"返回""。 * * @param fileName * @return */ public static String getPathPart(String fileName) { int point = getPathLastIndex(fileName); int length = fileName.length(); if (point == -1) { return ""; } else if (point == length - 1) { int secondPoint = getPathLastIndex(fileName, point - 1); if (secondPoint == -1) { return ""; } else { return fileName.substring(0, secondPoint); } } else { return fileName.substring(0, point); } } /** * 得到路径分隔符在文件路径中最后出现的位置。 对于DOS或者UNIX风格的分隔符都可以。 * * @param fileName * @return */ public static int getPathLastIndex(String fileName) { int point = fileName.lastIndexOf("/"); if (point == -1) { point = fileName.lastIndexOf(""); } return point; } /** * 得到路径分隔符在文件路径中指定位置前最后出现的位置。 对于DOS或者UNIX风格的分隔符都可以。 * * @param fileName * @param fromIndex * @return */ public static int getPathLastIndex(String fileName, int fromIndex) { int point = fileName.lastIndexOf("/", fromIndex); if (point == -1) { point = fileName.lastIndexOf("", fromIndex); } return point; } /** * 得到路径分隔符在文件路径中首次出现的位置。 对于DOS或者UNIX风格的分隔符都可以。 * * @param fileName * @return */ public static int getPathIndex(String fileName) { int point = fileName.indexOf("/"); if (point == -1) { point = fileName.indexOf(""); } return point; } /** * 得到路径分隔符在文件路径中指定位置后首次出现的位置。 对于DOS或者UNIX风格的分隔符都可以。 * * @param fileName * @param fromIndex * @return */ public static int getPathIndex(String fileName, int fromIndex) { int point = fileName.indexOf("/", fromIndex); if (point == -1) { point = fileName.indexOf("", fromIndex); } return point; } /** * 将文件名中的类型部分去掉。 * * @param filename * @return */ public static String removeFileExt(String filename) { int index = filename.lastIndexOf("."); if (index != -1) { return filename.substring(0, index); } else { return filename; } } /** * 得到相对路径。 文件名不是目录名的子节点时返回文件名。 * * @param pathName * @param fileName * @return */ public static String getSubpath(String pathName, String fileName) { int index = fileName.indexOf(pathName); if (index != -1) { return fileName.substring(index + pathName.length() + 1); } else { return fileName; } } /** * 删除一个文件。 * * @param filename * @throws IOException */ public static void deleteFile(String filename) throws IOException { File file = new File(filename); if (file.isDirectory()) { throw new IOException("IOException -> BadInputException: not a file."); } if (!file.exists()) { throw new IOException("IOException -> BadInputException: file is not exist."); } if (!file.delete()) { throw new IOException("Cannot delete file. filename = " + filename); } } /** * 删除文件夹及其下面的子文件夹 * * @param dir * @throws IOException */ public static void deleteDir(File dir) throws IOException { if (dir.isFile()) throw new IOException("IOException -> BadInputException: not a directory."); File[] files = dir.listFiles(); if (files != null) { for (int i = 0; i < files.length; i++) { File file = files[i]; if (file.isFile()) { file.delete(); } else { deleteDir(file); } } } dir.delete(); } /** * 删除文件夹下面的子文件夹 * * @param dir * @throws IOException */ public static void deleteChildrenDir(File dir) throws IOException { if (dir.isFile()) throw new IOException("IOException -> BadInputException: not a directory."); File[] files = dir.listFiles(); if (files != null) { for (int i = 0; i < files.length; i++) { File file = files[i]; if (file.isFile()) { file.delete(); } else { deleteDir(file); } } } } /** * 复制文件 * * @param src * @param dst * @throws Exception */ public static void copy(File src, File dst) throws Exception { int BUFFER_SIZE = 4096; InputStream in = null; OutputStream out = null; try { in = new BufferedInputStream(new FileInputStream(src), BUFFER_SIZE); out = new BufferedOutputStream(new FileOutputStream(dst), BUFFER_SIZE); byte[] buffer = new byte[BUFFER_SIZE]; int len = 0; while ((len = in.read(buffer)) > 0) { out.write(buffer, 0, len); } } catch (Exception e) { throw e; } finally { if (null != in) { try { in.close(); } catch (IOException e) { e.printStackTrace(); } in = null; } if (null != out) { try { out.close(); } catch (IOException e) { e.printStackTrace(); } out = null; } } } /** * @复制文件,支持把源文件内容追加到目标文件末尾 * @param src * @param dst * @param append * @throws Exception */ public static void copy(File src, File dst, boolean append) throws Exception { int BUFFER_SIZE = 4096; InputStream in = null; OutputStream out = null; try { in = new BufferedInputStream(new FileInputStream(src), BUFFER_SIZE); out = new BufferedOutputStream(new FileOutputStream(dst, append), BUFFER_SIZE); byte[] buffer = new byte[BUFFER_SIZE]; int len = 0; while ((len = in.read(buffer)) > 0) { out.write(buffer, 0, len); } } catch (Exception e) { throw e; } finally { if (null != in) { try { in.close(); } catch (IOException e) { e.printStackTrace(); } in = null; } if (null != out) { try { out.close(); } catch (IOException e) { e.printStackTrace(); } out = null; } } } /** * 文件拆分并删除原文件 * 拆分后文件路径为file原路径 * 拆分后文件名:[文件名NNN] NNN是从001依次增长 * */ public static void divide(File file, long size) throws Exception { if (!file.exists() || (!file.isFile())) { throw new Exception("指定文件不存在!"); } // 获得被分割文件父文件,将来被分割成的小文件便存在这个目录下 File parentFile = file.getParentFile(); // 取得文件的大小 long fileLength = file.length(); System.out.println("文件大小:" + fileLength + " 字节"); if (size <= 0) { size = fileLength / 2; } // 取得被分割后的小文件的数目 int num = (fileLength % size != 0) ? (int) (fileLength / size + 1) : (int) (fileLength / size); // 存放被分割后的小文件名 String[] fileNames = new String[num]; // 输入文件流,即被分割的文件 FileInputStream in = new FileInputStream(file); // 读输入文件流的开始和结束下标 long end = 0; int begin = 0; // 根据要分割的数目输出文件 for (int i = 0; i < num; i++) { // 对于前num - 1个小文件,大小都为指定的size String numFileStr = String.format("%03d",i+1); File outFile = new File(parentFile, file.getName() + numFileStr + ".unl"); // 构建小文件的输出流 FileOutputStream out = new FileOutputStream(outFile); // 将结束下标后移size end += size; end = (end > fileLength) ? fileLength : end; // 从输入流中读取字节存储到输出流中 for (; begin < end; begin++) { out.write(in.read()); } out.close(); fileNames[i] = outFile.getAbsolutePath(); } file.delete(); in.close(); } }
3.压缩文件工具类
package com.ztesoft.iotcmp.util; import com.ztesoft.zsmart.core.log.ZSmartLogger; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.OutputStream; import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; public class ZipUtils { private static final ZSmartLogger logger = ZSmartLogger.getLogger(ZipUtils.class); private static final int BUFFER_SIZE = 2 * 1024; /** * 压缩成ZIP 方法1 * @param srcDir 压缩文件夹路径 * @param out 压缩文件输出流 * @param KeepDirStructure 是否保留原来的目录结构,true:保留目录结构; * false:所有文件跑到压缩包根目录下(注意:不保留目录结构可能会出现同名文件,会压缩失败) * @throws RuntimeException 压缩失败会抛出运行时异常 */ public static void toZip(String srcDir, OutputStream out, boolean KeepDirStructure) throws RuntimeException{ long start = System.currentTimeMillis(); ZipOutputStream zos = null ; try { zos = new ZipOutputStream(out); File sourceFile = new File(srcDir); compress(sourceFile,zos,sourceFile.getName(),KeepDirStructure); long end = System.currentTimeMillis(); logger.info("压缩完成,耗时:{}ms",(end - start)); } catch (Exception e) { throw new RuntimeException("zip error from ZipUtils",e); }finally{ if(zos != null){ try { zos.close(); } catch (IOException e) { e.printStackTrace(); } } } } /** * 压缩成ZIP 方法2 * @param srcFiles 需要压缩的文件列表 * @param out 压缩文件输出流 * @throws RuntimeException 压缩失败会抛出运行时异常 */ public static void toZip(List<File> srcFiles , OutputStream out)throws RuntimeException { long start = System.currentTimeMillis(); ZipOutputStream zos = null ; try { zos = new ZipOutputStream(out); for (File srcFile : srcFiles) { byte[] buf = new byte[BUFFER_SIZE]; zos.putNextEntry(new ZipEntry(srcFile.getName())); int len; FileInputStream in = new FileInputStream(srcFile); while ((len = in.read(buf)) != -1){ zos.write(buf, 0, len); } zos.closeEntry(); in.close(); } long end = System.currentTimeMillis(); logger.info("压缩完成,耗时:{}ms",(end - start)); } catch (Exception e) { throw new RuntimeException("zip error from ZipUtils",e); }finally{ if(zos != null){ try { zos.close(); } catch (IOException e) { e.printStackTrace(); } } } } /** * 递归压缩方法 * @param sourceFile 源文件 * @param zos zip输出流 * @param name 压缩后的名称 * @param KeepDirStructure 是否保留原来的目录结构,true:保留目录结构; * false:所有文件跑到压缩包根目录下(注意:不保留目录结构可能会出现同名文件,会压缩失败) * @throws Exception */ private static void compress(File sourceFile, ZipOutputStream zos, String name, boolean KeepDirStructure) throws Exception{ byte[] buf = new byte[BUFFER_SIZE]; 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(),KeepDirStructure); } else { compress(file, zos, file.getName(),KeepDirStructure); } } } } } }
String tempFileName = FILE_NAME_PREFIX + date + "_BOSSZZZ_C";
File tempFile = new File(localFilePath, tempFileName);
log.info("文件所在的本地路径:" + tempFile.getCanonicalPath());
FileUtils.writeFile(builder,tempFile);