1 /* 2 * Copyright (c) 2010, 2015, 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.File; 25 import java.io.IOException; 26 import java.io.InputStream; 27 import java.io.OutputStream; 28 import java.net.URI; 29 import java.net.URLDecoder; 30 import java.nio.ByteBuffer; 31 import java.nio.channels.FileChannel; 32 import java.nio.channels.SeekableByteChannel; 33 import java.nio.file.DirectoryStream; 34 import java.nio.file.FileAlreadyExistsException; 35 import java.nio.file.FileSystem; 36 import java.nio.file.FileSystemAlreadyExistsException; 37 import java.nio.file.FileSystemException; 38 import java.nio.file.FileSystems; 39 import java.nio.file.FileVisitResult; 40 import java.nio.file.Files; 41 import java.nio.file.OpenOption; 42 import java.nio.file.Path; 43 import java.nio.file.Paths; 44 import java.nio.file.SimpleFileVisitor; 45 import java.nio.file.attribute.BasicFileAttributeView; 46 import java.nio.file.attribute.BasicFileAttributes; 47 import java.nio.file.spi.FileSystemProvider; 48 import java.util.ArrayList; 49 import java.util.Arrays; 50 import java.util.Collections; 51 import java.util.Enumeration; 52 import java.util.HashMap; 53 import java.util.HashSet; 54 import java.util.Iterator; 55 import java.util.LinkedList; 56 import java.util.List; 57 import java.util.Map; 58 import java.util.Random; 59 import java.util.Set; 60 import java.util.concurrent.TimeUnit; 61 import java.util.zip.ZipEntry; 62 import java.util.zip.ZipFile; 63 64 import static java.nio.file.StandardOpenOption.*; 65 import static java.nio.file.StandardCopyOption.*; 66 67 /* 68 * Tests various zipfs operations. 69 * 70 * @test 71 * @bug 6990846 7009092 7009085 7015391 7014948 7005986 7017840 7007596 72 * 7157656 8002390 7012868 7012856 8015728 8038500 8040059 8069211 73 * 8131067 74 * @summary Test Zip filesystem provider 75 * @run main ZipFSTester 76 * @run main/othervm/java.security.policy=test.policy ZipFSTester 77 * @modules jdk.zipfs 78 */ 79 80 public class ZipFSTester { 81 82 public static void main(String[] args) throws Exception { 83 84 // create JAR file for test, actual contents don't matter 85 Path jarFile = Utils.createJarFile("tester.jar", 86 "META-INF/MANIFEST.MF", 87 "dir1/foo", 88 "dir2/bar"); 89 90 try (FileSystem fs = newZipFileSystem(jarFile, Collections.emptyMap())) { 91 test0(fs); 92 test1(fs); 93 test2(fs); // more tests 94 } 95 testTime(jarFile); 96 test8069211(); 97 test8131067(); 98 } 99 100 static void test0(FileSystem fs) 101 throws Exception 102 { 103 List<String> list = new LinkedList<>(); 104 try (ZipFile zf = new ZipFile(fs.toString())) { 105 Enumeration<? extends ZipEntry> zes = zf.entries(); 106 while (zes.hasMoreElements()) { 107 list.add(zes.nextElement().getName()); 108 } 109 for (String pname : list) { 110 Path path = fs.getPath(pname); 111 if (!Files.exists(path)) 112 throw new RuntimeException("path existence check failed!"); 113 while ((path = path.getParent()) != null) { 114 if (!Files.exists(path)) 115 throw new RuntimeException("parent existence check failed!"); 116 } 117 } 118 } 119 } 120 121 static void test1(FileSystem fs0) 122 throws Exception 123 { 124 Random rdm = new Random(); 125 // clone a fs and test on it 126 Path tmpfsPath = getTempPath(); 127 Map<String, Object> env = new HashMap<String, Object>(); 128 env.put("create", "true"); 129 try (FileSystem copy = newZipFileSystem(tmpfsPath, env)) { 130 z2zcopy(fs0, copy, "/", 0); 131 } 132 133 try (FileSystem fs = newZipFileSystem(tmpfsPath, new HashMap<String, Object>())) { 134 135 FileSystemProvider provider = fs.provider(); 136 // newFileSystem(path...) should not throw exception 137 try (FileSystem fsPath = provider.newFileSystem(tmpfsPath, new HashMap<String, Object>())){} 138 try (FileSystem fsUri = provider.newFileSystem( 139 new URI("jar", tmpfsPath.toUri().toString(), null), 140 new HashMap<String, Object>())) 141 { 142 throw new RuntimeException("newFileSystem(URI...) does not throw exception"); 143 } catch (FileSystemAlreadyExistsException fsaee) {} 144 145 // prepare a src 146 Path src = getTempPath(); 147 String tmpName = src.toString(); 148 OutputStream os = Files.newOutputStream(src); 149 byte[] bits = new byte[12345]; 150 rdm.nextBytes(bits); 151 os.write(bits); 152 os.close(); 153 154 try { 155 provider.newFileSystem(new File(System.getProperty("test.src", ".")).toPath(), 156 new HashMap<String, Object>()); 157 throw new RuntimeException("newFileSystem() opens a directory as zipfs"); 158 } catch (UnsupportedOperationException uoe) {} 159 160 try { 161 provider.newFileSystem(src, new HashMap<String, Object>()); 162 throw new RuntimeException("newFileSystem() opens a non-zip file as zipfs"); 163 } catch (UnsupportedOperationException uoe) {} 164 165 166 // copyin 167 Path dst = getPathWithParents(fs, tmpName); 168 Files.copy(src, dst); 169 checkEqual(src, dst); 170 171 // copy 172 Path dst2 = getPathWithParents(fs, "/xyz" + rdm.nextInt(100) + 173 "/efg" + rdm.nextInt(100) + "/foo.class"); 174 Files.copy(dst, dst2); 175 //dst.moveTo(dst2); 176 checkEqual(src, dst2); 177 178 // delete 179 Files.delete(dst); 180 if (Files.exists(dst)) 181 throw new RuntimeException("Failed!"); 182 183 // moveout 184 Path dst3 = Paths.get(tmpName + "_Tmp"); 185 Files.move(dst2, dst3); 186 checkEqual(src, dst3); 187 if (Files.exists(dst2)) 188 throw new RuntimeException("Failed!"); 189 190 // copyback + move 191 Files.copy(dst3, dst); 192 Path dst4 = getPathWithParents(fs, tmpName + "_Tmp0"); 193 Files.move(dst, dst4); 194 checkEqual(src, dst4); 195 196 // delete 197 Files.delete(dst4); 198 if (Files.exists(dst4)) 199 throw new RuntimeException("Failed!"); 200 Files.delete(dst3); 201 if (Files.exists(dst3)) 202 throw new RuntimeException("Failed!"); 203 204 // move (existing entry) 205 Path dst5 = fs.getPath("META-INF/MANIFEST.MF"); 206 if (Files.exists(dst5)) { 207 Path dst6 = fs.getPath("META-INF/MANIFEST.MF_TMP"); 208 Files.move(dst5, dst6); 209 walk(fs.getPath("/")); 210 } 211 212 // newInputStream on dir 213 Path parent = dst2.getParent(); 214 try { 215 Files.newInputStream(parent); 216 throw new RuntimeException("Failed"); 217 } catch (FileSystemException e) { 218 e.printStackTrace(); // expected fse 219 } 220 221 // rmdirs 222 try { 223 rmdirs(parent); 224 } catch (IOException x) { 225 x.printStackTrace(); 226 } 227 228 // newFileChannel() copy in, out and verify via fch 229 fchCopy(src, dst); // in 230 checkEqual(src, dst); 231 Path tmp = Paths.get(tmpName + "_Tmp"); 232 fchCopy(dst, tmp); // out 233 checkEqual(src, tmp); 234 Files.delete(tmp); 235 236 // test channels 237 channel(fs, dst); 238 Files.delete(dst); 239 Files.delete(src); 240 } finally { 241 if (Files.exists(tmpfsPath)) 242 Files.delete(tmpfsPath); 243 } 244 } 245 246 static void test2(FileSystem fs) throws Exception { 247 248 Path fs1Path = getTempPath(); 249 Path fs2Path = getTempPath(); 250 Path fs3Path = getTempPath(); 251 252 // create a new filesystem, copy everything from fs 253 Map<String, Object> env = new HashMap<String, Object>(); 254 env.put("create", "true"); 255 FileSystem fs0 = newZipFileSystem(fs1Path, env); 256 257 final FileSystem fs2 = newZipFileSystem(fs2Path, env); 258 final FileSystem fs3 = newZipFileSystem(fs3Path, env); 259 260 System.out.println("copy src: fs -> fs0..."); 261 z2zcopy(fs, fs0, "/", 0); // copy fs -> fs1 262 fs0.close(); // dump to file 263 264 System.out.println("open fs0 as fs1"); 265 env = new HashMap<String, Object>(); 266 final FileSystem fs1 = newZipFileSystem(fs1Path, env); 267 268 System.out.println("listing..."); 269 final ArrayList<String> files = new ArrayList<>(); 270 final ArrayList<String> dirs = new ArrayList<>(); 271 list(fs1.getPath("/"), files, dirs); 272 273 Thread t0 = new Thread(new Runnable() { 274 public void run() { 275 List<String> list = new ArrayList<>(dirs); 276 Collections.shuffle(list); 277 for (String path : list) { 278 try { 279 z2zcopy(fs1, fs2, path, 0); 280 } catch (Exception x) { 281 x.printStackTrace(); 282 } 283 } 284 } 285 286 }); 287 288 Thread t1 = new Thread(new Runnable() { 289 public void run() { 290 List<String> list = new ArrayList<>(dirs); 291 Collections.shuffle(list); 292 for (String path : list) { 293 try { 294 z2zcopy(fs1, fs2, path, 1); 295 } catch (Exception x) { 296 x.printStackTrace(); 297 } 298 } 299 } 300 301 }); 302 303 Thread t2 = new Thread(new Runnable() { 304 public void run() { 305 List<String> list = new ArrayList<>(dirs); 306 Collections.shuffle(list); 307 for (String path : list) { 308 try { 309 z2zcopy(fs1, fs2, path, 2); 310 } catch (Exception x) { 311 x.printStackTrace(); 312 } 313 } 314 } 315 316 }); 317 318 Thread t3 = new Thread(new Runnable() { 319 public void run() { 320 List<String> list = new ArrayList<>(files); 321 Collections.shuffle(list); 322 while (!list.isEmpty()) { 323 Iterator<String> itr = list.iterator(); 324 while (itr.hasNext()) { 325 String path = itr.next(); 326 try { 327 if (Files.exists(fs2.getPath(path))) { 328 z2zmove(fs2, fs3, path); 329 itr.remove(); 330 } 331 } catch (FileAlreadyExistsException x){ 332 itr.remove(); 333 } catch (Exception x) { 334 x.printStackTrace(); 335 } 336 } 337 } 338 } 339 340 }); 341 342 System.out.println("copying/removing..."); 343 t0.start(); t1.start(); t2.start(); t3.start(); 344 t0.join(); t1.join(); t2.join(); t3.join(); 345 346 System.out.println("closing: fs1, fs2"); 347 fs1.close(); 348 fs2.close(); 349 350 int failed = 0; 351 System.out.println("checkEqual: fs vs fs3"); 352 for (String path : files) { 353 try { 354 checkEqual(fs.getPath(path), fs3.getPath(path)); 355 } catch (IOException x) { 356 //x.printStackTrace(); 357 failed++; 358 } 359 } 360 System.out.println("closing: fs3"); 361 fs3.close(); 362 363 System.out.println("opening: fs3 as fs4"); 364 FileSystem fs4 = newZipFileSystem(fs3Path, env); 365 366 367 ArrayList<String> files2 = new ArrayList<>(); 368 ArrayList<String> dirs2 = new ArrayList<>(); 369 list(fs4.getPath("/"), files2, dirs2); 370 371 System.out.println("checkEqual: fs vs fs4"); 372 for (String path : files2) { 373 checkEqual(fs.getPath(path), fs4.getPath(path)); 374 } 375 System.out.println("walking: fs4"); 376 walk(fs4.getPath("/")); 377 System.out.println("closing: fs4"); 378 fs4.close(); 379 System.out.printf("failed=%d%n", failed); 380 381 Files.delete(fs1Path); 382 Files.delete(fs2Path); 383 Files.delete(fs3Path); 384 } 385 386 // test file stamp 387 static void testTime(Path src) throws Exception { 388 BasicFileAttributes attrs = Files 389 .getFileAttributeView(src, BasicFileAttributeView.class) 390 .readAttributes(); 391 // create a new filesystem, copy this file into it 392 Map<String, Object> env = new HashMap<String, Object>(); 393 env.put("create", "true"); 394 Path fsPath = getTempPath(); 395 FileSystem fs = newZipFileSystem(fsPath, env); 396 397 System.out.println("test copy with timestamps..."); 398 // copyin 399 Path dst = getPathWithParents(fs, "me"); 400 Files.copy(src, dst, COPY_ATTRIBUTES); 401 checkEqual(src, dst); 402 System.out.println("mtime: " + attrs.lastModifiedTime()); 403 System.out.println("ctime: " + attrs.creationTime()); 404 System.out.println("atime: " + attrs.lastAccessTime()); 405 System.out.println(" ==============>"); 406 BasicFileAttributes dstAttrs = Files 407 .getFileAttributeView(dst, BasicFileAttributeView.class) 408 .readAttributes(); 409 System.out.println("mtime: " + dstAttrs.lastModifiedTime()); 410 System.out.println("ctime: " + dstAttrs.creationTime()); 411 System.out.println("atime: " + dstAttrs.lastAccessTime()); 412 413 // 1-second granularity 414 if (attrs.lastModifiedTime().to(TimeUnit.SECONDS) != 415 dstAttrs.lastModifiedTime().to(TimeUnit.SECONDS) || 416 attrs.lastAccessTime().to(TimeUnit.SECONDS) != 417 dstAttrs.lastAccessTime().to(TimeUnit.SECONDS) || 418 attrs.creationTime().to(TimeUnit.SECONDS) != 419 dstAttrs.creationTime().to(TimeUnit.SECONDS)) { 420 throw new RuntimeException("Timestamp Copy Failed!"); 421 } 422 Files.delete(fsPath); 423 } 424 425 static void test8069211() throws Exception { 426 // create a new filesystem, copy this file into it 427 Map<String, Object> env = new HashMap<String, Object>(); 428 env.put("create", "true"); 429 Path fsPath = getTempPath(); 430 try (FileSystem fs = newZipFileSystem(fsPath, env);) { 431 OutputStream out = Files.newOutputStream(fs.getPath("/foo")); 432 out.write("hello".getBytes()); 433 out.close(); 434 out.close(); 435 } 436 try (FileSystem fs = newZipFileSystem(fsPath, new HashMap<String, Object>())) { 437 if (!Arrays.equals(Files.readAllBytes(fs.getPath("/foo")), 438 "hello".getBytes())) { 439 throw new RuntimeException("entry close() failed"); 440 } 441 } catch (Exception x) { 442 throw new RuntimeException("entry close() failed", x); 443 } finally { 444 Files.delete(fsPath); 445 } 446 } 447 448 static void test8131067() throws Exception { 449 Map<String, Object> env = new HashMap<String, Object>(); 450 env.put("create", "true"); 451 452 // file name with space character for URI to quote it 453 File tmp = File.createTempFile("test zipfs", "zip"); 454 tmp.delete(); // we need a clean path, no file 455 Path fsPath = tmp.toPath(); 456 try (FileSystem fs = newZipFileSystem(fsPath, env);) { 457 Files.write(fs.getPath("/foo"), "hello".getBytes()); 458 URI fooUri = fs.getPath("/foo").toUri(); 459 if (!Arrays.equals(Files.readAllBytes(Paths.get(fooUri)), 460 "hello".getBytes())) { 461 throw new RuntimeException("entry close() failed"); 462 } 463 } finally { 464 Files.delete(fsPath); 465 } 466 } 467 468 private static FileSystem newZipFileSystem(Path path, Map<String, ?> env) 469 throws Exception 470 { 471 // Use URLDecoder (for test only) to remove the double escaped space 472 // character 473 return FileSystems.newFileSystem( 474 new URI("jar", URLDecoder.decode(path.toUri().toString(), "utf8"), 475 null), env, null); 476 } 477 478 private static Path getTempPath() throws IOException 479 { 480 File tmp = File.createTempFile("testzipfs_", "zip"); 481 tmp.delete(); // we need a clean path, no file 482 return tmp.toPath(); 483 } 484 485 private static void list(Path path, List<String> files, List<String> dirs ) 486 throws IOException 487 { 488 if (Files.isDirectory(path)) { 489 try (DirectoryStream<Path> ds = Files.newDirectoryStream(path)) { 490 for (Path child : ds) 491 list(child, files, dirs); 492 } 493 dirs.add(path.toString()); 494 } else { 495 files.add(path.toString()); 496 } 497 } 498 499 private static void z2zcopy(FileSystem src, FileSystem dst, String path, 500 int method) 501 throws IOException 502 { 503 Path srcPath = src.getPath(path); 504 Path dstPath = dst.getPath(path); 505 506 if (Files.isDirectory(srcPath)) { 507 if (!Files.exists(dstPath)) { 508 try { 509 mkdirs(dstPath); 510 } catch (FileAlreadyExistsException x) {} 511 } 512 try (DirectoryStream<Path> ds = Files.newDirectoryStream(srcPath)) { 513 for (Path child : ds) { 514 z2zcopy(src, dst, 515 path + (path.endsWith("/")?"":"/") + child.getFileName(), 516 method); 517 } 518 } 519 } else { 520 try { 521 if (Files.exists(dstPath)) 522 return; 523 switch (method) { 524 case 0: 525 Files.copy(srcPath, dstPath); 526 break; 527 case 1: 528 chCopy(srcPath, dstPath); 529 break; 530 case 2: 531 //fchCopy(srcPath, dstPath); 532 streamCopy(srcPath, dstPath); 533 break; 534 } 535 } catch (FileAlreadyExistsException x) {} 536 } 537 } 538 539 private static void z2zmove(FileSystem src, FileSystem dst, String path) 540 throws IOException 541 { 542 Path srcPath = src.getPath(path); 543 Path dstPath = dst.getPath(path); 544 545 if (Files.isDirectory(srcPath)) { 546 if (!Files.exists(dstPath)) 547 mkdirs(dstPath); 548 try (DirectoryStream<Path> ds = Files.newDirectoryStream(srcPath)) { 549 for (Path child : ds) { 550 z2zmove(src, dst, 551 path + (path.endsWith("/")?"":"/") + child.getFileName()); 552 } 553 } 554 } else { 555 //System.out.println("moving..." + path); 556 Path parent = dstPath.getParent(); 557 if (parent != null && Files.notExists(parent)) 558 mkdirs(parent); 559 Files.move(srcPath, dstPath); 560 } 561 } 562 563 private static void walk(Path path) throws IOException 564 { 565 Files.walkFileTree( 566 path, 567 new SimpleFileVisitor<Path>() { 568 private int indent = 0; 569 private void indent() { 570 int n = 0; 571 while (n++ < indent) 572 System.out.printf(" "); 573 } 574 575 @Override 576 public FileVisitResult visitFile(Path file, 577 BasicFileAttributes attrs) 578 { 579 indent(); 580 System.out.printf("%s%n", file.getFileName().toString()); 581 return FileVisitResult.CONTINUE; 582 } 583 584 @Override 585 public FileVisitResult preVisitDirectory(Path dir, 586 BasicFileAttributes attrs) 587 { 588 indent(); 589 System.out.printf("[%s]%n", dir.toString()); 590 indent += 2; 591 return FileVisitResult.CONTINUE; 592 } 593 594 @Override 595 public FileVisitResult postVisitDirectory(Path dir, 596 IOException ioe) 597 throws IOException 598 { 599 indent -= 2; 600 return FileVisitResult.CONTINUE; 601 } 602 }); 603 } 604 605 private static void mkdirs(Path path) throws IOException { 606 if (Files.exists(path)) 607 return; 608 path = path.toAbsolutePath(); 609 Path parent = path.getParent(); 610 if (parent != null) { 611 if (Files.notExists(parent)) 612 mkdirs(parent); 613 } 614 Files.createDirectory(path); 615 } 616 617 private static void rmdirs(Path path) throws IOException { 618 while (path != null && path.getNameCount() != 0) { 619 Files.delete(path); 620 path = path.getParent(); 621 } 622 } 623 624 // check the content of two paths are equal 625 private static void checkEqual(Path src, Path dst) throws IOException 626 { 627 //System.out.printf("checking <%s> vs <%s>...%n", 628 // src.toString(), dst.toString()); 629 630 //streams 631 byte[] bufSrc = new byte[8192]; 632 byte[] bufDst = new byte[8192]; 633 try (InputStream isSrc = Files.newInputStream(src); 634 InputStream isDst = Files.newInputStream(dst)) 635 { 636 int nSrc = 0; 637 while ((nSrc = isSrc.read(bufSrc)) != -1) { 638 int nDst = 0; 639 while (nDst < nSrc) { 640 int n = isDst.read(bufDst, nDst, nSrc - nDst); 641 if (n == -1) { 642 System.out.printf("checking <%s> vs <%s>...%n", 643 src.toString(), dst.toString()); 644 throw new RuntimeException("CHECK FAILED!"); 645 } 646 nDst += n; 647 } 648 while (--nSrc >= 0) { 649 if (bufSrc[nSrc] != bufDst[nSrc]) { 650 System.out.printf("checking <%s> vs <%s>...%n", 651 src.toString(), dst.toString()); 652 throw new RuntimeException("CHECK FAILED!"); 653 } 654 nSrc--; 655 } 656 } 657 } 658 659 // channels 660 try (SeekableByteChannel chSrc = Files.newByteChannel(src); 661 SeekableByteChannel chDst = Files.newByteChannel(dst)) 662 { 663 if (chSrc.size() != chDst.size()) { 664 System.out.printf("src[%s].size=%d, dst[%s].size=%d%n", 665 chSrc.toString(), chSrc.size(), 666 chDst.toString(), chDst.size()); 667 throw new RuntimeException("CHECK FAILED!"); 668 } 669 ByteBuffer bbSrc = ByteBuffer.allocate(8192); 670 ByteBuffer bbDst = ByteBuffer.allocate(8192); 671 672 int nSrc = 0; 673 while ((nSrc = chSrc.read(bbSrc)) != -1) { 674 int nDst = chDst.read(bbDst); 675 if (nSrc != nDst) { 676 System.out.printf("checking <%s> vs <%s>...%n", 677 src.toString(), dst.toString()); 678 throw new RuntimeException("CHECK FAILED!"); 679 } 680 while (--nSrc >= 0) { 681 if (bbSrc.get(nSrc) != bbDst.get(nSrc)) { 682 System.out.printf("checking <%s> vs <%s>...%n", 683 src.toString(), dst.toString()); 684 throw new RuntimeException("CHECK FAILED!"); 685 } 686 nSrc--; 687 } 688 bbSrc.flip(); 689 bbDst.flip(); 690 } 691 692 // Check if source read position is at the end 693 if (chSrc.position() != chSrc.size()) { 694 System.out.printf("src[%s]: size=%d, position=%d%n", 695 chSrc.toString(), chSrc.size(), chSrc.position()); 696 throw new RuntimeException("CHECK FAILED!"); 697 } 698 699 // Check if destination read position is at the end 700 if (chDst.position() != chDst.size()) { 701 System.out.printf("dst[%s]: size=%d, position=%d%n", 702 chDst.toString(), chDst.size(), chDst.position()); 703 throw new RuntimeException("CHECK FAILED!"); 704 } 705 } catch (IOException x) { 706 x.printStackTrace(); 707 } 708 } 709 710 private static void fchCopy(Path src, Path dst) throws IOException 711 { 712 Set<OpenOption> read = new HashSet<>(); 713 read.add(READ); 714 Set<OpenOption> openwrite = new HashSet<>(); 715 openwrite.add(CREATE_NEW); 716 openwrite.add(WRITE); 717 718 try (FileChannel srcFc = src.getFileSystem() 719 .provider() 720 .newFileChannel(src, read); 721 FileChannel dstFc = dst.getFileSystem() 722 .provider() 723 .newFileChannel(dst, openwrite)) 724 { 725 ByteBuffer bb = ByteBuffer.allocate(8192); 726 while (srcFc.read(bb) >= 0) { 727 bb.flip(); 728 dstFc.write(bb); 729 bb.clear(); 730 } 731 } 732 } 733 734 private static void chCopy(Path src, Path dst) throws IOException 735 { 736 Set<OpenOption> read = new HashSet<>(); 737 read.add(READ); 738 Set<OpenOption> openwrite = new HashSet<>(); 739 openwrite.add(CREATE_NEW); 740 openwrite.add(WRITE); 741 742 try (SeekableByteChannel srcCh = Files.newByteChannel(src, read); 743 SeekableByteChannel dstCh = Files.newByteChannel(dst, openwrite)) 744 { 745 746 ByteBuffer bb = ByteBuffer.allocate(8192); 747 while (srcCh.read(bb) >= 0) { 748 bb.flip(); 749 dstCh.write(bb); 750 bb.clear(); 751 } 752 753 // Check if source read position is at the end 754 if (srcCh.position() != srcCh.size()) { 755 System.out.printf("src[%s]: size=%d, position=%d%n", 756 srcCh.toString(), srcCh.size(), srcCh.position()); 757 throw new RuntimeException("CHECK FAILED!"); 758 } 759 760 // Check if destination write position is at the end 761 if (dstCh.position() != dstCh.size()) { 762 System.out.printf("dst[%s]: size=%d, position=%d%n", 763 dstCh.toString(), dstCh.size(), dstCh.position()); 764 throw new RuntimeException("CHECK FAILED!"); 765 } 766 } 767 } 768 769 private static void streamCopy(Path src, Path dst) throws IOException 770 { 771 byte[] buf = new byte[8192]; 772 try (InputStream isSrc = Files.newInputStream(src); 773 OutputStream osDst = Files.newOutputStream(dst)) 774 { 775 int n = 0; 776 while ((n = isSrc.read(buf)) != -1) { 777 osDst.write(buf, 0, n); 778 } 779 } 780 } 781 782 static void channel(FileSystem fs, Path path) 783 throws Exception 784 { 785 System.out.println("test ByteChannel..."); 786 Set<OpenOption> read = new HashSet<>(); 787 read.add(READ); 788 int n = 0; 789 ByteBuffer bb = null; 790 ByteBuffer bb2 = null; 791 int N = 120; 792 793 try (SeekableByteChannel sbc = Files.newByteChannel(path)) { 794 System.out.printf(" sbc[0]: pos=%d, size=%d%n", sbc.position(), sbc.size()); 795 if (sbc.position() != 0) { 796 throw new RuntimeException("CHECK FAILED!"); 797 } 798 799 bb = ByteBuffer.allocate((int)sbc.size()); 800 n = sbc.read(bb); 801 System.out.printf(" sbc[1]: read=%d, pos=%d, size=%d%n", 802 n, sbc.position(), sbc.size()); 803 if (sbc.position() != sbc.size()) { 804 throw new RuntimeException("CHECK FAILED!"); 805 } 806 bb2 = ByteBuffer.allocate((int)sbc.size()); 807 } 808 809 // sbc.position(pos) is not supported in current version 810 // try the FileChannel 811 try (SeekableByteChannel sbc = fs.provider().newFileChannel(path, read)) { 812 sbc.position(N); 813 System.out.printf(" sbc[2]: pos=%d, size=%d%n", 814 sbc.position(), sbc.size()); 815 if (sbc.position() != N) { 816 throw new RuntimeException("CHECK FAILED!"); 817 } 818 bb2.limit(100); 819 n = sbc.read(bb2); 820 System.out.printf(" sbc[3]: read=%d, pos=%d, size=%d%n", 821 n, sbc.position(), sbc.size()); 822 if (n < 0 || sbc.position() != (N + n)) { 823 throw new RuntimeException("CHECK FAILED!"); 824 } 825 System.out.printf(" sbc[4]: bb[%d]=%d, bb1[0]=%d%n", 826 N, bb.get(N) & 0xff, bb2.get(0) & 0xff); 827 } 828 } 829 830 // create parents if does not exist 831 static Path getPathWithParents(FileSystem fs, String name) 832 throws Exception 833 { 834 Path path = fs.getPath(name); 835 Path parent = path.getParent(); 836 if (parent != null && Files.notExists(parent)) 837 mkdirs(parent); 838 return path; 839 } 840 }