手机
当前位置:查字典教程网 >编程开发 >Java >java使用nio2拷贝文件的示例
java使用nio2拷贝文件的示例
摘要:这个程序只是为了更方便的进行拷贝文件(夹)而创造。1.可以不用新建文件夹,就像windows的复制粘贴一样简单。2.有简单的出错重连机制3....

这个程序只是为了更方便的进行拷贝文件(夹)而创造。

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

}

}

【java使用nio2拷贝文件的示例】相关文章:

简单的用java实现读/写文本文件的示例

java中使用Filter控制用户登录权限具体实例

java多线程入门知识及示例程序

Java调用.dll文件的方法

java中通用的线程池实例代码

java使用命令行打包JAR

在java中使用dom4j解析xml(示例代码)

java开发之读写txt文件操作的实现

java线程并发cyclicbarrier类使用示例

java使用JSONObject实例

精品推荐
分类导航