1 /* 2 * Copyright (c) 2009, 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.file.*; 27 import java.nio.file.attribute.*; 28 import java.nio.file.spi.*; 29 import java.util.*; 30 import java.util.zip.*; 31 32 import static java.nio.file.StandardCopyOption.*; 33 34 public class LargeZip { 35 // If true, don't delete large ZIP file created for test. 36 static final boolean debug = System.getProperty("debug") != null; 37 38 //static final int DATA_LEN = 1024 * 1024; 39 static final int DATA_LEN = 80 * 1024; 40 static final int DATA_SIZE = 8; 41 42 static long fileSize = 6L * 1024L * 1024L * 1024L; // 6GB 43 44 static boolean userFile = false; 45 static byte[] data; 46 static File largeFile; 47 static String lastEntryName; 48 49 /* args can be empty, in which case check a 3 GB file which is created for 50 * this test (and then deleted). Or it can be a number, in which case 51 * that designates the size of the file that's created for this test (and 52 * then deleted). Or it can be the name of a file to use for the test, in 53 * which case it is *not* deleted. Note that in this last case, the data 54 * comparison might fail. 55 */ realMain(String[] args)56 static void realMain (String[] args) throws Throwable { 57 if (args.length > 0) { 58 try { 59 fileSize = Long.parseLong(args[0]); 60 System.out.println("Testing with file of size " + fileSize); 61 } catch (NumberFormatException ex) { 62 largeFile = new File(args[0]); 63 if (!largeFile.exists()) { 64 throw new Exception("Specified file " + args[0] + " does not exist"); 65 } 66 userFile = true; 67 System.out.println("Testing with user-provided file " + largeFile); 68 } 69 } 70 File testDir = null; 71 if (largeFile == null) { 72 testDir = new File(System.getProperty("test.scratch", "."), 73 "LargeZip"); 74 if (testDir.exists()) { 75 if (!testDir.delete()) { 76 throw new Exception("Cannot delete already-existing test directory"); 77 } 78 } 79 check(!testDir.exists() && testDir.mkdirs()); 80 largeFile = new File(testDir, "largezip.zip"); 81 createLargeZip(); 82 } else { 83 if (args.length > 1) 84 updateLargeZip(args[1]); // add new entry with zfs 85 } 86 readLargeZip1(); 87 readLargeZip2(); 88 89 if (!userFile && !debug) { 90 check(largeFile.delete()); 91 check(testDir.delete()); 92 } 93 } 94 createLargeZip()95 static void createLargeZip() throws Throwable { 96 int iterations = DATA_LEN / DATA_SIZE; 97 ByteBuffer bb = ByteBuffer.allocate(DATA_SIZE); 98 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 99 for (int i = 0; i < iterations; i++) { 100 bb.putDouble(0, Math.random()); 101 baos.write(bb.array(), 0, DATA_SIZE); 102 } 103 data = baos.toByteArray(); 104 105 try (FileOutputStream fos = new FileOutputStream(largeFile); 106 BufferedOutputStream bos = new BufferedOutputStream(fos); 107 ZipOutputStream zos = new ZipOutputStream(bos)) 108 { 109 long length = 0; 110 while (length < fileSize) { 111 ZipEntry ze = new ZipEntry("entry-" + length); 112 lastEntryName = ze.getName(); 113 zos.putNextEntry(ze); 114 zos.write(data, 0, data.length); 115 zos.closeEntry(); 116 length = largeFile.length(); 117 } 118 System.out.println("Last entry written is " + lastEntryName); 119 } 120 } 121 122 private static byte buf[] = new byte[4096]; 123 checkEntry(ZipEntry e, InputStream is)124 static void checkEntry(ZipEntry e, InputStream is) throws Throwable { 125 long N = 0; 126 int n = 0; 127 while ((n = is.read(buf)) >= 0) { 128 N += n; 129 } 130 check(N == e.getSize()); 131 } 132 readLargeZip1()133 static void readLargeZip1() throws Throwable { 134 ZipFile zipFile = new ZipFile(largeFile); 135 ZipEntry entry = null; 136 String entryName = null; 137 int count = 0; 138 System.out.println("ZipFile:"); 139 Enumeration<? extends ZipEntry> entries = zipFile.entries(); 140 while (entries.hasMoreElements()) { 141 entry = entries.nextElement(); 142 entryName = entry.getName(); 143 System.out.println(" checking " + entryName); 144 if (!entry.isDirectory()) { 145 try (InputStream zeis = zipFile.getInputStream(entry)) { 146 checkEntry(entry, zeis); 147 } 148 } 149 count++; 150 } 151 System.out.println("Number of entries read: " + count); 152 check(!entry.isDirectory()); 153 if (userFile || check(entryName.equals(lastEntryName))) { 154 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 155 InputStream is = zipFile.getInputStream(entry); 156 int len; 157 while ((len = is.read(buf)) >= 0) { 158 baos.write(buf, 0, len); 159 } 160 baos.close(); 161 is.close(); 162 if (!userFile) 163 check(Arrays.equals(data, baos.toByteArray())); 164 } 165 } 166 readLargeZip2()167 static void readLargeZip2() throws Throwable { 168 System.out.println("ZipInputStream:"); 169 try (FileInputStream fis = new FileInputStream(largeFile); 170 BufferedInputStream bis = new BufferedInputStream(fis); 171 ZipInputStream zis = new ZipInputStream(bis)) 172 { 173 ZipEntry entry = null; 174 String entryName = null; 175 int count = 0; 176 while ((entry = zis.getNextEntry()) != null) { 177 entryName = entry.getName(); 178 179 System.out.println(" checking " + entryName + 180 ", method=" + entry.getMethod()); 181 if (entryName.equals(lastEntryName)) { 182 break; 183 } 184 if (!entry.isDirectory()) { 185 checkEntry(entry, zis); 186 } 187 count++; 188 } 189 System.out.println("Number of entries read: " + count); 190 System.out.println("Last entry read is " + entryName); 191 if (!userFile) { 192 check(!entry.isDirectory()); 193 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 194 byte buf[] = new byte[4096]; 195 int len; 196 while ((len = zis.read(buf)) >= 0) { 197 baos.write(buf, 0, len); 198 } 199 baos.close(); 200 check(Arrays.equals(data, baos.toByteArray())); 201 check(zis.getNextEntry() == null); 202 } 203 } 204 } 205 updateFile(FileSystem fs, Path src)206 private static void updateFile(FileSystem fs, Path src) throws IOException { 207 Path dst = fs.getPath(src.toString()); 208 Path parent = dst.getParent(); 209 if (parent != null && Files.notExists(parent)) 210 Files.createDirectories(parent); 211 Files.copy(src, dst, REPLACE_EXISTING); 212 } 213 getZipFSProvider()214 private static FileSystemProvider getZipFSProvider() { 215 for (FileSystemProvider provider : FileSystemProvider.installedProviders()) { 216 if ("jar".equalsIgnoreCase(provider.getScheme())) 217 return provider; 218 } 219 return null; 220 } 221 updateLargeZip(String pName)222 static void updateLargeZip(String pName) throws Throwable { 223 FileSystemProvider provider = getZipFSProvider(); 224 if (provider == null) { 225 System.err.println("ZIP filesystem provider is not installed"); 226 System.exit(1); 227 } 228 Map<String, Object> env = env = new HashMap<>(); 229 try (FileSystem fs = provider.newFileSystem(largeFile.toPath(), env)) { 230 Path path = FileSystems.getDefault().getPath(pName); 231 Files.walkFileTree( 232 path, 233 new SimpleFileVisitor<Path>() { 234 @Override 235 public FileVisitResult visitFile(Path file, 236 BasicFileAttributes attrs) 237 throws IOException 238 { 239 updateFile(fs, file); 240 return FileVisitResult.CONTINUE; 241 } 242 }); 243 } 244 } 245 246 247 //--------------------- Infrastructure --------------------------- 248 static volatile int passed = 0, failed = 0; pass()249 static void pass() {passed++;} pass(String msg)250 static void pass(String msg) {System.out.println(msg); passed++;} fail()251 static void fail() {failed++; Thread.dumpStack();} fail(String msg)252 static void fail(String msg) {System.out.println(msg); fail();} unexpected(Throwable t)253 static void unexpected(Throwable t) {failed++; t.printStackTrace();} unexpected(Throwable t, String msg)254 static void unexpected(Throwable t, String msg) { 255 System.out.println(msg); failed++; t.printStackTrace();} check(boolean cond)256 static boolean check(boolean cond) {if (cond) pass(); else fail(); return cond;} equal(Object x, Object y)257 static void equal(Object x, Object y) { 258 if (x == null ? y == null : x.equals(y)) pass(); 259 else fail(x + " not equal to " + y);} main(String[] args)260 public static void main(String[] args) throws Throwable { 261 try {realMain(args);} catch (Throwable t) {unexpected(t);} 262 System.out.println("\nPassed = " + passed + " failed = " + failed); 263 if (failed > 0) throw new AssertionError("Some tests failed");} 264 } 265