java nio Files DirectoryStream 文件复制_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > java nio Files DirectoryStream 文件复制

java nio Files DirectoryStream 文件复制

 2015/1/21 0:42:02  TimerBin  程序员俱乐部  我要评论(0)
  • 摘要:JDK1.7中新增了nio包,基于此包可实现java程序基于操作系统的情况下对文件或文件夹进行CRUD操作,同时支持跨系统间的文件操作。一、对文件操作代码1、在java中基于IO对系统文件进行操作publicstaticvoidoldCopyFileList(){longbegin=System.currentTimeMillis();FileInputStreaminput=null;FileOutputStreamoutput=null;try{Filefile=newFile("D
  • 标签:file files 文件 Java 复制 CTO

JDK1.7 中新增了nio包,基于此包可实现java程序基于操作系统的情况下对文件或文件夹进行CRUD操作,同时支持跨系统间的文件操作。

一、对文件操作代码

1、在java中基于IO对系统文件进行操作

class="java">public static void oldCopyFileList(){
	long begin = System.currentTimeMillis();
	FileInputStream input = null;
	FileOutputStream output = null;
	try {
		File file = new File("D:/1");
		String newPath = "D:/2";  
		if(!file.isFile()){
			for(int i=0;i<file.listFiles().length;i++){
				File fileSun = file.listFiles()[i];
				input = new FileInputStream(file.listFiles()[i]);
				output = new FileOutputStream(newPath + "/"+(fileSun.getName()).toString());
				byte[] b = new byte[1024 * 5];
				int len;
				while ((len = input.read(b)) != -1) {
					output.write(b, 0, len);
				}
				output.flush();
			}
		}
	} catch (IOException e) {
		e.printStackTrace();
	}finally{
		if(null !=input ){
			try {
				input.close();
			} catch (IOException e) {
			}
		}
		if(null !=output ){
			try {
				output.close();
			} catch (IOException e) {
			}
		}
	}
	System.err.println("time:"+(System.currentTimeMillis()-begin));
}

?2、java中基于nio对文件进行操作

?

public static void newFileList(){
	long begin = System.currentTimeMillis();
	try {
		Path path = Paths.get("D:/1");  
		String newPath = "D:/2/";  
		DirectoryStream<Path> streamList = Files.newDirectoryStream(path);
		for (Path pathSun : streamList){
		     Files.copy(pathSun, Paths.get(newPath+pathSun.getFileName()) , StandardCopyOption.COPY_ATTRIBUTES);
		} 
	} catch (IOException e) {
			e.printStackTrace();
	}
	System.err.println("time:"+(System.currentTimeMillis()-begin));
}

3、在Files工具类中同样提供了基于InputStream的文件操作方式,代码如下所示:

public static void oldCopyFileList(){
	long begin = System.currentTimeMillis();
	FileInputStream input = null;
	try {
		File file = new File("D:/1");
		String newPath = "D:/2/";  
		if(!file.isFile()){
			for(int i=0;i<file.listFiles().length;i++){
				File fileSun = file.listFiles()[i];
				System.err.println(fileSun.getName());
				input = new FileInputStream(file.listFiles()[i]);
				    Files.copy(input, Paths.get(newPath+fileSun.getName()),  StandardCopyOption.REPLACE_EXISTING);
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
		   if(null !=input ){
			try {
				input.close();
			} catch (IOException e) {
		   }
		}
	}
	System.err.println("time:"+(System.currentTimeMillis()-begin));
}

?这种方式可用于上传的图片添加水印,但是只有想法,未投入到生产使用,不知道是否有什么后遗症。

比较

在处理单个大文件的拷贝时使用IO的效率要高于nio。nio在进行多个小文件拷贝时效率远远高于IO。

二、源码分析

window系统源码(与上方代码相对应这里只针对copy源码)

1、Files.copy

public static Path copy(Path paramPath1, Path paramPath2, CopyOption[] 
paramArrayOfCopyOption)throws IOException{
    FileSystemProvider localFileSystemProvider = provider(paramPath1);
      if (provider(paramPath2) == localFileSystemProvider){
      localFileSystemProvider.copy(paramPath1, paramPath2, 
          paramArrayOfCopyOption);
    }else {
      //这里有支持其他系统的意思,我还未细研究写出应用实例
      CopyMoveHelper.copyToForeignTarget(paramPath1, 
      paramPath2, paramArrayOfCopyOption);
    }
    return paramPath2;
}

?通过以下代码来获得是当前是什么系统的,具体为什么还没有想通?

public static FileSystem getDefault(){
    return DefaultFileSystemHolder.defaultFileSystem;
}
private static class DefaultFileSystemHolder {
    static final FileSystem defaultFileSystem = defaultFileSystem();
    private static FileSystem defaultFileSystem(){
       FileSystemProvider localFileSystemProvider = (FileSystemProvider)AccessController.doPrivileged(new PrivilegedAction(){
         public FileSystemProvider run() {
            return Filesystems.html" target="_blank">Systems.DefaultFileSystemHolder.access$000();
         }
       });
       return localFileSystemProvider.getFileSystem(URI.create("file:///"));
    }
}

?2、WindowsFileSystemProvider.copy? 在linux下的实现类为UnixFileSystemProvider

public void copy(Path paramPath1, Path paramPath2, CopyOption[] paramArrayOfCopyOption)
throws IOException{
     WindowsFileCopy.copy(WindowsPath.toWindowsPath(paramPath1), WindowsPath.toWindowsPath(paramPath2), paramArrayOfCopyOption);
}

?这里将公用的Path转为WindowsPath,linux下转为了UnixPath,还有相应的ZipPath,对zip文件操作。

?

3、WindowsFileCopy.copy() 这个方法操作非常复杂,这里只是最简单列了一种情况,而且其中好多异常捕获和线程的开关都删除掉了,有兴趣的请查看源码

WindowsFileAttributes localWindowsFileAttributes1 = null;
WindowsFileAttributes localWindowsFileAttributes2 = null;
//获得文件属性 比如只读 等等
long l1 = 0L;
l1 = paramWindowsPath1.openForReadAttributeAccess(bool);
localWindowsFileAttributes1 = WindowsFileAttributes.readAttributes(l1);
//获得文件属性 比如只读 等等
long l2 = 0L;
l2 = paramWindowsPath2.openForReadAttributeAccess(false);
localWindowsFileAttributes2 = WindowsFileAttributes.readAttributes(l2);
//获得文件路径
String str1 = asWin32Path(paramWindowsPath1);
String str2 = asWin32Path(paramWindowsPath2);
int i2 = ((paramWindowsPath1.getFileSystem().supportsLinks()) && (!bool)) ? 2048 : 0;
try {
   WindowsNativeDispatcher.CopyFileEx(str1, str2, i2, 0L);
} catch (WindowsException localWindowsException6) {
   localWindowsException6.rethrowAsIOException(paramWindowsPath1, paramWindowsPath2);
}

?4、WindowsNativeDispatcher 与操作系统对接的文件操作类

static void CopyFileEx(String paramString1, String paramString2, int paramInt, long paramLong)
    throws WindowsException{
    NativeBuffer localNativeBuffer1 = asNativeBuffer(paramString1);
    NativeBuffer localNativeBuffer2 = asNativeBuffer(paramString2);
    try {
      CopyFileEx0(localNativeBuffer1.address(), localNativeBuffer2.address(), paramInt, paramLong);
    }
    finally {
      localNativeBuffer2.release();
      localNativeBuffer1.release();
    }
  } 
private static native long CreateFile0(long paramLong1, int paramInt1, int paramInt2, long paramLong2, int paramInt3, int paramInt4)
    throws WindowsException;

?此类中还提供了CreateFile、DeleteFile、CreateDirectory等方法。

?

?

由于Jdk中添加了nio包,同时新增加了用以遍历文件目录的迭代器DirectoryStream继承于Iterable。

官方解释如下:

An object to iterate over the entries in a directory. A directory stream
allows for the convenient use of the for-each construct to iterate over a
directory.

其特点:其中定义了一个interface Filter<T> 静态内部接口

?

上一篇: 不学Java8你就Out了!——Java8的default方法详解 下一篇: 没有下一篇了!
发表评论
用户名: 匿名