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 * @modules jdk.zipfs 76 * @run main ZipFSTester 77 * @run main/othervm/java.security.policy=test.policy ZipFSTester 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"); 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 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 { 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) { 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 { | 1 /* 2 * Copyright (c) 2010, 2018, 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.Channels; 32 import java.nio.channels.FileChannel; 33 import java.nio.channels.SeekableByteChannel; 34 import java.nio.file.DirectoryStream; 35 import java.nio.file.FileAlreadyExistsException; 36 import java.nio.file.FileSystem; 37 import java.nio.file.FileSystemAlreadyExistsException; 38 import java.nio.file.FileSystemException; 39 import java.nio.file.FileSystems; 40 import java.nio.file.FileVisitResult; 41 import java.nio.file.Files; 42 import java.nio.file.OpenOption; 43 import java.nio.file.Path; 44 import java.nio.file.Paths; 45 import java.nio.file.SimpleFileVisitor; 46 import java.nio.file.attribute.BasicFileAttributeView; 47 import java.nio.file.attribute.BasicFileAttributes; 48 import java.nio.file.spi.FileSystemProvider; 49 import java.util.ArrayList; 50 import java.util.Arrays; 51 import java.util.Collections; 52 import java.util.Enumeration; 53 import java.util.HashMap; 54 import java.util.HashSet; 55 import java.util.Iterator; 56 import java.util.LinkedList; 57 import java.util.List; 58 import java.util.Map; 59 import java.util.Random; 60 import java.util.Set; 61 import java.util.concurrent.TimeUnit; 62 import java.util.zip.CRC32; 63 import java.util.zip.ZipEntry; 64 import java.util.zip.ZipFile; 65 import java.util.zip.ZipOutputStream; 66 67 import static java.nio.file.StandardOpenOption.*; 68 import static java.nio.file.StandardCopyOption.*; 69 70 /* 71 * Tests various zipfs operations. 72 * 73 * @test 74 * @bug 6990846 7009092 7009085 7015391 7014948 7005986 7017840 7007596 75 * 7157656 8002390 7012868 7012856 8015728 8038500 8040059 8069211 76 * 8131067 8034802 77 * @summary Test Zip filesystem provider 78 * @modules jdk.zipfs 79 * @run main ZipFSTester 80 * @run main/othervm/java.security.policy=test.policy ZipFSTester 81 */ 82 83 public class ZipFSTester { 84 85 public static void main(String[] args) throws Exception { 86 // create JAR file for test, actual contents don't matter 87 Path jarFile = Utils.createJarFile("tester.jar", 88 "META-INF/MANIFEST.MF", 89 "dir1/foo", 90 "dir2/bar", 91 "dir1/dir3/fooo"); 92 93 try (FileSystem fs = newZipFileSystem(jarFile, Collections.emptyMap())) { 94 test0(fs); 95 test1(fs); 96 test2(fs); // more tests 97 } 98 99 testStreamChannel(); 100 testTime(jarFile); 101 test8069211(); 102 test8131067(); 103 } 104 105 private static Random rdm = new Random(); 106 107 static void test0(FileSystem fs) 108 throws Exception 109 { 110 List<String> list = new LinkedList<>(); 111 try (ZipFile zf = new ZipFile(fs.toString())) { 112 Enumeration<? extends ZipEntry> zes = zf.entries(); 113 while (zes.hasMoreElements()) { 114 list.add(zes.nextElement().getName()); 115 } 116 for (String pname : list) { 117 Path path = fs.getPath(pname); 118 if (!Files.exists(path)) 119 throw new RuntimeException("path existence check failed!"); 120 while ((path = path.getParent()) != null) { 121 if (!Files.exists(path)) 122 throw new RuntimeException("parent existence check failed!"); 123 } 124 } 125 } 126 } 127 128 static void test1(FileSystem fs0) 129 throws Exception 130 { 131 // prepare a src for testing 132 Path src = getTempPath(); 133 String tmpName = src.toString(); 134 try (OutputStream os = Files.newOutputStream(src)) { 135 byte[] bits = new byte[12345]; 136 rdm.nextBytes(bits); 137 os.write(bits); 138 } 139 140 // clone a fs from fs0 and test on it 141 Path tmpfsPath = getTempPath(); 142 Map<String, Object> env = new HashMap<String, Object>(); 143 env.put("create", "true"); 144 try (FileSystem copy = newZipFileSystem(tmpfsPath, env)) { 145 z2zcopy(fs0, copy, "/", 0); 146 147 // copy the test jar itself in 148 Files.copy(Paths.get(fs0.toString()), copy.getPath("/foo.jar")); 149 Path zpath = copy.getPath("/foo.jar"); 150 try (FileSystem zzfs = FileSystems.newFileSystem(zpath, null)) { 151 Files.copy(src, zzfs.getPath("/srcInjarjar")); 152 } 153 } 154 155 try (FileSystem fs = newZipFileSystem(tmpfsPath, new HashMap<String, Object>())) { 156 157 FileSystemProvider provider = fs.provider(); 158 // newFileSystem(path...) should not throw exception 159 try (FileSystem fsPath = provider.newFileSystem(tmpfsPath, new HashMap<String, Object>())){} 160 try (FileSystem fsUri = provider.newFileSystem( 161 new URI("jar", tmpfsPath.toUri().toString(), null), 162 new HashMap<String, Object>())) 163 { 164 throw new RuntimeException("newFileSystem(URI...) does not throw exception"); 165 } catch (FileSystemAlreadyExistsException fsaee) {} 166 167 try { 168 provider.newFileSystem(new File(System.getProperty("test.src", ".")).toPath(), 169 new HashMap<String, Object>()); 170 throw new RuntimeException("newFileSystem() opens a directory as zipfs"); 171 } catch (UnsupportedOperationException uoe) {} 172 173 try { 174 provider.newFileSystem(src, new HashMap<String, Object>()); 175 throw new RuntimeException("newFileSystem() opens a non-zip file as zipfs"); 176 } catch (UnsupportedOperationException uoe) {} 177 178 // walk 179 walk(fs.getPath("/")); 180 181 // copyin 182 Path dst = getPathWithParents(fs, tmpName); 183 Files.copy(src, dst); 184 checkEqual(src, dst); 185 186 // copy 187 Path dst2 = getPathWithParents(fs, "/xyz" + rdm.nextInt(100) + 188 "/efg" + rdm.nextInt(100) + "/foo.class"); 189 Files.copy(dst, dst2); 190 //dst.moveTo(dst2); 191 checkEqual(src, dst2); 192 193 // delete 194 Files.delete(dst); 195 if (Files.exists(dst)) 196 throw new RuntimeException("Failed!"); 197 198 // moveout 199 Path dst3 = Paths.get(tmpName + "_Tmp"); 234 } 235 236 // rmdirs 237 try { 238 rmdirs(parent); 239 } catch (IOException x) { 240 x.printStackTrace(); 241 } 242 243 // newFileChannel() copy in, out and verify via fch 244 fchCopy(src, dst); // in 245 checkEqual(src, dst); 246 Path tmp = Paths.get(tmpName + "_Tmp"); 247 fchCopy(dst, tmp); // out 248 checkEqual(src, tmp); 249 Files.delete(tmp); 250 251 // test channels 252 channel(fs, dst); 253 Files.delete(dst); 254 255 // test foo.jar in jar/zipfs #8034802 256 Path jpath = fs.getPath("/foo.jar"); 257 System.out.println("walking: " + jpath); 258 try (FileSystem zzfs = FileSystems.newFileSystem(jpath, null)) { 259 walk(zzfs.getPath("/")); 260 // foojar:/srcInjarjar 261 checkEqual(src, zzfs.getPath("/srcInjarjar")); 262 263 dst = getPathWithParents(zzfs, tmpName); 264 fchCopy(src, dst); 265 checkEqual(src, dst); 266 tmp = Paths.get(tmpName + "_Tmp"); 267 fchCopy(dst, tmp); // out 268 checkEqual(src, tmp); 269 Files.delete(tmp); 270 271 channel(zzfs, dst); 272 Files.delete(dst); 273 } 274 } finally { 275 Files.deleteIfExists(tmpfsPath); 276 Files.deleteIfExists(src); 277 } 278 } 279 280 static void test2(FileSystem fs) throws Exception { 281 282 Path fs1Path = getTempPath(); 283 Path fs2Path = getTempPath(); 284 Path fs3Path = getTempPath(); 285 286 // create a new filesystem, copy everything from fs 287 Map<String, Object> env = new HashMap<String, Object>(); 288 env.put("create", "true"); 289 FileSystem fs0 = newZipFileSystem(fs1Path, env); 290 291 final FileSystem fs2 = newZipFileSystem(fs2Path, env); 292 final FileSystem fs3 = newZipFileSystem(fs3Path, env); 293 294 System.out.println("copy src: fs -> fs0..."); 295 z2zcopy(fs, fs0, "/", 0); // copy fs -> fs1 296 fs0.close(); // dump to file 400 401 ArrayList<String> files2 = new ArrayList<>(); 402 ArrayList<String> dirs2 = new ArrayList<>(); 403 list(fs4.getPath("/"), files2, dirs2); 404 405 System.out.println("checkEqual: fs vs fs4"); 406 for (String path : files2) { 407 checkEqual(fs.getPath(path), fs4.getPath(path)); 408 } 409 System.out.println("walking: fs4"); 410 walk(fs4.getPath("/")); 411 System.out.println("closing: fs4"); 412 fs4.close(); 413 System.out.printf("failed=%d%n", failed); 414 415 Files.delete(fs1Path); 416 Files.delete(fs2Path); 417 Files.delete(fs3Path); 418 } 419 420 static final int METHOD_STORED = 0; 421 static final int METHOD_DEFLATED = 8; 422 423 static Object[][] getEntries() { 424 Object[][] entries = new Object[10 + rdm.nextInt(20)][3]; 425 for (int i = 0; i < entries.length; i++) { 426 entries[i][0] = "entries" + i; 427 entries[i][1] = rdm.nextInt(10) % 2 == 0 ? 428 METHOD_STORED : METHOD_DEFLATED; 429 entries[i][2] = new byte[rdm.nextInt(8192)]; 430 rdm.nextBytes((byte[])entries[i][2]); 431 } 432 return entries; 433 } 434 435 // check the content of read from zipfs is equal to the "bytes" 436 private static void checkRead(Path path, byte[] expected) throws IOException { 437 //streams 438 try (InputStream is = Files.newInputStream(path)) { 439 if (!Arrays.equals(is.readAllBytes(), expected)) { 440 System.out.printf(" newInputStream <%s> failed...%n", path.toString()); 441 throw new RuntimeException("CHECK FAILED!"); 442 } 443 } 444 445 // channels -- via sun.nio.ch.ChannelInputStream 446 try (SeekableByteChannel sbc = Files.newByteChannel(path); 447 InputStream is = Channels.newInputStream(sbc)) { 448 449 // check all bytes match 450 if (!Arrays.equals(is.readAllBytes(), expected)) { 451 System.out.printf(" newByteChannel <%s> failed...%n", path.toString()); 452 throw new RuntimeException("CHECK FAILED!"); 453 } 454 455 // Check if read position is at the end 456 if (sbc.position() != expected.length) { 457 System.out.printf("pos [%s]: size=%d, position=%d%n", 458 path.toString(), expected.length, sbc.position()); 459 throw new RuntimeException("CHECK FAILED!"); 460 } 461 462 // Check position(x) + read() at the random/specific pos/len 463 byte[] buf = new byte[1024]; 464 ByteBuffer bb = ByteBuffer.wrap(buf); 465 for (int i = 0; i < 10; i++) { 466 int pos = rdm.nextInt((int)sbc.size()); 467 int len = rdm.nextInt(Math.min(buf.length, expected.length - pos)); 468 // System.out.printf(" --> %d, %d%n", pos, len); 469 bb.position(0).limit(len); // bb.flip().limit(len); 470 if (sbc.position(pos).position() != pos || 471 sbc.read(bb) != len || 472 !Arrays.equals(buf, 0, bb.position(), expected, pos, pos + len)) { 473 System.out.printf("read()/position() failed%n"); 474 } 475 } 476 } catch (IOException x) { 477 x.printStackTrace(); 478 throw new RuntimeException("CHECK FAILED!"); 479 } 480 } 481 482 // test entry stream/channel reading 483 static void testStreamChannel() throws Exception { 484 Path zpath = getTempPath(); 485 try { 486 var crc = new CRC32(); 487 Object[][] entries = getEntries(); 488 489 // [1] create zip via ZipOutputStream 490 try (var os = Files.newOutputStream(zpath); 491 var zos = new ZipOutputStream(os)) { 492 for (Object[] entry : entries) { 493 var ze = new ZipEntry((String)entry[0]); 494 int method = (int)entry[1]; 495 byte[] bytes = (byte[])entry[2]; 496 if (method == METHOD_STORED) { 497 ze.setSize(bytes.length); 498 crc.reset(); 499 crc.update(bytes); 500 ze.setCrc(crc.getValue()); 501 } 502 ze.setMethod(method); 503 zos.putNextEntry(ze); 504 zos.write(bytes); 505 zos.closeEntry(); 506 } 507 } 508 try (var zfs = newZipFileSystem(zpath, Collections.emptyMap())) { 509 for (Object[] e : entries) { 510 Path path = zfs.getPath((String)e[0]); 511 int method = (int)e[1]; 512 byte[] bytes = (byte[])e[2]; 513 // System.out.printf("checking read [%s, %d, %d]%n", 514 // path.toString(), bytes.length, method); 515 checkRead(path, bytes); 516 } 517 } 518 Files.deleteIfExists(zpath); 519 520 // [2] create zip via zfs.newByteChannel 521 try (var zfs = newZipFileSystem(zpath, Map.of("create", "true"))) { 522 for (Object[] e : entries) { 523 // tbd: method is not used 524 try (var sbc = Files.newByteChannel(zfs.getPath((String)e[0]), 525 CREATE_NEW, WRITE)) { 526 sbc.write(ByteBuffer.wrap((byte[])e[2])); 527 } 528 } 529 } 530 try (var zfs = newZipFileSystem(zpath, Collections.emptyMap())) { 531 for (Object[] e : entries) { 532 checkRead(zfs.getPath((String)e[0]), (byte[])e[2]); 533 } 534 } 535 Files.deleteIfExists(zpath); 536 537 // [3] create zip via Files.write()/newoutputStream/ 538 try (var zfs = newZipFileSystem(zpath, Map.of("create", "true"))) { 539 for (Object[] e : entries) { 540 Files.write(zfs.getPath((String)e[0]), (byte[])e[2]); 541 } 542 } 543 try (var zfs = newZipFileSystem(zpath, Collections.emptyMap())) { 544 for (Object[] e : entries) { 545 checkRead(zfs.getPath((String)e[0]), (byte[])e[2]); 546 } 547 } 548 Files.deleteIfExists(zpath); 549 550 // [4] create zip via zfs.newByteChannel, with "method_stored" 551 try (var zfs = newZipFileSystem(zpath, 552 Map.of("create", true, "noCompression", true))) { 553 for (Object[] e : entries) { 554 try (var sbc = Files.newByteChannel(zfs.getPath((String)e[0]), 555 CREATE_NEW, WRITE)) { 556 sbc.write(ByteBuffer.wrap((byte[])e[2])); 557 } 558 } 559 } 560 try (var zfs = newZipFileSystem(zpath, Collections.emptyMap())) { 561 for (Object[] e : entries) { 562 checkRead(zfs.getPath((String)e[0]), (byte[])e[2]); 563 } 564 } 565 Files.deleteIfExists(zpath); 566 567 } finally { 568 Files.deleteIfExists(zpath); 569 } 570 } 571 572 // test file stamp 573 static void testTime(Path src) throws Exception { 574 BasicFileAttributes attrs = Files 575 .getFileAttributeView(src, BasicFileAttributeView.class) 576 .readAttributes(); 577 // create a new filesystem, copy this file into it 578 Map<String, Object> env = new HashMap<String, Object>(); 579 env.put("create", "true"); 580 Path fsPath = getTempPath(); 581 try (FileSystem fs = newZipFileSystem(fsPath, env)) { 582 System.out.println("test copy with timestamps..."); 583 // copyin 584 Path dst = getPathWithParents(fs, "me"); 585 Files.copy(src, dst, COPY_ATTRIBUTES); 586 checkEqual(src, dst); 587 System.out.println("mtime: " + attrs.lastModifiedTime()); 588 System.out.println("ctime: " + attrs.creationTime()); 589 System.out.println("atime: " + attrs.lastAccessTime()); 590 System.out.println(" ==============>"); 591 BasicFileAttributes dstAttrs = Files 592 .getFileAttributeView(dst, BasicFileAttributeView.class) 593 .readAttributes(); 594 System.out.println("mtime: " + dstAttrs.lastModifiedTime()); 595 System.out.println("ctime: " + dstAttrs.creationTime()); 596 System.out.println("atime: " + dstAttrs.lastAccessTime()); 597 598 // 1-second granularity 599 if (attrs.lastModifiedTime().to(TimeUnit.SECONDS) != 600 dstAttrs.lastModifiedTime().to(TimeUnit.SECONDS) || 601 attrs.lastAccessTime().to(TimeUnit.SECONDS) != 602 dstAttrs.lastAccessTime().to(TimeUnit.SECONDS) || 603 attrs.creationTime().to(TimeUnit.SECONDS) != 604 dstAttrs.creationTime().to(TimeUnit.SECONDS)) { 605 throw new RuntimeException("Timestamp Copy Failed!"); 606 } 607 } finally { 608 Files.delete(fsPath); 609 } 610 } 611 612 static void test8069211() throws Exception { 613 // create a new filesystem, copy this file into it 614 Map<String, Object> env = new HashMap<String, Object>(); 615 env.put("create", "true"); 616 Path fsPath = getTempPath(); 617 try (FileSystem fs = newZipFileSystem(fsPath, env);) { 618 OutputStream out = Files.newOutputStream(fs.getPath("/foo")); 619 out.write("hello".getBytes()); 620 out.close(); 621 out.close(); 622 } 623 try (FileSystem fs = newZipFileSystem(fsPath, new HashMap<String, Object>())) { 624 if (!Arrays.equals(Files.readAllBytes(fs.getPath("/foo")), 625 "hello".getBytes())) { 626 throw new RuntimeException("entry close() failed"); 627 } 628 } catch (Exception x) { 629 throw new RuntimeException("entry close() failed", x); 630 } finally { 794 return; 795 path = path.toAbsolutePath(); 796 Path parent = path.getParent(); 797 if (parent != null) { 798 if (Files.notExists(parent)) 799 mkdirs(parent); 800 } 801 Files.createDirectory(path); 802 } 803 804 private static void rmdirs(Path path) throws IOException { 805 while (path != null && path.getNameCount() != 0) { 806 Files.delete(path); 807 path = path.getParent(); 808 } 809 } 810 811 // check the content of two paths are equal 812 private static void checkEqual(Path src, Path dst) throws IOException 813 { 814 System.out.printf("checking <%s> vs <%s>...%n", 815 src.toString(), dst.toString()); 816 817 //streams 818 byte[] bufSrc = new byte[8192]; 819 byte[] bufDst = new byte[8192]; 820 try (InputStream isSrc = Files.newInputStream(src); 821 InputStream isDst = Files.newInputStream(dst)) 822 { 823 int nSrc = 0; 824 while ((nSrc = isSrc.read(bufSrc)) != -1) { 825 int nDst = 0; 826 while (nDst < nSrc) { 827 int n = isDst.read(bufDst, nDst, nSrc - nDst); 828 if (n == -1) { 829 System.out.printf("checking <%s> vs <%s>...%n", 830 src.toString(), dst.toString()); 831 throw new RuntimeException("CHECK FAILED!"); 832 } 833 nDst += n; 834 } 835 while (--nSrc >= 0) { 872 } 873 nSrc--; 874 } 875 bbSrc.flip(); 876 bbDst.flip(); 877 } 878 879 // Check if source read position is at the end 880 if (chSrc.position() != chSrc.size()) { 881 System.out.printf("src[%s]: size=%d, position=%d%n", 882 chSrc.toString(), chSrc.size(), chSrc.position()); 883 throw new RuntimeException("CHECK FAILED!"); 884 } 885 886 // Check if destination read position is at the end 887 if (chDst.position() != chDst.size()) { 888 System.out.printf("dst[%s]: size=%d, position=%d%n", 889 chDst.toString(), chDst.size(), chDst.position()); 890 throw new RuntimeException("CHECK FAILED!"); 891 } 892 893 // Check position(x) + read() at the specific pos/len 894 for (int i = 0; i < 10; i++) { 895 int pos = rdm.nextInt((int)chSrc.size()); 896 int limit = rdm.nextInt(1024); 897 if (chSrc.position(pos).position() != chDst.position(pos).position()) { 898 System.out.printf("dst/src.position(pos failed%n"); 899 } 900 bbSrc.clear().limit(limit); 901 bbDst.clear().limit(limit); 902 if (chSrc.read(bbSrc) != chDst.read(bbDst) || 903 !bbSrc.flip().equals(bbDst.flip())) { 904 System.out.printf("dst/src.read() failed%n"); 905 } 906 } 907 } catch (IOException x) { 908 x.printStackTrace(); 909 } 910 } 911 912 private static void fchCopy(Path src, Path dst) throws IOException 913 { 914 Set<OpenOption> read = new HashSet<>(); 915 read.add(READ); 916 Set<OpenOption> openwrite = new HashSet<>(); 917 openwrite.add(CREATE_NEW); 918 openwrite.add(WRITE); 919 920 try (FileChannel srcFc = src.getFileSystem() 921 .provider() 922 .newFileChannel(src, read); 923 FileChannel dstFc = dst.getFileSystem() 924 .provider() 925 .newFileChannel(dst, openwrite)) 926 { |