/* ==================================================================
* Created [2009-4-27 下午11:32:55] by Jon.King
* ==================================================================
* TSS
* ==================================================================
* mailTo:jinpujun@hotmail.com
* Copyright (c) Jon.King, 2009-2012
* ==================================================================
*/
package com.jinhe.tss.core.util;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import javax.servlet.http.HttpServletResponse;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Expand;
import org.dom4j.Document;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
import com.jinhe.tss.core.exception.BusinessException;
import com.jinhe.tss.core.sso.context.Context;
/**
* 文件操作帮助类
*/
public class FileHelper {
public final static String PATH_SEPARATOR = "/";
/**
* 读入文件为字符串
* @param file
* @return
*/
public static String readFile(File file) {
StringBuffer sb = new StringBuffer();
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
String data = null;
while((data = br.readLine())!=null){
sb.append(data).append("\n");
}
br.close();
} catch (FileNotFoundException e) {
throw new BusinessException("找不到指定的文件", e);
} catch (IOException e) {
throw new BusinessException("读取文件内容时IO异常", e);
}
return sb.toString();
}
/**
* 指定编码读入文件为字符串
* @param file
* @param charSet
* @return
*/
public static String readFile(File file, String charSet) {
StringBuffer sb = new StringBuffer();
BufferedReader br = null;
try {
br = new BufferedReader(new InputStreamReader(new FileInputStream(file), charSet));
String data = null;
while((data = br.readLine())!=null){
sb.append(data).append("\n");
}
br.close();
} catch (FileNotFoundException e) {
throw new BusinessException("找不到指定的文件", e);
} catch (IOException e) {
throw new BusinessException("读取文件内容时IO异常", e);
}
return sb.toString();
}
/**
* 写入文件
* @param file
* @param htmlContent
*/
public static void writeFile(File file, String content){
try {
FileWriter fw = new FileWriter(file);
fw.write(content, 0, content.length());
fw.close();
} catch (IOException e) {
throw new BusinessException("写入文件内容时IO异常", e);
}
}
/**
* 将XML文件Document对象写入到指定的文件中。 保证格式不变。
*
* @param doc
* 源XML文件Document对象
* @param dirFile
* 目标文件
*/
public static void writeXMLDoc(Document doc, String dirFile) {
// pass: FileWriter和FileOutputStream区别:前者会改变文件编码格式,后者不会。
// 另外可通过format.setEncoding("UTF-8")方式来设置XMLWriter的输出编码方式。
XMLWriter writer = null;
try {
OutputFormat format = OutputFormat.createPrettyPrint();
writer = new XMLWriter(new FileOutputStream(dirFile), format);
writer.write(doc);
} catch (UnsupportedEncodingException e) {
throw new BusinessException("不支持的编码格式", e);
} catch (FileNotFoundException e) {
throw new BusinessException("文件未找到", e);
} catch (IOException e) {
throw new BusinessException("文件读写失败", e);
} finally {
try {
if(writer != null) {
writer.close();
}
} catch (IOException e) {
throw new BusinessException("文件流关闭失败", e);
}
}
}
/**
* 将上传到临时文件夹的文件重新写入到特定的文件夹中
*
* @param dir
* 目标目录
* @param file
* 源文件
* @return
*/
public static String copyFile(File dir, File file) {
return copyFile(dir, file, true, true);
}
/**
* 将上传到临时文件夹的文件重新写入到特定的文件夹中。
* 本方法采用FileInputStream、FileOutputStream二进制流的形式读取以及写入文件,
* 可确保不会改变文件的内容和格式。采用Reader以及Writer则会改变文件。
*
* @param dir
* 目标目录
* @param file
* 源文件
* @param isUpdate
* 同文件名的文件存在时是否覆盖原文件
* @param isCut
* 是否剪切
* @return
*/
public static String copyFile(File dir, File file, boolean isUpdate, boolean isCut) {
if (!dir.exists()) {
dir.mkdir();
}
String fileName = file.getName();
File newFile = new File(dir.getPath() + "/" + fileName);
if (newFile.exists() && !isUpdate) {
throw new BusinessException("与该文件文件名一样的文件已经存在,请先修改文件名!");
}
InputStream in;
try {
in = new FileInputStream(file);
} catch (FileNotFoundException e) {
throw new BusinessException("文件找不到!", e);
}
OutputStream out;
try {
out = new FileOutputStream(newFile);
} catch (FileNotFoundException e) {
try {
in.close();
} catch (IOException e1) {
throw new BusinessException("文件输入流关闭失败", e1);
}
throw new BusinessException("文件找不到!", e);
}
int len = 0;
byte[] b = new byte[1024];
try {
while ((len = in.read(b)) != -1) {
out.write(b, 0, len);
out.flush();
}
} catch (IOException e) {
throw new BusinessException("文件读写失败", e);
} finally {
try {
in.close();
} catch (IOException e) {
throw new BusinessException("文件输入流关闭失败", e);
} finally {
try {
out.close();
} catch (IOException e) {
throw new BusinessException("文件输出流关闭失败", e);
}
}
}
if (isCut && file.exists()) {
file.delete();
}
return fileName;
}
/**
* 根据文件的后缀名列出制定目录下的文件(只限于指定目录,不包含子目录的文件)
*
* @param suffix
* 后缀名
* @param dir
* @return
*/
public static List<String> listFilesByType(String suffix, File dir) {
List<String> list = new ArrayList<String>();
if (dir.exists()) {
String[] files = dir.list();
for (int i = 0; i < files.length; i++) {
String fileName = files[i];
if (fileName.endsWith(suffix)) {
list.add(fileName);
}
}
}
return list;
}
/**
* 列出文件夹下所有的文件和子文件夹(只限于指定目录,不包含子目录的文件和文件夹)
*
* @param dir
* @return
*/
public static List<String> listFiles(File dir) {
return listFilesByType("", dir);
}
/**
* 列出文件夹下所有子文件夹(只限于指定目录,不包含子目录的文件夹)
*
* @param dir
* @return
*/
public static List<File> listSubDir(File dir) {
List<File> list = new ArrayList<File>();
if (dir.exists()) {
File[] files = dir.listFiles();
for (int i = 0; i < files.length; i++)
if (files[i].isDirectory())
list.add(files[i]);
}
return list;
}
/**
* 根据文件的后缀名列出制定目录下的文件名列表(包含子目录的文件,即深度读取)
*
* @param suffix
* 后缀名
* @param dir
* @return List[File1Name,File2Name,File3Name]
*/
public static List<String> listFileNamesByTypeDeeply(String suffix, File dir) {
List<String> list = new ArrayList<String>();
if (dir.exists()) {
String[] files = dir.list();
for (int i = 0; i < files.length; i++) {
String fileName = files[i];
if (fileName.endsWith(suffix)) {
list.add(fileName);
}
File file = new File(dir.getPath() + "/" + fileName);
if (file.isDirectory()) {
list.addAll(listFileNamesByTypeDeeply(suffix, file));
}
}
}
return list;
}
/**
* 根据文件的后缀名列出制定目录下的文件列表(包含子目录的文件,即深度读取)
* @param suffix
* 后缀名
* @param dir
* @return List[File1,File2,File3]
*/
public static List<File> listFilesByTypeDeeply(String suffix, File dir) {
List<File> list = new ArrayList<File>();
if (dir.exists()) {
String[] files = dir.list();
for (int i = 0; i < files.length; i++) {
String fileName = files[i];
File file = new File(dir.getPath() + "/" + fileName);
if (file.isDirectory()) {
list.addAll(listFilesByTypeDeeply(suffix, file));
} else if (fileName.endsWith(suffix)) {
list.add(file);
}
}
}
return list;
}
public static List<File> listFilesByTypeDeeply(File dir) {
return listFilesByTypeDeeply("", dir);
}
/**
* 在指定文件夹下根据文件名查找子文件夹
*
* @param dir
* @param pathName
* @return
*/
public static File findPathByName(File dir, String pathName) {
for (Iterator<File> it = FileHelper.listSubDir(dir).iterator(); it.hasNext();) {
File file = it.next();
if (file.getName().endsWith(pathName)) {
return file;
}
}
return null;
}
/**
* <p>
* 检查导入文件夹下是否是规定的文件
* </p>
*/
public static boolean checkFile(File dir, String fileName) {
List<String> files = listFiles(dir);
for (String temp : files )
if (temp.equals(fileName))
return true;
return false;
}
/**
* 拷贝一个文件夹下指定类型的文件到另外一个文件夹
*
* @param suffix
* @param dirName
* @param toDirName
* @param isCut
* 是否剪切
*/
public static void copyFilesInDir(String suffix, File fromDir, File toDir, boolean isCut) {
if (!fromDir.exists()) {
throw new BusinessException("拷贝文件夹中的文件时出错,源文件夹(" + fromDir.getPath() + ")不存在!");
}
List<String> list = listFilesByType(suffix, fromDir);
if (!toDir.exists()) {
toDir.mkdir();
}
for (Iterator<String> it = list.iterator(); it.hasNext();) {
String fileName = (String) it.next();
File file = new File(fromDir.getPath() + "/" + fileName);
if (file.isDirectory()) {
copyFilesInDir(suffix, file, new File(toDir.getPath() + "/" + fileName), isCut);
}
else {
copyFile(toDir, file, true, false);
}
}
if (isCut) {
deleteFilesInDir("", fromDir);
}
}
/**
* 复制整个文件夹的内容
*
* @return
*/
public static void copyFolder(String fromDir, String toDir) {
copyFolder(new File(fromDir), new File(toDir));
}
public static void copyFolder(File fromDir, File toDir) {
copyFilesInDir("", fromDir, toDir, false);
}
/**
* 删除文件夹下指定类型的文件,如果文件夹为空,则删除该文件夹
*
* @param suffix
* @param dir
*/
public static void deleteFilesInDir(String suffix, File dir) {
if (dir.exists()) {
List<String> list = listFilesByType(suffix, dir);
for (Iterator<String> it = list.iterator(); it.hasNext();) {
String fileName = (String) it.next();
File file = new File(dir.getPath() + "/" + fileName);
if (file.isDirectory()) {
deleteFilesInDir(suffix, file);
} else {
file.delete();
}
}
if (dir.list().length == 0) {
dir.delete();
}
}
}
/**
* 删除文件或文件夹
* @param File
*/
public static void deleteFile(File file) {
if(file.isFile()) {
file.delete();
}
else if(file.isDirectory()) {
deleteFilesInDir("", file);
}
}
/**
* 压缩文件。
* @param destPath
* @param srcFile
* @return
*/
public static String exportZip(String destFileName, File sourceFile){
String zipFileName = destFileName + "/" + sourceFile.getName() + ".zip";
ZipOutputStream out = null;
try {
out = new ZipOutputStream(new FileOutputStream(zipFileName));
File[] fileList = sourceFile.listFiles();
for (int i = 0; i < fileList.length; i++)
exportZip(out, fileList[i], fileList[i].getName());
} catch (Exception e) {
throw new BusinessException("压缩文件时出错!", e);
} finally {
try {
out.close();
} catch (IOException e) {
throw new BusinessException("压缩完关闭输出流时出错!", e);
}
}
return zipFileName;
}
private static void exportZip(ZipOutputStream out, File f, String base) throws Exception{
if(f.isDirectory()) { //如果是目录
File[] fl = f.listFiles();
out.putNextEntry(new ZipEntry(base + "/"));
base = base.length() == 0 ? "" : base + "/";
for (int i = 0; i < fl.length; i++) {
exportZip(out, fl[i], base + fl[i].getName());
}
} else {
out.putNextEntry(new ZipEntry(base));
FileInputStream in = new FileInputStream(f);
int b;
while ((b = in.read()) != -1) {
out.write(b);
}
in.close();
}
}
/**
* 得到文件后缀
* @param fileName
* @return
*/
public static String getFileSuffix(String fileName) {
if (null == fileName)
return null;
int index = fileName.lastIndexOf(".");
if (index > -1)
return fileName.substring(index + 1);
return "";
}
/**
* 得到文件名称(不带后缀名)
* @param fileName
* @return
*/
public static String getFileNameNoSuffix(String fileName) {
if (null == fileName)
return null;
int index = fileName.lastIndexOf(".");
if (index > -1)
return fileName.substring(0, index);
return fileName;
}
/**
* 解压缩文件处理
* @param zipFileName
* @param destDir
* @return
*/
public static String unZip(File zipFileName, String destDir) {
int index = zipFileName.getName().lastIndexOf(".");
String name = zipFileName.getName().substring(0, index);
Expand expand = new Expand();
expand.setSrc(zipFileName);
expand.setOverwrite(false);
File newPath = new File(destDir + "/" + name);
expand.setDest(newPath);
expand.setProject(new Project());
expand.execute();
return newPath.getPath();
}
/**
* <p>
* 覆盖原有文件
* </p>
*
* @param src
* 源文件
* @param file
* 要覆盖文件的路径
* @return
*/
public static void wirteOldFile(String src, File file, String fileName) {
InputStream inStream = null;
FileOutputStream outStream = null;
inStream = (InputStream) (new ByteArrayInputStream(src.getBytes()));
try {
outStream = new FileOutputStream(file.toString() + fileName);
} catch (FileNotFoundException e) {
try {
inStream.close();
} catch (IOException e1) {
throw new BusinessException("输入流关闭失败", e1);
}
throw new BusinessException("文件未找到:" + fileName, e);
}
int byteread = 0;
byte[] buffer = new byte[256];
try {
while ((byteread = inStream.read(buffer)) != -1) {
outStream.write(buffer, 0, byteread);
}
} catch (IOException e) {
throw new BusinessException("数据流读写失败", e);
} finally {
try {
if(inStream != null)
inStream.close();
} catch (IOException e) {
throw new BusinessException("输入流关闭失败", e);
} finally {
try {
if(outStream != null)
outStream.close();
} catch (IOException e) {
throw new BusinessException("输出流关闭失败", e);
}
}
}
}
/**
* <p>
* 创建文件夹
* </p>
* @param path
* 文件夹路径
*/
public static File createDir(String path) {
File file = new File(path);
if ( !file.exists() ) {
file.mkdirs();
}
return file;
}
/**
* 获取文件的扩展名
* @param filename
* @return
*/
public static String getFileExtension(String filename) {
int index = filename.lastIndexOf(".");
if(index != -1) {
return filename.substring(index + 1);
}
return "";
}
/**
* 重命名文件名
* @param filePath
* @param newName
*/
public static boolean renameFile(String filePath, String newName) {
URL url = URLUtil.getResourceFileUrl(filePath);
if(url != null) {
File file = new File(url.getFile());
return file.renameTo(new File(file.getParent() + "/" + newName));
}
return false;
}
/**
* 判断文件目录是否文件夹。
* @param dir
* @param fileName
* @return
*/
public static boolean isFolder(File dir, String fileName){
if(dir == null || fileName == null) {
return false;
}
File file = new File(dir.getPath() + "/" + fileName);
return file.isDirectory();
}
/**
* 使用http请求下载附件。
* @param sourceFilePath 导出文件路径
* @param exportName 导出名字
*/
public static void downloadFileByHttp(String sourceFilePath, String exportName) {
HttpServletResponse response = Context.getResponse();
response.reset(); // 设置附件下载页面
response.setContentType("application/octet-stream"); // 设置附件类型
response.setContentLength((int) new File(sourceFilePath).length()); // 文件长度
response.setHeader("Content-Disposition", "attachment; filename=\"" + exportName + "\""); // 设置标头
InputStream inStream = null;
OutputStream outStream = null;
try {
outStream = response.getOutputStream();
inStream = new FileInputStream(sourceFilePath);
int len = 0;
byte[] b = new byte[1024];
while ((len = inStream.read(b)) != -1) {
outStream.write(b, 0, len);
outStream.flush();
}
} catch (IOException e) {
throw new BusinessException("导出时发生IOException!!", e);
} finally{
try {
if(inStream != null){
inStream.close();
}
if(outStream != null){
outStream.close();
}
outStream.close();
} catch (IOException e) {
throw new BusinessException("导出时发生IOException!!", e);
}
}
new File(sourceFilePath).delete(); // 删除资源文件夹下面的zip文件
}
}