|
这个程序只是为了更方便的进行拷贝文件(夹)而创造。 1.可以不用新建文件夹,就像windows的复制粘贴一样简单。 2.有简单的出错重连机制 3.不需要重复拷贝,差异化复制文件。 4.拷贝文件夹的时候可以不用复制全路径,只关注需要拷贝的文件夹。 5.程序做了简单的必要检查,效率也不算低。 6.使用的是7的nio2的新API。
复制代码 代码如下: 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.nio.file.attribute.FileTime; import java.util.Stack;
import org.apache.log4j.Logger;
import com.xyq.myfile.cope.entity.PathType; import com.xyq.util.MD5Util;
/*** * 基于jdk7的拷贝算法 * * @author xyq * */ public class MyFiles2 {
private String src; private String tar; private Path srcPath; private Path tarPath; private int reCount = 3; private boolean isCover = false; private boolean useMd5 = false; private int subNameNum = 0; // log4j对象 private Logger logger; // 在文件夹-->文件夹模式中,是否拷贝全路径,默认不拷贝 private boolean isCopeAllPath = false;
public MyFiles2(String src,String tar) {
this.src = src; this.tar = tar; this.srcPath = Paths.get(src); this.tarPath = Paths.get(tar); }
public MyFiles2() { }
public String getSrc() { return src; }
public void setSrc(String src) { this.src = src; this.srcPath = Paths.get(src); }
public String getTar() { return tar; }
public void setTar(String tar) { this.tar = tar; this.tarPath = Paths.get(tar); }
public int getReCount() { return reCount; }
public void setReCount(int reCount) { this.reCount = reCount; }
public boolean isCover() { return isCover; }
public void setCover(boolean isCover) { this.isCover = isCover; }
public Logger getLogger() { return logger; }
public void setLogger(Logger logger) { this.logger = logger; }
public boolean isUseMd5() { return useMd5; }
public void setUseMd5(boolean useMd5) { this.useMd5 = useMd5; }
public boolean isCopeAllPath() { return isCopeAllPath; }
public void setCopeAllPath(boolean isCopeAllPath) { this.isCopeAllPath = isCopeAllPath; }
public boolean copeFileCore(PathType... types) {
if (initCheck() && initCheck2s(this.srcPath,false)) return copeFileCore(this.srcPath,this.tarPath,reCount,isCover, types); return false; }
private boolean initCheck() {
if (this.srcPath == null) { logInfo("原始路径未设置,程序无法启动~~"); return false; } else if (this.tarPath == null) { logInfo("目标路径未设置,程序无法启动~~"); return false; } else if (!Files.exists(srcPath)) { logInfo("原始路径不存在,程序无法启动~~"); return false; } else if (!Files.exists(tarPath.getRoot())) { logInfo("目标路径的根盘符不存在,程序无法启动~~"); return false; } return true; }
private boolean initCheck2s(Path path,boolean dOrF) {
if (!Files.isDirectory(path)) { if (dOrF) { logInfo(path + "不是一个有效的文件夹"); return false; } } else if (!dOrF) { logInfo(path + "不是一个有效的文件"); return false; } return true; }
/**** * 拷贝文件算法 * * @param path1 * 原始路径 * @param path2 * 目标路径 * @param reCount * 重复次数 * @param isCover * 是否覆盖拷贝 * @param types * 你所写的目标路径是文件还是文件夹,可以不写,默认是文件 * @return */ public boolean copeFileCore(Path path1,Path path2,int reCount, boolean isCover,PathType... types) {
// 如果原始文件不存在,就直接异常 if (!initCheck() || !initCheck2s(path1,false)) return false; PathType type = PathType.FILES; if (types != null && types.length > 0) { type = types[0]; // 如果目标是一个文件夹,并且指定是往一个文件夹拷贝的时候 if (type.equals(PathType.DIRS)) { path2 = Paths.get(path2.toString(),path1.getFileName() .toString()); } } // 如果目标文件已经存在,就判断是否相同,相同就不用拷贝了 if (Files.exists(path2)) { if (Files.isDirectory(path2) && PathType.FILES.equals(type)) { logInfo(path2 + "已经存在,它是一个文件夹而不是文件"); return false; } if (isSameFile(path1,path2,useMd5)) return true; } // 当目标文件不存在的时候 else { Path parPath = path2.getParent(); // 如果目标文件的父类文件夹不存在,就尝试创建 if (!Files.exists(parPath)) for (int i = 1; i < reCount; i++) { try { Files.createDirectories(parPath); break; } catch (Exception e) { if (i == reCount) { logInfo(e); return false; } } } }
for (int i = 1; i <= reCount; i++) { try { if (isCover) Files.copy(path1, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES); else Files.copy(path1,StandardCopyOption.COPY_ATTRIBUTES); // 同步最后修改时间 synLastFileTime(path1,path2); break; } catch (IOException e) { // 如果在指定时间内都无法完成拷贝,那么就果断记录到异常信息中 if (i == reCount) { logInfo(e); return false; } } } return true;
}
public void copeDir() {
if (!initCheck() || !initCheck2s(srcPath,true)) return; copeDir(this.srcPath.toString(),this.tarPath.toString()); }
/*** * 拷贝文件夹保护层 * * @param path1 * @param path2 */ public void copeDir(String path1,final String path2) {
if (!initCheck() || !initCheck2s(srcPath,true)) return; Path p1 = Paths.get(path1); final Path tarPath = Paths.get(path2); if (!isCopeAllPath) subNameNum = srcPath.getNameCount() - 1; try { Files.walkFileTree(p1,new FileVisitor<Path>() {
Path p2 = null; Stack<Path> dirStack = new Stack<Path>();
@Override public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
// 当使用不拷贝全路径时,作为本文件夹的名字节点的记录位置 // if (!copeAllPath) /**** * 如果是相同的文件夹,那么就跳过无需拷贝. */ if (isSamePath(dir,tarPath)) { System.out.println("是相同的,跳过!!!!!!!!!!!!!!!!!"); return FileVisitResult.SKIP_SUBTREE; } p2 = replacePath(dir,subNameNum); if (dir.toFile().length() == 0 && !Files.exists(p2)) Files.createDirectories(p2); dirStack.push(p2); return FileVisitResult.CONTINUE;
}
@Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
Path toFilePath = Paths.get(dirStack.peek().toString(), file.getFileName().toString()); copeFileCore(file,toFilePath,3,true); return FileVisitResult.CONTINUE;
}
@Override public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
return FileVisitResult.CONTINUE; }
@Override public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException { if (!dirStack.isEmpty()) dirStack.pop(); return FileVisitResult.CONTINUE; }
}); } catch (IOException e) { logInfo(e); } }
/*** * 替换Path * * @param path1 * @param path2 * @return */ private Path replacePath(Path path1,String path2,int nameCountNum) {
if (path1.getNameCount() == 0 && path1.equals(path1.getRoot())) return Paths.get(path2); return Paths.get(path2, path1.subpath(nameCountNum,path1.getNameCount()).toString()); }
/*** * 要么是地址完全相同,要么就是原始文件的父类与目标相同,因为程序支持拷贝到父类 * * @param path1 * @param path2 * @return */ private boolean isSamePath(Path path1,Path path2) {
if (path1.equals(path2)) return true; return false; }
/*** * 同步文件的修改时间 * * @param path1 * @param path2 * @return */ public boolean synLastFileTime(Path path1,Path path2) {
FileTime srcPathTime; try { srcPathTime = Files.getLastModifiedTime(path1); Files.setLastModifiedTime(path2,srcPathTime); return srcPathTime.equals(Files.getLastModifiedTime(path2)); } catch (IOException e) { logInfo(e); return false; } }
/*** * 判断两个文件是否相同 * * @param path1 * @param path2 * @return */ public boolean isSameFile(Path path1,boolean useMd5) {
try { // 只要两个文件长度不一致,就绝对不是一个文件 if (Files.size(path1) != Files.size(path2)) return false; // 如果是最后的修改时间不一样,就直接使用MD5验证 else if (!Files.getLastModifiedTime(path1).equals( Files.getLastModifiedTime(path2)) || useMd5) return MD5Util.getFileMD5String(path1.toFile()).equals( MD5Util.getFileMD5String(path2.toFile())); return true; } catch (Exception e) { logInfo(e); return false; } }
/*** * 针对异常处理的 */ private void logInfo(Exception e) {
if (this.logger != null) logger.error(e.getMessage()); else if (e != null) System.out.println("异常:" + e.getMessage()); }
private void logInfo(String errorMessage) {
if (this.logger != null) logger.error(errorMessage); else System.out.println("异常:" + errorMessage); }
public static void main(String[] args) {
// new MyFiles2("e:/t/1.txt","e:/3/33").copeFileCore(); MyFiles2 my = new MyFiles2("e:/ttt/tt/t/1.txt","e:/3/33.txt"); my.copeFileCore(PathType.DIRS); } }
复制代码 代码如下: public enum PathType {
FILES,DIRS; }
复制代码 代码如下: 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; } } } } }
复制代码 代码如下: import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException;
public class MD5Util {
protected static char hexDigits[] = { '0','1','2','3','4','5','6', '7','8','9','a','b','c','d','e','f' }; protected static MessageDigest messagedigest = null; static { try { messagedigest = MessageDigest.getInstance("MD5"); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } }
public static String getFileMD5String(File file) throws IOException {
/*** * MappedByteBuffer是NIO的API,使用这个API会有一个bug, * 当使用 FileChannel.map 方法时,MappedByteBuffer 已经在系统内占用了一个句柄, * 而使用 FileChannel.close 方法是无法释放这个句柄的,、 * 且FileChannel有没有提供类似 unmap 的方法,因此会出现无法删除文件的情况。 */ // FileInputStream in = new FileInputStream(file); // FileChannel ch = in.getChannel(); // MappedByteBuffer byteBuffer = ch.map(FileChannel.MapMode.READ_ONLY, // 0, // file.length());
InputStream fis = null; BufferedInputStream bis = null; fis = new FileInputStream(file); bis = new BufferedInputStream(fis); byte[] buffer = new byte[2048]; int numRead = 0; while ((numRead = bis.read(buffer)) > 0) { messagedigest.update(buffer,numRead); } CloseIoUtil.closeAll(bis,fis); return bufferToHex(messagedigest.digest()); }
public static String getMD5String(String s) { return getMD5String(s.getBytes()); }
public static String getMD5String(byte[] bytes) { messagedigest.update(bytes); return bufferToHex(messagedigest.digest()); }
private static String bufferToHex(byte bytes[]) { return bufferToHex(bytes,bytes.length); }
private static String bufferToHex(byte bytes[],int m,int n) { StringBuffer stringbuffer = new StringBuffer(2 * n); int k = m + n; for (int l = m; l < k; l++) { appendHexPair(bytes[l],stringbuffer); } return stringbuffer.toString(); }
private static void appendHexPair(byte bt,StringBuffer stringbuffer) { char c0 = hexDigits[(bt & 0xf0) >> 4]; char c1 = hexDigits[bt & 0xf]; stringbuffer.append(c0); stringbuffer.append(c1); }
public static boolean checkPassword(String password,String md5PwdStr) { String s = getMD5String(password); return s.equals(md5PwdStr); }
public static void main(String[] args) throws IOException {
File big = new File("e:/sss.txt"); String md5 = getFileMD5String(big); // // long end = System.currentTimeMillis(); // System.out.println("md5:" + md5); // System.out.println("time:" + ((end - begin) / 1000) + "s");
System.out.println(md5);
}
}
复制代码 代码如下: import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException;
public class MD5Util {
protected static char hexDigits[] = { '0',String md5PwdStr) { String s = getMD5String(password); return s.equals(md5PwdStr); }
public static void main(String[] args) throws IOException {
File big = new File("e:/sss.txt"); String md5 = getFileMD5String(big); // // long end = System.currentTimeMillis(); // System.out.println("md5:" + md5); // System.out.println("time:" + ((end - begin) / 1000) + "s");
System.out.println(md5);
} }
您可能感兴趣的文章:- java 实现文件夹的拷贝实例代码
- java文件复制代码片断(java实现文件拷贝)
- Java利用文件输入输出流实现文件夹内所有文件拷贝到另一个文件夹
(编辑:安卓应用网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|