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