当前位置: 移动技术网 > IT编程>开发语言>Java > java使用nio2拷贝文件的示例

java使用nio2拷贝文件的示例

2019年07月22日  | 移动技术网IT编程  | 我要评论

这个程序只是为了更方便的进行拷贝文件(夹)而创造。
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, path2,
       standardcopyoption.replace_existing,
       standardcopyoption.copy_attributes);
    else
     files.copy(path1, path2, 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, path2, 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, path path2, 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, 0, 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, 0, 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', '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, 0, 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, 0, 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);

 }
}

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网