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 }