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