java使用nio2拷贝文件的示例

这个程序只是为了更方便的进行拷贝文件(夹)而创造。
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);

}
}

(0)

相关推荐

  • java NIO 详解

    Java NIO提供了与标准IO不同的IO工作方式: Channels and Buffers(通道和缓冲区):标准的IO基于字节流和字符流进行操作的,而NIO是基于通道(Channel)和缓冲区(Buffer)进行操作,数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中. Asynchronous IO(异步IO):Java NIO可以让你异步的使用IO,例如:当线程从通道读取数据到缓冲区时,线程还是可以进行其他事情.当数据被写入到缓冲区时,线程可以继续处理它.从缓冲区写入通道也类似. S

  • Java NIO:浅析IO模型_动力节点Java学院整理

    也许很多朋友在学习NIO的时候都会感觉有点吃力,对里面的很多概念都感觉不是那么明朗.在进入Java NIO编程之前,我们今天先来讨论一些比较基础的知识:I/O模型.下面本文先从同步和异步的概念 说起,然后接着阐述了阻塞和非阻塞的区别,接着介绍了阻塞IO和非阻塞IO的区别,然后介绍了同步IO和异步IO的区别,接下来介绍了5种IO模型,最后介绍了两种和高性能IO设计相关的设计模式(Reactor和Proactor). 以下是本文的目录大纲: 一.什么是同步?什么是异步? 二.什么是阻塞?什么是非阻塞

  • java的nio的使用示例分享

    Java NIO(New Input/Output)--新的输入/输出API包--是2002年引入到J2SE 1.4里的.Java NIO的目标是提高Java平台上的I/O密集型任务的性能.过了十年,很多Java开发者还是不知道怎么充分利用NIO,更少的人知道在Java SE 7里引入了更新的输入/输出 API(NIO.2).NIO和NIO.2对于Java平台最大的贡献是提高了Java应用开发中的一个核心组件的性能:输入/输出处理.不过这两个包都不是很好用,并且它们也不是适用于所有的场景.如果能

  • Java 高并发八:NIO和AIO详解

    IO感觉上和多线程并没有多大关系,但是NIO改变了线程在应用层面使用的方式,也解决了一些实际的困难.而AIO是异步IO和前面的系列也有点关系.在此,为了学习和记录,也写一篇文章来介绍NIO和AIO. 1. 什么是NIO NIO是New I/O的简称,与旧式的基于流的I/O方法相对,从名字看,它表示新的一套Java I/O标 准.它是在Java 1.4中被纳入到JDK中的,并具有以下特性: NIO是基于块(Block)的,它以块为基本单位处理数据 (硬盘上存储的单位也是按Block来存储,这样性能

  • Java NIO工作原理的全面分析

    ◆  输入/输出:概念性描述I/O 简介I/O ? 或者输入/输出 ? 指的是计算机与外部世界或者一个程序与计算机的其余部分的之间的接口.它对于任何计算机系统都非常关键,因而所有 I/O 的主体实际上是内置在操作系统中的.单独的程序一般是让系统为它们完成大部分的工作.在 Java 编程中,直到最近一直使用 流 的方式完成 I/O.所有 I/O 都被视为单个的字节的移动,通过一个称为 Stream 的对象一次移动一个字节.流 I/O 用于与外部世界接触.它也在内部使用,用于将对象转换为字节,然后再

  • Java NIO和IO的区别

    下表总结了Java NIO和IO之间的主要差别,我会更详细地描述表中每部分的差异. 复制代码 代码如下: IO                NIO面向流            面向缓冲阻塞IO            非阻塞IO无                选择器 面向流与面向缓冲 Java NIO和IO之间第一个最大的区别是,IO是面向流的,NIO是面向缓冲区的. Java IO面向流意味着每次从流中读一个或多个字节,直至读取所有字节,它们没有被缓存在任何地方.此外,它不能前后移动流中的数

  • java使用nio2拷贝文件的示例

    这个程序只是为了更方便的进行拷贝文件(夹)而创造.1.可以不用新建文件夹,就像windows的复制粘贴一样简单.2.有简单的出错重连机制3.不需要重复拷贝,差异化复制文件.4.拷贝文件夹的时候可以不用复制全路径,只关注需要拷贝的文件夹.5.程序做了简单的必要检查,效率也不算低.6.使用的是7的nio2的新API. 复制代码 代码如下: import java.io.IOException;import java.nio.file.FileVisitResult;import java.nio.f

  • java导出json格式文件的示例代码

    本文介绍了java导出json格式文件的示例代码,分享给大家,具体如下: 生成json文件代码: import java.io.File; import java.io.FileWriter; import java.io.Writer; public class CreateFileUtil { /** * 生成.json格式文件 */ public static boolean createJsonFile(String jsonString, String filePath, String

  • Java定时调用.ktr文件的示例代码(解决方案)

    1.Maven依赖 <!-- Kettle --> <dependency> <groupId>pentaho-kettle</groupId> <artifactId>kettle-core</artifactId> <version>7.1.0.0-12</version> </dependency> <dependency> <groupId>pentaho-kettl

  • java使用WatchService监控文件夹示例

    通过java7提供的WatchService API 实现对文件夹的监控 package service; import config.Config; import java.io.IOException; import java.nio.file.*; import java.util.List; import java.util.concurrent.TimeUnit; public class WatchDirService { private WatchService watchServ

  • java使用gzip实现文件解压缩示例

    复制代码 代码如下: package com.cjonline.foundation.cpe.action; import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.InputStream;import java.

  • java实现倒序读取文件功能示例分享

    Long end,long num,File file,String charset4个参数说明end 相当于坐标 ,tail 向上的起点,num是读取的行数,file 目标文件 charset字符集 默认UTF8end 为 null 代表从 文件 最末端 向上 获取. Map m=FileUtil.tail(null,10,file,null)//读取文件最后10行,结果在 m.get(FileUtil.ARR) 里FileUtil.tail(m.get(FileUtil.POINT),3,f

  • java通过url读取文件内容示例

    复制代码 代码如下: using System;  using System.Collections;  using System.ComponentModel;  using System.Data;  using System.Drawing;  using System.Web;  using System.Web.SessionState;  using System.Web.UI;  using System.Web.UI.WebControls;  using System.Web.

  • Java实现自动压缩文件并加密的方法示例

    本文实例讲述了Java实现自动压缩文件并加密的方法.分享给大家供大家参考,具体如下: 实现功能:自动压缩并加密 /** * * @Title: zipFilesAndEncrypt * @Description: 将指定路径下的文件压缩至指定zip文件,并以指定密码加密,若密码为空,则不进行加密保护 * @param srcFileName 待压缩文件路径 * @param zipFileName zip文件名 * @param password 加密密码 * @return * @throws

  • 使用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 jav

  • Java可以如何实现文件变动的监听的示例

    应用中使用logback作为日志输出组件的话,大部分会去配置 `logback.xml` 这个文件,而且生产环境下,直接去修改logback.xml文件中的日志级别,不用重启应用就可以生效 那么,这个功能是怎么实现的呢? 应用中使用logback作为日志输出组件的话,大部分会去配置 logback.xml 这个文件,而且生产环境下,直接去修改logback.xml文件中的日志级别,不用重启应用就可以生效 那么,这个功能是怎么实现的呢? I. 问题描述及分析 针对上面的这个问题,首先抛出一个实际的

随机推荐