[TOC]
前言
我相信你在写代码的时候肯定需要复制文件,甚至是移动文件,实质就是IO操作,我这里先从文件的复制开始,后面讲解文件的移动。该代码在我现在开发的实际项目中正在使用,你拿到代码也可以直接调用。
文件复制
核心代码就是BufferedInputStream
和BufferedOutputStream
,根据API介绍可以得知
我们使用构造方法摘要的第一个就可以了,因为我只需要输入流即可。
public static void copyFile(InputStream image, String targetAddr,String fileName) throws IOException {
BufferedInputStream inBuff = null;
BufferedOutputStream outBuff = null;
try {
// 判断文件夹是否存在
makeDirPath(targetAddr);
// 新建文件输入流并对它进行缓冲
File targetFile=new File(targetAddr+fileName);
inBuff = new BufferedInputStream(image);
// 新建文件输出流并对它进行缓冲
outBuff = new BufferedOutputStream(new FileOutputStream(targetFile));
// 缓冲数组
byte[] b = new byte[1024 * 5];
int len;
while ((len = inBuff.read(b)) != -1) {
outBuff.write(b, 0, len);
}
// 刷新此缓冲的输出流
outBuff.flush();
} finally {
// 关闭流
if (inBuff != null)
inBuff.close();
if (outBuff != null)
outBuff.close();
}
}
怎么样!是不是很简单,那我们再加一点点难度,比如我想指定文件扩展名,也就是文件后缀格式(虽然这挺没有必要的),于是我们可以这么写:
public static void copyFileA(InputStream image, String targetAddr,String fileName,String extension) throws IOException {
BufferedInputStream inBuff = null;
BufferedOutputStream outBuff = null;
try {
// 新建文件输入流并对它进行缓冲
File targetFile=new File(targetAddr+fileName+extension);
inBuff = new BufferedInputStream(image);
// 新建文件输出流并对它进行缓冲
outBuff = new BufferedOutputStream(new FileOutputStream(targetFile));
// 缓冲数组
byte[] b = new byte[1024 * 5];
int len;
while ((len = inBuff.read(b)) != -1) {
outBuff.write(b, 0, len);
}
// 刷新此缓冲的输出流
outBuff.flush();
} finally {
// 关闭流
if (inBuff != null)
inBuff.close();
if (outBuff != null)
outBuff.close();
}
}
在复制的时候我有一个函数是判断文件夹是否存在的,代码很简短,也很实用,可以直接使用:
private static void makeDirPath(String targetAddr) {
String realFileParentPath = targetAddr;
File dirPath = new File(realFileParentPath);
if (!dirPath.exists()) {
dirPath.mkdirs();
}
}
讲解
总共没几行代码,但是有一个比较重要的部分我想着重强调一下作用是什么,就是注释为缓冲数组
的的部分,首先我们拿到一个文件的时候,其实就是一串字符流而已,再白话一点,就是一串数字,接下来我们新建了一个文件,这个文件和刚刚的文件应该是一模一样的,但是我们做不到一次性全抄下来,先找了一个白纸写下一部分,然后再往最终目的地输送,直至没有数据了。
文件移动
我以前总是这样想的,如果我会了文件的复制和删除,那么,移动就好办了,就是先复制一份,再删除咯。实际上有个方法可以直接实现,就是renameTo
代码
public static void moveTotherFolders(String pathName,String fileName,String endPath){
String startPath = pathName + File.separator + fileName;
try {
File startFile = new File(startPath);
File tmpFile = new File(endPath);//获取文件夹路径
if(!tmpFile.exists()){//判断文件夹是否创建,没有创建则创建新文件夹
tmpFile.mkdirs();
}
System.out.println(endPath + startFile.getName());
if (startFile.renameTo(new File(endPath + startFile.getName()))) {
MiLog.WriteLog("MOVE_FILE", "文件移动成功!文件名:《"+fileName+"》 目标路径:{"+endPath+"}");
} else {
MiLog.WriteLog("MOVE_FILE", "文件移动失败!文件名:《"+fileName+"》 起始路径:{"+startPath+"}");
}
} catch (Exception e) {
MiLog.WriteLog("MOVE_FILE", "文件移动失败!文件名:《"+fileName+"》 起始路径:{"+startPath+"}");
}
}
上面的代码里,写日志的部分是我自己加的,这部分代码我以前也展示过,就是我自己造的轮子,也源于我之前工作单位的代码改造而来的。就是两个路径的转换,也比较简单。
文件删除
文件删除就更简单了,判断一下是否存在,然后 delete 就可以了,在windows系统当中,删除就是删除文件名而已,所以通常来说速度都是很快的。
public static void deleteFileOrPath(String storePath) {
File fileOrPath = new File(storePath);
if (fileOrPath.exists()) {
if (fileOrPath.isDirectory()) {
File files[] = fileOrPath.listFiles();
for (int i = 0; i < files.length; i++) {
files[i].delete();
}
}
fileOrPath.delete();
}
}
总结
字符流的IO是最基本的操作,也是基础中的基础,这有助于我们理解代码是什么,文件是什么,我们传送的,复制的,删除的又是什么,我相信很多小伙伴早就会了,我只是帮忙复习了一遍,总结了一下,最开始的时候,我对文件的操作总是很头疼,因为我总是在想,Web是怎么操作文件的,让我很不理解,后来才发现原来文件根本没在Web上,而是一直在本地或者在服务器的磁盘上,所以操作文件就变成了操作本地的文件地址,于是系统中存文件的时候,大部分都是存文件的路径,而不是真的把文件存到数据库。