使用jdk7的nio2操作文件拷贝和剪切示例
package com.xyq.io.simply.core;
import java.io.file;
import java.io.ioexception;
import java.nio.file.filevisitresult;
import java.nio.file.filevisitor;
import java.nio.file.files;
import java.nio.file.path;
import java.nio.file.paths;
import java.nio.file.standardcopyoption;
import java.nio.file.attribute.basicfileattributes;
import java.util.arraylist;
import java.util.list;
import com.xyq.io.enums.filetypemode;
import com.xyq.io.enums.optionfile_type;
import com.xyq.io.inf.newnioinf;
import com.xyq.io.util.findfileutil;
import com.xyq.io.util.md5util;
public class newnio implements newnioinf {
/***
* 拷贝或者移动文件
*/
@override
public boolean copeormovefile(string src, string tar, optionfile_type type) {
return realcopeormovefile(paths.get(src), tar, type);
}
private boolean realcopeormovefile(path srcpath, string tar,
optionfile_type type) {
path tarpath = null;
boolean copesuccess = true;
// 必须原始文件存在
if (srcpath.tofile().exists()) {
/***
* 如果原始路径是带斜杠的那么就认为这是一个文件夹
*/
if (isdir(tar))
tarpath = paths.get(tar + file.separator
+ srcpath.tofile().getname());
else
tarpath = paths.get(tar);
/***
* 然后进行n次(可以作为参数)拷贝操作(出错重连),是否覆盖拷贝,拷贝属性,拷贝操作不能使用回滚选项
*/
for (int i = 0; i < 3; i++) {
/***
* 如果是目标文件已经存在
*/
if (tarpath.tofile().exists()) {
/***
* 如果验证两个文件夹是相同的,拷贝选项下就不用拷贝,移动选项下就是删除原始文件
*/
// 拷贝
if (optionfile_type.cope.equals(type)) {
if (equalsfile(srcpath.tofile(), tarpath.tofile()))
return true;
else
copesuccess = copefile(srcpath, tarpath, true);
}
/***
* 移动操作,这里得非常小心,正常情况下,如果两个文件是一样的话,
* 那么直接删除原始文件就可以了。但是,如果两个文件的一样,并且地址也
* 是一样的话,那么就不能删除原始的了,因为就是同一个文件,不能删除的。
*/
else if (optionfile_type.move.equals(type)) {
if (equalsfile(srcpath.tofile(), tarpath.tofile())) {
if (!srcpath.tofile().getabsolutefile()
.equals(tarpath.tofile().getabsolutefile()))
try {
files.delete(srcpath);
/***
* 之所以要手动指向true,是因为可能存在前面删除失败的情况
*/
if (!copesuccess)
copesuccess = true;
} catch (ioexception e) {
copesuccess = false;
}
// 前面因为有异常的可能就不直接return,这里就可以了
else
return true;
} else
copesuccess = movefile(srcpath, tarpath);
}
}
/***
* 当目标文件不存在的时候,先判断父类文件夹是可创 建(父类文件夹存在或者可以创建),可创建时就创建
*/
else {
file par = tarpath.getparent().tofile();
/***
* 如果父类文件夹不存在并且无法创建,那么就不用拷贝了
*/
if (!par.exists() && !par.mkdirs())
copesuccess = false;
else if (optionfile_type.cope.equals(type))
copesuccess = copefile(srcpath, tarpath, false);
else if (optionfile_type.move.equals(type))
copesuccess = movefile(srcpath, tarpath);
}
// 如果操作成功,跳出循环
if (copesuccess)
break;
}
} else
copesuccess = false;
return copesuccess;
}
/****
* 拷贝文件
*/
private boolean copefile(path srcpath, path tarpath, boolean isexist) {
if (isexist)
try {
files.copy(srcpath, tarpath,
standardcopyoption.replace_existing,
standardcopyoption.copy_attributes);
} catch (ioexception e) {
return false;
}
else
try {
files.copy(srcpath, tarpath, standardcopyoption.copy_attributes);
} catch (ioexception e) {
return false;
}
return true;
}
/***
* 移动文件,不能使用属性选项
*
* @param srcpath
* @param tarpath
* @return
*/
private boolean movefile(path srcpath, path tarpath) {
try {
files.move(srcpath, tarpath, standardcopyoption.atomic_move);
} catch (ioexception e) {
return false;
}
return true;
}
/***
* 判断path路径是否是一个文件夹
*
* @param path
* @return
*/
private boolean isdir(string path) {
char lastc = path.charat(path.length() - 1);
if (lastc == '\\' || lastc == '/')
return true;
return false;
}
/***
* 这是来验证两个文件是否相同,只是简单验证,可以强制必须使用md5进行验证
*/
public boolean equalsfile(file src, file tar) {
// 如果两个文件的长度不一样,那么肯定两个文件是不一样的
if (src.length() != tar.length())
return false;
if (!src.getname().equals(tar.getname())
|| src.lastmodified() != tar.lastmodified())
return md5util.encoderfilebymd5(src).equals(
md5util.encoderfilebymd5(tar));
return true;
}
/***
* 拷贝或者移动文件夹
*/
@override
public void copeormovedirectory(string src, final string tar, int tiersize,
final optionfile_type type) {
if (!new file(src).exists())
throw new runtimeexception("找不到原始文件夹" + src);
final int rootpos = getrootposition(new file(src), tiersize);
if (rootpos != -1) {
try {
files.walkfiletree(paths.get(src), new filevisitor<path>() {
string tardirstring = null;
/***
* 到达文件夹前,先把目标路径写好
*
* @param dir
* @param attrs
* @return
* @throws ioexception
*/
@override
public filevisitresult previsitdirectory(path dir,
basicfileattributes attrs) throws ioexception {
tardirstring = dir.tofile().getabsolutepath();
tardirstring = tar + tardirstring.substring(rootpos)
+ file.separator;
return filevisitresult.continue;
}
/***
* 到达文件之后,进行拷贝或者移动操作
*
* @param file
* @param attrs
* @return
* @throws ioexception
*/
@override
public filevisitresult visitfile(path file,
basicfileattributes attrs) throws ioexception {
file f = file.tofile();
if (f.exists() && f.canread() && !f.ishidden())
realcopeormovefile(file, tardirstring, type);
return filevisitresult.continue;
}
@override
public filevisitresult visitfilefailed(path file,
ioexception exc) throws ioexception {
return filevisitresult.continue;
}
/***
* 到达文件夹后
*
* @param dir
* @param exc
* @return
* @throws ioexception
*/
@override
public filevisitresult postvisitdirectory(path dir,
ioexception exc) throws ioexception {
return filevisitresult.continue;
}
});
} catch (exception e) {
e.printstacktrace();
}
// 如果是剪切操作,并且剪切成功,那么就要删除所有文件夹
if (optionfile_type.move.equals(type) && isblockdir(src))
deldir(src);
} else
throw new runtimeexception("指定父类文件夹层次错误~~~");
}
/***
* 根据指定层次获取指定盘符的位置
*/
private int getrootposition(file file, int tier) {
if (file != null) {
string path = file.getabsolutepath();
int cc = 0;
for (int i = path.length() - 1; i >= 0; i--) {
if (path.charat(i) == '\\') {
cc++;
if (cc == tier + 1) {
cc = i;
return cc;
}
}
}
}
return -1;
}
/***
* 查看该文件夹下是否还有文件
*
* @param dirpath
* @return
*/
private boolean isblockdir(string dirpath) {
file dir = new file(dirpath);
file[] dirlist = dir.listfiles();
if (dirlist == null || dirlist.length == 0)
return true;
else {
// 寻找文件
for (file f : dirlist)
if (!f.isdirectory())
return false;
}
return true;
}
/***
* 删除空文件夹
*
* @param dirpath
*/
private void deldir(string dirpath) {
file dir = new file(dirpath);
file[] dirlist = dir.listfiles();
if (dirlist == null || dirlist.length == 0)
dir.delete();
else {
// 删除所有文件
for (file f : dirlist)
if (f.isdirectory())
deldir(f.getabsolutepath());
else
f.delete();
// 删除完当前文件夹下所有文件后删除文件夹
dirlist = dir.listfiles();
if (dirlist.length == 0)
dir.delete();
}
}
/***
* 根据文件类型查找相关的文件
*/
@override
public list<string> findfilesbytype(string dir, string[] keys,
boolean ismatchcase) throws ioexception {
list<string> list = new arraylist<string>();
files.walkfiletree(paths.get(dir), new findfileutil(keys, ismatchcase,
list, filetypemode.types));
return list;
}
/***
* 根据文件名称查找相关的文件
*/
@override
public list<string> findfilesbyname(string dir, string[] keys,
boolean ismatchcase) throws ioexception {
list<string> list = new arraylist<string>();
files.walkfiletree(paths.get(dir), new findfileutil(keys, ismatchcase,
list, filetypemode.names));
return list;
}
public static void main(string[] args) throws ioexception {
newnioinf inf = new newnio();
inf.copeormovefile("e:/cc/dd/11.txt", "e:/xx/xxx/zzz/",
optionfile_type.cope);
inf.copeormovedirectory("e:\\bb\\cc\\dd", "e:\\",1, optionfile_type.move);
system.out.println(inf.findfilesbyname("d:\\workspace", new string[] { "txt" },
false).size());
}
}
---------------------------
package com.xyq.io.enums;
/***
* 文件类型
* @author xyq
*
*/
public enum filetypemode {
types,names
}
---------------------------------
package com.xyq.io.enums;
/***
* 操作文件的类型
* @author xyq
*
*/
public enum optionfile_type {
cope,move;
}
---------------------
package com.xyq.io.inf;
import java.io.ioexception;
import java.util.list;
import com.xyq.io.enums.optionfile_type;
public interface newnioinf {
/***
* 拷贝或者移动文件
* @param src
* @param tar
* @return
*/
public boolean copeormovefile(string src,string tar,optionfile_type type);
/***
* 拷贝或者移动文件夹
* @param src
* @param tar
* @param tiersize 层次,拷贝完成后的路径0只是当前文件夹,+1就是加一级父类文件夹(但不拷贝父类内容)
* @param type
*/
public void copeormovedirectory(string src,string tar,int tiersize,optionfile_type type);
/**
* 根据文件类型查找相关文件集合,多种类型时用逗号隔开
*
* @param dir
* 目录
* @param keys
* 文件类型
* @param ismatchcase
* 是否区分大小写
* @return
* @throws ioexception
*/
list<string> findfilesbytype(string dir, string[] keys, boolean ismatchcase)
throws ioexception;
/**
* 根据文件名称查找相关文件集合,多种民称时用逗号隔开
*
* @param dir
* 目录
* @param keys
* 文件名称
* @param ismatchcase
* 是否区分大小写
* @return
* @throws ioexception
*/
list<string> findfilesbyname(string dir, string[] keys, boolean ismatchcase)
throws ioexception;
}
--------------------
package com.xyq.io.util;
import java.io.file;
import java.io.ioexception;
import java.nio.file.filevisitresult;
import java.nio.file.path;
import java.nio.file.simplefilevisitor;
import java.nio.file.attribute.basicfileattributes;
import java.util.list;
import com.xyq.io.enums.filetypemode;
public class findfileutil extends simplefilevisitor<path> {
/***
* 关键词列表,是否转换大小写,返回结果集
*/
private string[] keyarray = null;
private boolean ismatchcase;
private list<string> resultlist;
private filetypemode mode;
public findfileutil(string[] keyarray, boolean ismatchcase,
list<string> resultlist, filetypemode mode) {
this.keyarray = keyarray;
this.ismatchcase = ismatchcase;
this.resultlist = resultlist;
this.mode = mode;
}
@suppresswarnings("unused")
private findfileutil() {
}
@override
public filevisitresult visitfile(path file, basicfileattributes attrs)
throws ioexception {
file f = file.tofile();
if (f.exists() && f.canread() && !f.ishidden())
if (this.keyarray != null) {
for (string key : this.keyarray) {
if (!this.ismatchcase)
key = key.tolowercase();
if (matchfile(file, this.mode, key, ismatchcase))
resultlist.add(file.tostring());
}
}
return filevisitresult.continue;
}
/***
* 根据大小写和类型或名称进行文件匹配
*
* @param file
* @param mode
* @param key
* @param ismatchcase
* @return
*/
private boolean matchfile(path file, filetypemode mode, string key,
boolean ismatchcase) {
file f = file.tofile();
if (f.exists() && f.canread() && !f.ishidden()
&& !"system volume information".equals(f.getname())) {
string filename = null;
if (filetypemode.types.equals(mode)) {
filename = file.tostring();
return ismatchcase ? filename.endswith(key) : filename
.tolowercase().endswith(key);
} else if (filetypemode.names.equals(mode)) {
filename = file.tofile().getname();
return ismatchcase ? (filename.indexof(key) == -1 ? false
: true)
: (filename.tolowercase().indexof(key) == -1 ? false
: true);
}
}
return false;
}
@override
public filevisitresult visitfilefailed(path file, ioexception exc)
throws ioexception {
//如果错误信息中包含x:\system volume information,这是表示系统的隐藏盘,是不能读的
system.out.println(exc.getmessage());
return filevisitresult.continue;
}
}
--------------------------
package com.xyq.io.util;
import java.io.closeable;
public class closeioutil {
/***
* 关闭io流
*
* @param cls
*/
public static void closeall(closeable... cls) {
if (cls != null) {
for (closeable cl : cls) {
try {
if (cl != null)
cl.close();
} catch (exception e) {
} finally {
cl = null;
}
}
}
}
}
-----------------------------
package com.xyq.io.util;
import java.io.bufferedinputstream;
import java.io.file;
import java.io.fileinputstream;
import java.io.ioexception;
import java.io.unsupportedencodingexception;
import java.security.messagedigest;
import java.security.nosuchalgorithmexception;
import sun.misc.base64encoder;
public class md5util {
/***
* 加密字符串
*
* @param str
* @return
* @throws nosuchalgorithmexception
* @throws unsupportedencodingexception
*/
public static string encoderstringbymd5(string str)
throws nosuchalgorithmexception, unsupportedencodingexception {
// 确定计算方法
messagedigest md5 = messagedigest.getinstance("md5");
base64encoder base64en = new base64encoder();
// 加密后的字符串
string newstr = base64en.encode(md5.digest(str.getbytes("utf-8")));
return newstr;
}
/***
* 加密文件
*
* @param file
* @return
* @throws nosuchalgorithmexception
* @throws ioexception
*/
public static string encoderfilebymd5(file file) {
string newstr = null;
fileinputstream fis = null;
bufferedinputstream bis = null;
try {
// 确定计算方法
messagedigest md5 = messagedigest.getinstance("md5");
base64encoder base64en = new base64encoder();
byte[] buffer = new byte[1024];
fis = new fileinputstream(file);
bis = new bufferedinputstream(fis);
int length = -1;
while ((length = bis.read(buffer)) != -1)
md5.update(buffer, 0, length);
// 加密后的字符串
newstr = base64en.encode(md5.digest());
} catch (exception e) {
e.printstacktrace();
} finally {
closeioutil.closeall(bis, fis);
}
return newstr;
}
public static void main(string[] args) throws nosuchalgorithmexception, unsupportedencodingexception {
system.out.println(encoderstringbymd5("23"));
}
}