/**
* 文件操作大全(文件接口均是使用文件路径名)
* 1)创建文件
* 2)删除文件
* 3)移动文件
* 4)合并文件
* 5)分割文件
* 6)读取文件
* 7)列举文件
* @author Sking
*/
package file;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.RandomAccessFile;
import java.io.Reader;
import java.util.Random;
public class FileUtil {
/***-----------1.创建文件---------***/
/**
* 创建指定文件或目录,成功创建则返回true,否则false,
* 如果指定文件或目录的父目录不存在,则递归创建父目录。
* @param destFile 待创建的指定文件或目录
* @return 成功创建指定文件或目录则返回true,
* 如果目标文件或目录已存在或创建失败,返回false。
*/
public static boolean createFile(String destFile) {
File file = new File(destFile);
if (file.exists()) { //判断该文件是否存在
System.out.println("目标文件已存在!");
return false;//目标文件存在,返回false
}
//目标文件名是以文件分隔符结尾的,则为目录
if (destFile.endsWith(File.separator)) {
if(file.mkdirs()){
System.out.println("目录创建成功!");
return true;
}
}
//判断目标文件所在的目录是否存在
if (!file.getParentFile().exists()) {
//如果目标文件父目录不存在,则创建父目录
System.out.println("父目录不存在,正在创建!");
//递归创建父目录,如果创建失败则返回false
if (!file.getParentFile().mkdirs()) {
System.out.println("父目录创建失败!");
return false;
}
}
//创建目标文件
try {
if (file.createNewFile()) {
System.out.println("创建文件成功!");
return true;
} else {
System.out.println("创建文件失败!");
return false;
}
} catch (IOException e) {
e.printStackTrace();
System.out.println("创建文件失败!" + e.getMessage());
return false;
}
}
/***-----------2.删除文件---------***/
/**
* 删除指定的目录或文件,如果目录不为空则递归删除,
* 成功删除返回true,否则返回false。
* @param fileName 待删除的文件或目录
* @return 成功删除指定的文件或目录返回true,否则返回false
*/
public static boolean deleteFileOrDir(String fileName) {
File file = new File(fileName);
if (!file.exists()) {
System.out.println("待删除的目标文件不存在!");
return false;
} else {
if (file.isFile()) {//删除文件
return deleteFile(fileName);
} else {//删除目录
return deleteDir(fileName);
}
}
}
/**
* 删除指定文件,成功则返回true,否则返回false
* @param fileName 待删除文件
* @return 成功删除指定文件返回true,否则返回false
*/
public static boolean deleteFile(String fileName) {
File file = new File(fileName);
if (file.exists() && file.isFile()) {//文件存在
if (file.delete()) {
System.out.println("文件:" + fileName + "删除成功!");
return true;
} else {
System.out.println("文件" + fileName + "删除失败!");
return false;
}
} else {
System.out.println("待删除文件不存在!");
return false;
}
}
/**
* 递归删除指定目录,成功则返回true,否则返回false
* @param dir 待删除目录
* @return 成功删除指定目录返回true,否则返回false
*/
public static boolean deleteDir(String dir) {
//如果dir不以文件名称分隔符结尾,自动添加文件分隔符。
if (!dir.endsWith(File.separator)) {
dir = dir + File.separator;
}
File dirFile = new File(dir);
//文件不存在,或者不是一个目录,返回false
if (!dirFile.exists() || (!dirFile.isDirectory())) {
System.out.println("待删除目录不存在!");
return false;
}
boolean flag = true;
//递归删除子目录或文件
File[] files = dirFile.listFiles();//目录下抽象路径名数组
for (int i = 0; i < files.length; i++) {
if (files[i].isFile()) {//文件
flag = deleteFile(files[i].getAbsolutePath());
if (!flag) {
break;//遇到一次不成功操作则直接退出,返回false
}
}
else if (files[i].isDirectory()) {//子目录
flag = deleteDir(files[i].getAbsolutePath());
if (!flag) {
break;
}
}
}
if (!flag) {
System.out.println("删除目录失败!");
return false;
}
//删除当前目录
if (dirFile.delete()) {
System.out.println("目录:" + dir + "删除成功!");
return true;
} else {
return false;
}
}
/***-----------3.分割文件---------***/
/**
* 分割文件操作
* @param name 待分割的文件名
* @param size 分割后的小文件大小,字节为单位,
* 如果为负数,则默认大小为源文件的一半。
* @return 分割后的文件路径名数组
* @throws Exception 指定文件不存在,抛出异常
*/
public static String[] divide(String name, long size) throws Exception {
File file = new File(name);
if (!file.exists() || (!file.isFile())) {
throw new Exception("指定文件不存在!");
}
File parentFile = file.getParentFile();// 父目录抽象路径
long fileLength = file.length();
if (size <= 0) {
size = fileLength / 2;
}
int num=(int)(fileLength/size);
if(fileLength % size != 0)
num++;//分割后的小文件个数
String[] fileNames = new String[num];
FileInputStream in = new FileInputStream(file);
long end = 0;
int begin = 0;
// 根据要分割的数目输出文件
int index=file.getName().lastIndexOf('.');
String suffix=file.getName().substring(index);//文件后缀
for (int i = 0; i < num; i++) {
String fileName=file.getName().substring(0,index)+i+suffix;
File outFile = new File(parentFile, fileName);
FileOutputStream out = new FileOutputStream(outFile);
end += size;//将结束下标后移size
end = (end > fileLength) ? fileLength : end;
for (; begin < end; begin++) {
out.write(in.read());
}
out.close();
fileNames[i] = outFile.getAbsolutePath();
}
in.close();
return fileNames;
}
/***-----------4.合并文件---------***/
/**
* 合并文件操作
* @param fileNames 待合并的文件路径名列表
* @param TargetFileName 合并后文件的路径名
* @throws Exception IO异常
*/
public static void merge(String[] fileNames, String TargetFileName)
throws Exception{
File fin = null;
File fout = new File(TargetFileName);
FileOutputStream out = new FileOutputStream(fout);
for (int i = 0; i < fileNames.length; i++) {
fin = new File(fileNames[i]);
FileInputStream in = new FileInputStream(fin);
int c;
while ((c = in.read()) != -1) {
out.write(c);
}
in.close();
}
out.close();
}
/***-----------5.移动文件---------***/
/**
* 移动指定的文件,已存在目标文件则不覆盖
* @param sourceFileName 源文件
* @param targetFileName 目标文件
* @return 移动成功则返回true,否则false
*/
public static boolean moveFile(String sourceFileName, String targetFileName) {
return moveFile(sourceFileName, targetFileName, false);
}
/**
* 移动源文件sourceFile到目标文件targetFile,
* 根据isOverlay选择在目标文件已存在情况下是否进行覆盖
* @param sourceFile 源文件
* @param targetFile 目标文件
* @param isOverlay 是否进行覆盖的标志
* @return 如果成功移动文件返回true,否则返回false
*/
public static boolean moveFile(String sourceFile, String targetFile,
boolean isOverlay) {
// 判断原文件是否存在
File source = new File(sourceFile);
if (!source.exists()) {
System.out.println("源文件不存在!");
return false;
} else if (!source.isFile()) {
System.out.println("源文件不是文件!");
return false;
}
File target = new File(targetFile);
if (target.exists()) {//目标文件是否存在
if (isOverlay) {//目标文件存在,允许覆盖目标文件
// 删除已存在的目标文件,无论目标文件是目录还是文件
System.out.println("目标文件已存在,准备删除它!");
if (!deleteFileOrDir(targetFile)) {
System.out.println("目标文件删除失败");
return false;
}
} else {//目标文件已存在,且不进行覆盖,则返回false
System.out.println("文件移动失败,目标文件已存在!");
return false;
}
} else {
if (!target.getParentFile().exists()) {
// 如果目标文件父目录不存在,则创建目录
System.out.println("目标文件父目录不存在,正在创建!");
if (!target.getParentFile().mkdirs()) {
System.out.println("创建目标文件父目录失败!");
return false;
}
}
}
// 调用函数renameTo()移动原文件至目标文件
if (source.renameTo(target)) {
System.out.println("移动文件成功!");
return true;
} else {
System.out.println("移动文件失败!");
return false;
}
}
/**
*移动源目录到目标目录,不覆盖已存在目录
* @param sourceDirName 源目录
* @param targetDirName 目标目录
* @return 成功移动目录则返回true,否则返回false
*/
public static boolean moveDir(String sourceDirName, String targetDirName) {
return moveDir(sourceDirName, targetDirName, false);
}
/**
* 移动源目录到目标目录,根据标志 isOverlay确定是否覆盖已存在目录
* @param sourceDirName 源目录
* @param targetDirName 目标目录
* @param isOverlay 是否覆盖已存在目录的标志
* @return 成功移动则返回true,否则返回false
*/
public static boolean moveDir(String sourceDirName, String targetDirName,
boolean isOverlay) {
// 判断原目录是否存在
File sourceDir = new File(sourceDirName);
if (!sourceDir.exists()) {
System.out.println("原始目录不存在!");
return false;
} else if (!sourceDir.isDirectory()) {
System.out.println("源不是目录!");
return false;
}
//自动添加文件分隔符
if (!targetDirName.endsWith(File.separator)) {
targetDirName = targetDirName + File.separator;
}
File targetDir = new File(targetDirName);
if (targetDir.exists()) {//目标文件夹存在,
if (isOverlay) {//是否覆盖
System.out.println("目录已存在,准备删除它!");
if (!deleteFileOrDir(targetDirName)) {
System.out.println("删除已存在目录失败!");
}
} else {
System.out.println("目录已存在!");
return false;
}
} else {// 创建目标目录
System.out.println("该目录不存在,正在创建!");
if (!targetDir.mkdirs()) {
System.out.println("创建目标目录失败!");
return false;
}
}
boolean flag = true;
//移动原目录下的文件和子目录到目标目录下
File[] files = sourceDir.listFiles();
for (int i = 0; i < files.length; i++) {
if (files[i].isFile()) {// 移动子文件
//构造移动后新生成的文件路径
flag = moveFile(files[i].getAbsolutePath(),
targetDirName + files[i].getName(), isOverlay);
if (!flag) {
break;
}
}
else if (files[i].isDirectory()) {// 移动子目录
flag = moveDir(files[i].getAbsolutePath(), targetDirName
+ files[i].getName(), isOverlay);
if (!flag) {
break;
}
}
}
if (!flag) {
System.out.println("目录移动失败!");
return false;
}
// 删除原目录
if (deleteDir(sourceDirName)) {
System.out.println("目录移动成功!");
return true;
} else {
System.out.println("目录移动失败!");
return false;
}
}
/***-----------6.列举文件---------***/
/**
* 打印指定目录的目录结构
* @param dirName 指定目录
* @param deep 深度,实现缩进打印
*/
public static void getAllFiles(String dirName, int deep) {
//如果dir不以文件分隔符结尾,自动添加文件分隔符。
if (!dirName.endsWith(File.separator)) {
dirName = dirName + File.separator;
}
File dirFile = new File(dirName);
//文件不存在,或不是目录,则退出
if (!dirFile.exists() || (!dirFile.isDirectory())) {
System.out.println("找不到指定目录");
return;
}
//列出目录下所有文件(包括子目录)
File[] fileArray = dirFile.listFiles();
for (int i = 0; i < fileArray.length; i++) {
if (fileArray[i].isFile()) {
// 只打印文件名,而非完整路径
print(deep, fileArray[i].getName());
} else if (fileArray[i].isDirectory()) {
print(deep, fileArray[i].getName());//目录
getAllFiles(fileArray[i].getAbsolutePath(), deep + 1);
}
}
}
/**
* 实现层次缩进打印目录结构
* @param deep 深度
* @param msg 消息
*/
private static void print(int deep, String msg) {
for (int i = 1; i <= deep; i++)
System.out.print(" ");
System.out.println(msg);
}
/***-----------7.读取文件---------***/
/**1. 按字节读取文件,常用于读二进制文件,如图片、声音、影像文件等*/
/**
* 1.1 按字节读取文件, 一次读取一个字节
* @param fileName 文件路径名
*/
public static void readFileByByte(String fileName) {
File file = new File(fileName);
FileInputStream in = null;
try {
in = new FileInputStream(file);
int tempbyte;
//一次读取一个字节的方式
while ((tempbyte = in.read()) != -1) {
System.out.write(tempbyte);
}
in.close();
} catch (IOException e) {
e.printStackTrace();
return;
}finally {
if (in != null) {
try {
in.close();
} catch (IOException e1) {
}
}
}
}
/**
* 1.2 按字节读取文件, 一次读取多个字节
* @param fileName 文件路径名
*/
public static void readFileByBytes(String fileName) {
File file = new File(fileName);
FileInputStream in = null;
try {
in = new FileInputStream(file);
// 一次读取多个字节的方式
byte[] tempbytes = new byte[100];
int byteread = 0;
in = new FileInputStream(fileName);
// 读入多个字节到字节数组中,byteread为一次读入的字节数
while ((byteread = in.read(tempbytes)) != -1) {
System.out.write(tempbytes, 0, byteread);
}
} catch (Exception e1) {
e1.printStackTrace();
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e1) {
}
}
}
}
/**2. 以字符为单位读取文件,常用于读文本,数字等类型文件*/
/**
* 2.1 以字符为单位读取文件,一次读取一个字符
* @param fileName 文件路径名
*/
public static void readFileByChar(String fileName) {
File file = new File(fileName);
Reader reader = null;
try {
reader = new InputStreamReader(new FileInputStream(file));
int tempchar;
//一次读一个字符
while ((tempchar = reader.read()) != -1) {
// 对于windows下,\r\n这两个字符在一起时,表示一个换行。
// 但如果这两个字符分开显示时,会换两次行。
// 因此,屏蔽掉\r,或者屏蔽\n。否则,将会多出很多空行。
if (((char) tempchar) != '\r') {
System.out.print((char) tempchar);
}
}
reader.close();
} catch (Exception e) {
e.printStackTrace();
}finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e1) {
}
}
}
}
/**
* 2.2 以字符为单位读取文件,一次读取多个字符
* @param fileName 文件路径名
*/
public static void readFileByChars(String fileName) {
File file = new File(fileName);
Reader reader = null;
try {
reader = new InputStreamReader(new FileInputStream(file));
// 一次读多个字符
char[] tempchars = new char[30];
int charread = 0;
reader = new InputStreamReader(new FileInputStream(fileName));
// 读入多个字符到字符数组中,charread为一次读取字符数
while ((charread = reader.read(tempchars)) != -1) {
// 同样屏蔽掉\r不显示
if ((charread == tempchars.length)
&& (tempchars[tempchars.length - 1] != '\r')) {
System.out.print(tempchars);
} else {
for (int i = 0; i < charread; i++) {
if (tempchars[i] == '\r') {
continue;
} else {
System.out.print(tempchars[i]);
}
}
}
}
} catch (Exception e1) {
e1.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e1) {
}
}
}
}
/**
* 3. 以行为单位读取文件,常用于读面向行的格式化文件
* @param fileName 文件路径名
*/
public static void readFileByLines(String fileName) {
File file = new File(fileName);
BufferedReader reader = null;
try {
reader = new BufferedReader(new FileReader(file));
String tempString = null;
int line = 1;
// 一次读入一行,直到读入null为文件结束
while ((tempString = reader.readLine()) != null) {
// 显示行号
System.out.println("line " + line + ": " + tempString);
line++;
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e1) {
}
}
}
}
/**
* 4. 随机读取文件内容
* @param fileName 文件路径名
*/
public static void readFileByRandomAccess(String fileName) {
RandomAccessFile randomFile = null;
try {
// 打开一个随机访问文件流,按只读方式
randomFile = new RandomAccessFile(fileName, "r");
// 文件长度,字节数
long fileLength = randomFile.length();
// 读文件的起始位置
Random r=new Random();
//随机初始读取位置
int beginIndex=r.nextInt((int)fileLength);
// 将读文件的开始位置移到beginIndex位置。
randomFile.seek(beginIndex);
byte[] bytes = new byte[10];
int byteread = 0;
// 一次读10个字节,如果文件内容不足10个字节,则读剩下的字节。
// 将一次读取的字节数赋给byteread
while ((byteread = randomFile.read(bytes)) != -1) {
System.out.write(bytes, 0, byteread);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (randomFile != null) {
try {
randomFile.close();
} catch (IOException e1) {
}
}
}
}
}