欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

使用jdk7的nio2操作文件拷贝和剪切示例

程序员文章站 2024-02-20 20:24:28
复制代码 代码如下:package com.xyq.io.simply.core; import java.io.file;import java.io.ioexcept...

复制代码 代码如下:

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"));
 }
}