2、NIO复制本地文件及经常使用类

1、使用通道完成本地文件复制
1.利用通道完成文件的复制(非直接缓冲区)
//利用通道完成数据传输(非直接缓冲区)
    @Test
    public void test1() {

        //1.获取通道
        FileInputStream fis = null;
        FileOutputStream fos = null;
        FileChannel fisChannel = null;
        FileChannel fosChannel = null;
        //2.获取缓冲区
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        try {
            fis = new FileInputStream("d:/tomcat.zip");
            fos = new FileOutputStream("d:/tomcat2.zip");
            fisChannel = fis.getChannel();
            fosChannel = fos.getChannel();
            //3.读取通道中的数据至缓存区
            while(fisChannel.read(buffer)!=-1){
                //切换读写数据模式
                buffer.flip();
                //4.将缓存中的数据写出到指定文件
                fosChannel.write(buffer);
                buffer.clear();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            if(fisChannel!=null){
                try {
                    fisChannel.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if(fosChannel!=null){
                try {
                    fosChannel.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if(fos!=null){
                try {
                    fos.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if(fis!=null){
                try {
                    fis.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }
2.内存映射文件
//使用直接缓冲区完成文件的复制(内存映射文件)
    @Test
    public void test2() throws IOException{
        long start = System.currentTimeMillis();

        FileChannel inChannel = FileChannel.open(Paths.get("d:/1.mkv"), StandardOpenOption.READ);
        FileChannel outChannel = FileChannel.open(Paths.get("d:/2.mkv"), StandardOpenOption.WRITE, StandardOpenOption.READ, StandardOpenOption.CREATE);

        //内存映射文件
        MappedByteBuffer inMappedBuf = inChannel.map(MapMode.READ_ONLY, 0, inChannel.size());
        MappedByteBuffer outMappedBuf = outChannel.map(MapMode.READ_WRITE, 0, inChannel.size());

        //直接对缓冲区进行数据的读写操做
        byte[] dst = new byte[inMappedBuf.limit()];
        inMappedBuf.get(dst);
        outMappedBuf.put(dst);

        inChannel.close();
        outChannel.close();

        long end = System.currentTimeMillis();
        System.out.println("耗费时间为:" + (end - start));
    }
3.通道之间的数据传输(直接缓冲区)

​ 从哪里来–到哪里去html

@Test
    public void test3() throws IOException{
        FileChannel inChannel = FileChannel.open(Paths.get("d:/tomcat.zip"), StandardOpenOption.READ);
        FileChannel outChannel = FileChannel.open(Paths.get("d:/tomcat4.zip"), StandardOpenOption.WRITE, StandardOpenOption.READ, StandardOpenOption.CREATE);

      //去哪里:inChannel从0-末尾,到outChannel输出管道中去
// inChannel.transferTo(0, inChannel.size(), outChannel);
      //从哪里来:outChannel输出管道中的数据,是从inChannel输入管道中0-末尾来的数据
        outChannel.transferFrom(inChannel, 0, inChannel.size());

        inChannel.close();
        outChannel.close();
    }
4.通道之间的数据传输(直接缓冲区)Files.newByteChannel();
//通道之间的数据传输(直接缓冲区)Files.newByteChannel();
    @Test
    public void test4() throws IOException{
// import java.nio.channels.SeekableByteChannel;
        FileChannel fis = (FileChannel) Files.newByteChannel(Paths.get("d:/tomcat.zip"), StandardOpenOption.READ);
        FileChannel fos = (FileChannel) Files.newByteChannel(Paths.get("d:/tomcat9.zip"),  StandardOpenOption.WRITE,StandardOpenOption.CREATE,StandardOpenOption.READ);
// fis.transferTo(0, fis.size(), fos);
        fos.transferFrom(fis, 0, fis.size());
        fis.close();
        fos.close();
    }
2、经常使用类型介绍
1.FileChannel 的经常使用方法
int read(ByteBuffer dst)        // 从 Channel 中读取数据到 ByteBuffer
long read(ByteBuffer[] dsts)    // 将 Channel 中的数据“分散”到 ByteBuffer[]
int write(ByteBuffer src)       // 将 ByteBuffer 中的数据写入到 Channel
long write(ByteBuffer[] srcs)   // 将 ByteBuffer[] 中的数据“汇集”到 Channel
long position()                 //返回此通道的文件位置
FileChannel position(long p)    //设置此通道的文件位置
long size()                     //返回此通道的文件的当前大小
FileChannel truncate(long s)    //将此通道的文件截取为给定大小
void force(boolean metaData)    //强制将全部对此通道的文件更新写入到存储设备中
public static FileChannel open(Path path, OpenOption... options)//打开文件设置参数,获取通道
2.StandardOpenOption数据类型
public enum StandardOpenOption implements OpenOption{
  //读文件模式
    READ,
  //写文件模式
    WRITE,
  //追加数据到某个文件中,不能与READ同时使用,文件必须存在,不存在则报异常-java.nio.file.NoSuchFileException
    APPEND,

    /** * If the file already exists and it is opened for {@link #WRITE} * access, then its length is truncated to 0. This option is ignored * if the file is opened only for {@link #READ} access. */
    TRUNCATE_EXISTING,
    //新建文件,通常在写出数据到某个文件时用到,若是文件存在则覆盖
    CREATE,

    /**建立一个文件,若是文件存在则包异常--java.nio.file.FileAlreadyExistsException * Create a new file, failing if the file already exists. * The check for the existence of the file and the creation of the file * if it does not exist is atomic with respect to other file system * operations. */
    CREATE_NEW,

  //----如下未用到,留待之后使用
    DELETE_ON_CLOSE,

    /** * Sparse file. When used with the {@link #CREATE_NEW} option then this * option provides a <em>hint</em> that the new file will be sparse. The * option is ignored when the file system does not support the creation of * sparse files. */
    SPARSE,

    /** * Requires that every update to the file's content or metadata be written * synchronously to the underlying storage device. * * @see <a href="package-summary.html#integrity">Synchronized I/O file integrity</a> */
    SYNC,

    /** * Requires that every update to the file's content be written * synchronously to the underlying storage device. * * @see <a href="package-summary.html#integrity">Synchronized I/O file integrity</a> */
    DSYNC;
}
3.Path
Paths 提供的 get() 方法用来获取 Path 对象:
        Path get(String first, String … more) : 用于将多个字符串串连成路径。
    Path 经常使用方法:
        boolean endsWith(String path) : 判断是否以 path 路径结束
        boolean startsWith(String path) : 判断是否以 path 路径开始
        boolean isAbsolute() : 判断是不是绝对路径
        Path getFileName() : 返回与调用 Path 对象关联的文件名
        Path getName(int idx) : 返回的指定索引位置 idx 的路径名称
        int getNameCount() : 返回Path 根目录后面元素的数量
        Path getParent() :返回Path对象包含整个路径,不包含 Path 对象指定的文件路径
        Path getRoot() :返回调用 Path 对象的根路径
        Path resolve(Path p) :将相对路径解析为绝对路径
        Path toAbsolutePath() : 做为绝对路径返回调用 Path 对象
        String toString() : 返回调用 Path 对象的字符串表示形式
public static Path get(String first, String... more) {
  return FileSystems.getDefault().getPath(first, more);
}
//根据文件地址获取path对象 
public static Path get(URI uri) {
  String scheme =  uri.getScheme();
  if (scheme == null)
    throw new IllegalArgumentException("Missing scheme");

  // check for default provider to avoid loading of installed providers
  if (scheme.equalsIgnoreCase("file"))
    return FileSystems.getDefault().provider().getPath(uri);

  // try to find provider
  for (FileSystemProvider provider: FileSystemProvider.installedProviders()) {
    if (provider.getScheme().equalsIgnoreCase(scheme)) {
      return provider.getPath(uri);
    }
  }

  throw new FileSystemNotFoundException("Provider \"" + scheme + "\" not installed");
}
4.Files经常使用方法:
Path copy(Path src, Path dest, CopyOption … how) : 文件的复制
        Path createDirectory(Path path, FileAttribute<?> … attr) : 建立一个目录
        Path createFile(Path path, FileAttribute<?> … arr) : 建立一个文件
        void delete(Path path) : 删除一个文件
        Path move(Path src, Path dest, CopyOption…how) : 将 src 移动到 dest 位置
        long size(Path path) : 返回 path 指定文件的大小

        **Files经常使用方法:用于判断**
        boolean exists(Path path, LinkOption … opts) : 判断文件是否存在
        boolean isDirectory(Path path, LinkOption … opts) : 判断是不是目录
        boolean isExecutable(Path path) : 判断是不是可执行文件
        boolean isHidden(Path path) : 判断是不是隐藏文件
        boolean isReadable(Path path) : 判断文件是否可读
        boolean isWritable(Path path) : 判断文件是否可写
        boolean notExists(Path path, LinkOption … opts) : 判断文件是否不存在

    **Files经常使用方法:用于操做内容**
        SeekableByteChannel newByteChannel(Path path, OpenOption…how) : 获取与指定文件的链接,how 指定打开方式。
        DirectoryStream newDirectoryStream(Path path) : 打开 path 指定的目录
        InputStream newInputStream(Path path, OpenOption…how):获取 InputStream 对象
        OutputStream newOutputStream(Path path, OpenOption…how) : 获取 OutputStream 对象