1 /*
   2  * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 import java.io.*;
  25 import java.nio.*;
  26 import java.nio.channels.*;
  27 import java.nio.file.*;
  28 import java.nio.file.spi.*;
  29 import java.nio.file.attribute.*;
  30 import java.net.*;
  31 import java.text.DateFormat;
  32 import java.text.SimpleDateFormat;
  33 import java.util.*;
  34 
  35 import static java.nio.file.StandardOpenOption.*;
  36 import static java.nio.file.StandardCopyOption.*;
  37 
  38 /*
  39  * ZipFileSystem usage demo
  40  *
  41  * java Demo action ZipfileName [...]
  42  *
  43  * @author Xueming Shen
  44  */
  45 
  46 public class Demo {
  47 
  48     static enum Action {
  49         rename,          // <java Demo rename zipfile src dst>
  50                          // rename entry src to dst inside zipfile
  51 
  52         movein,          // <java Demo movein zipfile src dst>
  53                          // move an external src file into zipfile
  54                          // as entry dst
  55 
  56         moveout,         // <java Demo moveout zipfile src dst>
  57                          // move a zipfile entry src out to dst
  58 
  59         copy,            // <java Demo copy zipfile src dst>
  60                          // copy entry src to dst inside zipfile
  61 
  62         copyin,          // <java Demo copyin zipfile src dst>
  63                          // copy an external src file into zipfile
  64                          // as entry dst
  65 
  66         copyin_attrs,    // <java Demo copyin_attrs zipfile src dst>
  67                          // copy an external src file into zipfile
  68                          // as entry dst, with attributes (timestamp)
  69 
  70         copyout,         // <java Demo copyout zipfile src dst>
  71                          // copy zipfile entry src" out to file dst
  72 
  73         copyout_attrs,   // <java Demo copyout_attrs zipfile src dst>
  74 
  75         zzmove,          // <java Demo zzmove zfsrc zfdst path>
  76                          // move entry path/dir from zfsrc to zfdst
  77 
  78         zzcopy,          // <java Demo zzcopy zfsrc zfdst path>
  79                          // copy path from zipfile zfsrc to zipfile
  80                          // zfdst
  81 
  82         attrs,           // <java Demo attrs zipfile path>
  83                          // printout the attributes of entry path
  84 
  85         attrsspace,      // <java Demo attrsspace zipfile path>
  86                          // printout the storespace attrs of entry path
  87 
  88         setmtime,        // <java Demo setmtime zipfile "MM/dd/yy-HH:mm:ss" path...>
  89                          // set the lastModifiedTime of entry path
  90 
  91         setatime,        // <java Demo setatime zipfile "MM/dd/yy-HH:mm:ss" path...>
  92         setctime,        // <java Demo setctime zipfile "MM/dd/yy-HH:mm:ss" path...>
  93 
  94         lsdir,           // <java Demo lsdir zipfile dir>
  95                          // list dir's direct child files/dirs
  96 
  97         mkdir,           // <java Demo mkdir zipfile dir>
  98 
  99         mkdirs,          // <java Demo mkdirs zipfile dir>
 100 
 101         rmdirs,          // <java Demo rmdirs zipfile dir>
 102 
 103         list,            // <java Demo list zipfile [dir]>
 104                          // recursively list all entries of dir
 105                          // via DirectoryStream
 106 
 107         tlist,           // <java Demo tlist zipfile [dir]>
 108                          // list with buildDirTree=true
 109 
 110         vlist,           // <java Demo vlist zipfile [dir]>
 111                          // recursively verbose list all entries of
 112                          // dir via DirectoryStream
 113 
 114         walk,            // <java Demo walk zipfile [dir]>
 115                          // recursively walk all entries of dir
 116                          // via Files.walkFileTree
 117 
 118         twalk,           // <java Demo twalk zipfile [dir]>
 119                          // walk with buildDirTree=true
 120 
 121         extract,         // <java Demo extract zipfile file [...]>
 122 
 123         update,          // <java Demo extract zipfile file [...]>
 124 
 125         delete,          // <java Demo delete zipfile file [...]>
 126 
 127         add,             // <java Demo add zipfile file [...]>
 128 
 129         create,          // <java Demo create zipfile file [...]>
 130                          // create a new zipfile if it doesn't exit
 131                          // and then add the file(s) into it.
 132 
 133         attrs2,          // <java Demo attrs2 zipfile file [...]>
 134                          // test different ways to print attrs
 135 
 136         prof,
 137     }
 138 
 139     public static void main(String[] args) throws Throwable {
 140         FileSystemProvider provider = getZipFSProvider();
 141         if (provider == null) {
 142             System.err.println("ZIP filesystem provider is not installed");
 143             System.exit(1);
 144         }
 145 
 146         Action action = Action.valueOf(args[0]);
 147         Map<String, Object> env = env = new HashMap<>();
 148         if (action == Action.create)
 149             env.put("create", "true");
 150         try (FileSystem fs = provider.newFileSystem(Paths.get(args[1]), env)) {
 151             Path path, src, dst;
 152             switch (action) {
 153             case rename:
 154                 src = fs.getPath(args[2]);
 155                 dst = fs.getPath(args[3]);
 156                 Files.move(src, dst);
 157                 break;
 158             case moveout:
 159                 src = fs.getPath(args[2]);
 160                 dst = Paths.get(args[3]);
 161                 Files.move(src, dst);
 162                 break;
 163             case movein:
 164                 src = Paths.get(args[2]);
 165                 dst = fs.getPath(args[3]);
 166                 Files.move(src, dst);
 167                 break;
 168             case copy:
 169                 src = fs.getPath(args[2]);
 170                 dst = fs.getPath(args[3]);
 171                 Files.copy(src, dst);
 172                 break;
 173             case copyout:
 174                 src = fs.getPath(args[2]);
 175                 dst = Paths.get(args[3]);
 176                 Files.copy(src, dst);
 177                 break;
 178             case copyin:
 179                 src = Paths.get(args[2]);
 180                 dst = fs.getPath(args[3]);
 181                 Files.copy(src, dst);
 182                 break;
 183             case copyin_attrs:
 184                 src = Paths.get(args[2]);
 185                 dst = fs.getPath(args[3]);
 186                 Files.copy(src, dst, COPY_ATTRIBUTES);
 187                 break;
 188             case copyout_attrs:
 189                 src = fs.getPath(args[2]);
 190                 dst = Paths.get(args[3]);
 191                 Files.copy(src, dst, COPY_ATTRIBUTES);
 192                 break;
 193             case zzmove:
 194                 try (FileSystem fs2 = provider.newFileSystem(Paths.get(args[2]), env)) {
 195                     z2zmove(fs, fs2, args[3]);
 196                 }
 197                 break;
 198             case zzcopy:
 199                 try (FileSystem fs2 = provider.newFileSystem(Paths.get(args[2]), env)) {
 200                     z2zcopy(fs, fs2, args[3]);
 201                 }
 202                 break;
 203             case attrs:
 204                 for (int i = 2; i < args.length; i++) {
 205                     path = fs.getPath(args[i]);
 206                     System.out.println(path);
 207                     System.out.println(
 208                         Files.readAttributes(path, BasicFileAttributes.class).toString());
 209                 }
 210                 break;
 211             case setmtime:
 212                 DateFormat df = new SimpleDateFormat("MM/dd/yyyy-HH:mm:ss");
 213                 Date newDatetime = df.parse(args[2]);
 214                 for (int i = 3; i < args.length; i++) {
 215                     path = fs.getPath(args[i]);
 216                     Files.setAttribute(path, "lastModifiedTime",
 217                                        FileTime.fromMillis(newDatetime.getTime()));
 218                     System.out.println(
 219                         Files.readAttributes(path, BasicFileAttributes.class).toString());
 220                 }
 221                 break;
 222             case setctime:
 223                 df = new SimpleDateFormat("MM/dd/yyyy-HH:mm:ss");
 224                 newDatetime = df.parse(args[2]);
 225                 for (int i = 3; i < args.length; i++) {
 226                     path = fs.getPath(args[i]);
 227                     Files.setAttribute(path, "creationTime",
 228                                        FileTime.fromMillis(newDatetime.getTime()));
 229                     System.out.println(
 230                         Files.readAttributes(path, BasicFileAttributes.class).toString());
 231                 }
 232                 break;
 233             case setatime:
 234                 df = new SimpleDateFormat("MM/dd/yyyy-HH:mm:ss");
 235                 newDatetime = df.parse(args[2]);
 236                 for (int i = 3; i < args.length; i++) {
 237                     path = fs.getPath(args[i]);
 238                     Files.setAttribute(path, "lastAccessTime",
 239                                        FileTime.fromMillis(newDatetime.getTime()));
 240                     System.out.println(
 241                         Files.readAttributes(path, BasicFileAttributes.class).toString());
 242                 }
 243                 break;
 244             case attrsspace:
 245                 path = fs.getPath("/");
 246                 FileStore fstore = Files.getFileStore(path);
 247                 System.out.printf("filestore[%s]%n", fstore.name());
 248                 System.out.printf("    totalSpace: %d%n",
 249                                   (Long)fstore.getAttribute("totalSpace"));
 250                 System.out.printf("   usableSpace: %d%n",
 251                                   (Long)fstore.getAttribute("usableSpace"));
 252                 System.out.printf("  unallocSpace: %d%n",
 253                                   (Long)fstore.getAttribute("unallocatedSpace"));
 254                 break;
 255             case list:
 256             case tlist:
 257                 if (args.length < 3)
 258                     list(fs.getPath("/"), false);
 259                 else
 260                     list(fs.getPath(args[2]), false);
 261                 break;
 262             case vlist:
 263                 if (args.length < 3)
 264                     list(fs.getPath("/"), true);
 265                 else
 266                     list(fs.getPath(args[2]), true);
 267                 break;
 268             case twalk:
 269             case walk:
 270                 walk(fs.getPath((args.length > 2)? args[2] : "/"));
 271                 break;
 272             case extract:
 273                 if (args.length == 2) {
 274                      extract(fs, "/");
 275                 } else {
 276                     for (int i = 2; i < args.length; i++) {
 277                         extract(fs, args[i]);
 278                     }
 279                 }
 280                 break;
 281             case delete:
 282                 for (int i = 2; i < args.length; i++)
 283                     Files.delete(fs.getPath(args[i]));
 284                 break;
 285             case create:
 286             case add:
 287             case update:
 288                 for (int i = 2; i < args.length; i++) {
 289                     update(fs, args[i]);
 290                 }
 291                 break;
 292             case lsdir:
 293                 path = fs.getPath(args[2]);
 294                 final String fStr = (args.length > 3)?args[3]:"";
 295                 try (DirectoryStream<Path> ds = Files.newDirectoryStream(path,
 296                     new DirectoryStream.Filter<Path>() {
 297                         @Override
 298                         public boolean accept(Path path) {
 299                             return path.toString().contains(fStr);
 300                         }
 301                     }))
 302                 {
 303                     for (Path p : ds)
 304                         System.out.println(p);
 305                 }
 306                 break;
 307             case mkdir:
 308                 Files.createDirectory(fs.getPath(args[2]));
 309                 break;
 310             case mkdirs:
 311                 mkdirs(fs.getPath(args[2]));
 312                 break;
 313             case attrs2:
 314                 for (int i = 2; i < args.length; i++) {
 315                     path = fs.getPath(args[i]);
 316                     System.out.printf("%n%s%n", path);
 317                     System.out.println("-------(1)---------");
 318                     System.out.println(
 319                         Files.readAttributes(path, BasicFileAttributes.class).toString());
 320                     System.out.println("-------(2)---------");
 321                     Map<String, Object> map = Files.readAttributes(path, "zip:*");
 322                     for (Map.Entry<String, Object> e : map.entrySet()) {
 323                         System.out.printf("    %s : %s%n", e.getKey(), e.getValue());
 324                     }
 325                     System.out.println("-------(3)---------");
 326                     map = Files.readAttributes(path, "size,lastModifiedTime,isDirectory");
 327                     for (Map.Entry<String, ?> e : map.entrySet()) {
 328                         System.out.printf("    %s : %s%n", e.getKey(), e.getValue());
 329                     }
 330                 }
 331                 break;
 332             case prof:
 333                 list(fs.getPath("/"), false);
 334                 while (true) {
 335                     Thread.sleep(10000);
 336                     //list(fs.getPath("/"), true);
 337                     System.out.println("sleeping...");
 338                 }
 339             }
 340         } catch (Exception x) {
 341             x.printStackTrace();
 342         }
 343     }
 344 
 345     private static FileSystemProvider getZipFSProvider() {
 346         for (FileSystemProvider provider : FileSystemProvider.installedProviders()) {
 347             if ("jar".equals(provider.getScheme()))
 348                 return provider;
 349         }
 350         return null;
 351     }
 352 
 353     @SuppressWarnings("unused")
 354     /**
 355      * Not used in demo, but included for demonstrational purposes.
 356      */
 357     private static byte[] getBytes(String name) {
 358         return name.getBytes();
 359     }
 360 
 361     @SuppressWarnings("unused")
 362     /**
 363      * Not used in demo, but included for demonstrational purposes.
 364      */
 365     private static String getString(byte[] name) {
 366         return new String(name);
 367     }
 368 
 369     private static void walk(Path path) throws IOException
 370     {
 371         Files.walkFileTree(
 372             path,
 373             new SimpleFileVisitor<Path>() {
 374                 private int indent = 0;
 375                 private void indent() {
 376                     int n = 0;
 377                     while (n++ < indent)
 378                         System.out.printf(" ");
 379                 }
 380 
 381                 @Override
 382                 public FileVisitResult visitFile(Path file,
 383                                                  BasicFileAttributes attrs)
 384                 {
 385                     indent();
 386                     System.out.printf("%s%n", file.getFileName().toString());
 387                     return FileVisitResult.CONTINUE;
 388                 }
 389 
 390                 @Override
 391                 public FileVisitResult preVisitDirectory(Path dir,
 392                                                          BasicFileAttributes attrs)
 393                 {
 394                     indent();
 395                     System.out.printf("[%s]%n", dir.toString());
 396                     indent += 2;
 397                     return FileVisitResult.CONTINUE;
 398                 }
 399 
 400                 @Override
 401                 public FileVisitResult postVisitDirectory(Path dir,
 402                                                           IOException ioe)
 403                 {
 404                     indent -= 2;
 405                     return FileVisitResult.CONTINUE;
 406                 }
 407         });
 408     }
 409 
 410     private static void update(FileSystem fs, String path) throws Throwable{
 411         Path src = FileSystems.getDefault().getPath(path);
 412         if (Files.isDirectory(src)) {
 413             try (DirectoryStream<Path> ds = Files.newDirectoryStream(src)) {
 414                 for (Path child : ds)
 415                     update(fs, child.toString());
 416             }
 417         } else {
 418             Path dst = fs.getPath(path);
 419             Path parent = dst.getParent();
 420             if (parent != null && Files.notExists(parent))
 421                 mkdirs(parent);
 422             Files.copy(src, dst, REPLACE_EXISTING);
 423         }
 424     }
 425 
 426     private static void extract(FileSystem fs, String path) throws Throwable{
 427         Path src = fs.getPath(path);
 428         if (Files.isDirectory(src)) {
 429             try (DirectoryStream<Path> ds = Files.newDirectoryStream(src)) {
 430                 for (Path child : ds)
 431                     extract(fs, child.toString());
 432             }
 433         } else {
 434             if (path.startsWith("/"))
 435                 path = path.substring(1);
 436             Path dst = FileSystems.getDefault().getPath(path);
 437             Path parent = dst.getParent();
 438             if (Files.notExists(parent))
 439                 mkdirs(parent);
 440             Files.copy(src, dst, REPLACE_EXISTING);
 441         }
 442     }
 443 
 444     // use DirectoryStream
 445     private static void z2zcopy(FileSystem src, FileSystem dst, String path)
 446         throws IOException
 447     {
 448         Path srcPath = src.getPath(path);
 449         Path dstPath = dst.getPath(path);
 450 
 451         if (Files.isDirectory(srcPath)) {
 452             if (!Files.exists(dstPath)) {
 453                 try {
 454                     mkdirs(dstPath);
 455                 } catch (FileAlreadyExistsException x) {}
 456             }
 457             try (DirectoryStream<Path> ds = Files.newDirectoryStream(srcPath)) {
 458                 for (Path child : ds) {
 459                     z2zcopy(src, dst,
 460                             path + (path.endsWith("/")?"":"/") + child.getFileName());
 461                 }
 462             }
 463         } else {
 464             //System.out.println("copying..." + path);
 465             Files.copy(srcPath, dstPath);
 466         }
 467     }
 468 
 469     // use TreeWalk to move
 470     private static void z2zmove(FileSystem src, FileSystem dst, String path)
 471         throws IOException
 472     {
 473         final Path srcPath = src.getPath(path).toAbsolutePath();
 474         final Path dstPath = dst.getPath(path).toAbsolutePath();
 475 
 476         Files.walkFileTree(srcPath, new SimpleFileVisitor<Path>() {
 477 
 478             @Override
 479             public FileVisitResult visitFile(Path file,
 480                                             BasicFileAttributes attrs)
 481             {
 482                 Path dst = srcPath.relativize(file);
 483                 dst = dstPath.resolve(dst);
 484                 try {
 485                     Path parent = dstPath.getParent();
 486                     if (parent != null && Files.notExists(parent))
 487                         mkdirs(parent);
 488                     Files.move(file, dst);
 489                 } catch (IOException x) {
 490                     x.printStackTrace();
 491                 }
 492                 return FileVisitResult.CONTINUE;
 493             }
 494 
 495             @Override
 496             public FileVisitResult preVisitDirectory(Path dir,
 497                                                      BasicFileAttributes attrs)
 498             {
 499                 Path dst = srcPath.relativize(dir);
 500                 dst = dstPath.resolve(dst);
 501                 try {
 502 
 503                     if (Files.notExists(dst))
 504                         mkdirs(dst);
 505                 } catch (IOException x) {
 506                     x.printStackTrace();
 507                 }
 508                 return FileVisitResult.CONTINUE;
 509             }
 510 
 511             @Override
 512             public FileVisitResult postVisitDirectory(Path dir,
 513                                                       IOException ioe)
 514                 throws IOException
 515             {
 516                 try {
 517                     Files.delete(dir);
 518                 } catch (IOException x) {
 519                     //x.printStackTrace();
 520                 }
 521                 return FileVisitResult.CONTINUE;
 522             }
 523         });
 524 
 525     }
 526 
 527     private static void mkdirs(Path path) throws IOException {
 528         path = path.toAbsolutePath();
 529         Path parent = path.getParent();
 530         if (parent != null) {
 531             if (Files.notExists(parent))
 532                 mkdirs(parent);
 533         }
 534         Files.createDirectory(path);
 535     }
 536 
 537     @SuppressWarnings("unused")
 538     /**
 539      * Not used in demo, but included for demonstrational purposes.
 540      */
 541     private static void rmdirs(Path path) throws IOException {
 542         while (path != null && path.getNameCount() != 0) {
 543             Files.delete(path);
 544             path = path.getParent();
 545         }
 546     }
 547 
 548     private static void list(Path path, boolean verbose ) throws IOException {
 549         if (!"/".equals(path.toString())) {
 550            System.out.printf("  %s%n", path.toString());
 551            if (verbose)
 552                 System.out.println(Files.readAttributes(path, BasicFileAttributes.class).toString());
 553         }
 554         if (Files.notExists(path))
 555             return;
 556         if (Files.isDirectory(path)) {
 557             try (DirectoryStream<Path> ds = Files.newDirectoryStream(path)) {
 558                 for (Path child : ds)
 559                     list(child, verbose);
 560             }
 561         }
 562     }
 563 
 564     @SuppressWarnings("unused")
 565     /**
 566      * Checks that the content of two paths are equal.
 567      * Not used in demo, but included for demonstrational purposes.
 568      */
 569     private static void checkEqual(Path src, Path dst) throws IOException
 570     {
 571         //System.out.printf("checking <%s> vs <%s>...%n",
 572         //                  src.toString(), dst.toString());
 573 
 574         //streams
 575         byte[] bufSrc = new byte[8192];
 576         byte[] bufDst = new byte[8192];
 577         try (InputStream isSrc = Files.newInputStream(src);
 578              InputStream isDst = Files.newInputStream(dst))
 579         {
 580             int nSrc = 0;
 581             while ((nSrc = isSrc.read(bufSrc)) != -1) {
 582                 int nDst = 0;
 583                 while (nDst < nSrc) {
 584                     int n = isDst.read(bufDst, nDst, nSrc - nDst);
 585                     if (n == -1) {
 586                         System.out.printf("checking <%s> vs <%s>...%n",
 587                                           src.toString(), dst.toString());
 588                         throw new RuntimeException("CHECK FAILED!");
 589                     }
 590                     nDst += n;
 591                 }
 592                 while (--nSrc >= 0) {
 593                     if (bufSrc[nSrc] != bufDst[nSrc]) {
 594                         System.out.printf("checking <%s> vs <%s>...%n",
 595                                           src.toString(), dst.toString());
 596                         throw new RuntimeException("CHECK FAILED!");
 597                     }
 598                     nSrc--;
 599                 }
 600             }
 601         }
 602 
 603         // channels
 604 
 605         try (SeekableByteChannel chSrc = Files.newByteChannel(src);
 606              SeekableByteChannel chDst = Files.newByteChannel(dst))
 607         {
 608             if (chSrc.size() != chDst.size()) {
 609                 System.out.printf("src[%s].size=%d, dst[%s].size=%d%n",
 610                                   chSrc.toString(), chSrc.size(),
 611                                   chDst.toString(), chDst.size());
 612                 throw new RuntimeException("CHECK FAILED!");
 613             }
 614             ByteBuffer bbSrc = ByteBuffer.allocate(8192);
 615             ByteBuffer bbDst = ByteBuffer.allocate(8192);
 616 
 617             int nSrc = 0;
 618             while ((nSrc = chSrc.read(bbSrc)) != -1) {
 619                 int nDst = chDst.read(bbDst);
 620                 if (nSrc != nDst) {
 621                     System.out.printf("checking <%s> vs <%s>...%n",
 622                                       src.toString(), dst.toString());
 623                     throw new RuntimeException("CHECK FAILED!");
 624                 }
 625                 while (--nSrc >= 0) {
 626                     if (bbSrc.get(nSrc) != bbDst.get(nSrc)) {
 627                         System.out.printf("checking <%s> vs <%s>...%n",
 628                                           src.toString(), dst.toString());
 629                         throw new RuntimeException("CHECK FAILED!");
 630                     }
 631                     nSrc--;
 632                 }
 633                 bbSrc.flip();
 634                 bbDst.flip();
 635             }
 636         } catch (IOException x) {
 637             x.printStackTrace();
 638         }
 639     }
 640 
 641     private static void fchCopy(Path src, Path dst) throws IOException
 642     {
 643         Set<OpenOption> read = new HashSet<>();
 644         read.add(READ);
 645         Set<OpenOption> openwrite = new HashSet<>();
 646         openwrite.add(CREATE_NEW);
 647         openwrite.add(WRITE);
 648 
 649         try (FileChannel srcFc = src.getFileSystem().provider().newFileChannel(src, read);
 650              FileChannel dstFc = dst.getFileSystem().provider().newFileChannel(dst, openwrite))
 651         {
 652             ByteBuffer bb = ByteBuffer.allocate(8192);
 653             while (srcFc.read(bb) >= 0) {
 654                 bb.flip();
 655                 dstFc.write(bb);
 656                 bb.clear();
 657             }
 658         }
 659     }
 660 
 661     private static void chCopy(Path src, Path dst) throws IOException
 662     {
 663         Set<OpenOption> read = new HashSet<>();
 664         read.add(READ);
 665         Set<OpenOption> openwrite = new HashSet<>();
 666         openwrite.add(CREATE_NEW);
 667         openwrite.add(WRITE);
 668 
 669         try (SeekableByteChannel srcCh = Files.newByteChannel(src, read);
 670              SeekableByteChannel dstCh = Files.newByteChannel(dst, openwrite))
 671         {
 672             ByteBuffer bb = ByteBuffer.allocate(8192);
 673             while (srcCh.read(bb) >= 0) {
 674                 bb.flip();
 675                 dstCh.write(bb);
 676                 bb.clear();
 677             }
 678         }
 679     }
 680 
 681     private static void streamCopy(Path src, Path dst) throws IOException
 682     {
 683         byte[] buf = new byte[8192];
 684         try (InputStream isSrc = Files.newInputStream(src);
 685              OutputStream osDst = Files.newOutputStream(dst))
 686         {
 687             int n = 0;
 688             while ((n = isSrc.read(buf)) != -1) {
 689                 osDst.write(buf, 0, n);
 690             }
 691         }
 692     }
 693 }