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