MaxPathLength.java revision 12745:f068a4ffddd2
1/* 2 * Copyright (c) 2002, 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/* @test 25 @bug 4759207 4403166 4165006 4403166 6182812 6274272 7160013 26 @summary Test to see if win32 path length can be greater than 260 27 */ 28 29import java.io.*; 30import java.nio.file.Files; 31import java.nio.file.Path; 32import java.nio.file.DirectoryNotEmptyException; 33 34public class MaxPathLength { 35 private static String sep = File.separator; 36 private static String pathComponent = sep + 37 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; 38 private static String fileName = 39 "areallylongfilenamethatsforsur"; 40 private static boolean isWindows = false; 41 42 private static final int MAX_LENGTH = 256; 43 44 private static int counter = 0; 45 46 public static void main(String[] args) throws Exception { 47 String osName = System.getProperty("os.name"); 48 if (osName.startsWith("Windows")) { 49 isWindows = true; 50 } 51 52 for (int i = 4; i < 7; i++) { 53 String name = fileName; 54 while (name.length() < MAX_LENGTH) { 55 testLongPath (i, name, false); 56 testLongPath (i, name, true); 57 name = getNextName(name); 58 } 59 } 60 61 // test long paths on windows 62 // And these long pathes cannot be handled on Solaris and Mac platforms 63 if (isWindows) { 64 String name = fileName; 65 while (name.length() < MAX_LENGTH) { 66 testLongPath (20, name, false); 67 testLongPath (20, name, true); 68 name = getNextName(name); 69 } 70 } 71 } 72 73 private static String getNextName(String fName) { 74 return (fName.length() < MAX_LENGTH/2) ? fName + fName 75 : fName + "A"; 76 } 77 78 static void testLongPath(int max, String fn, 79 boolean tryAbsolute) throws Exception { 80 String[] created = new String[max]; 81 String pathString = "."; 82 for (int i = 0; i < max -1; i++) { 83 pathString = pathString + pathComponent + (counter++); 84 created[max - 1 -i] = pathString; 85 } 86 87 File dirFile = new File(pathString); 88 File f = new File(pathString + sep + fn); 89 90 String tPath = f.getPath(); 91 if (tryAbsolute) { 92 tPath = f.getCanonicalPath(); 93 } 94 created[0] = tPath; 95 96 //for getCanonicalPath testing on win32 97 File fu = new File(pathString + sep + fn.toUpperCase()); 98 99 if (dirFile.exists()) { 100 System.err.println("Warning: Test directory structure exists already!"); 101 return; 102 } 103 104 try { 105 Files.createDirectories(dirFile.toPath()); 106 107 if (tryAbsolute) 108 dirFile = new File(dirFile.getCanonicalPath()); 109 if (!dirFile.isDirectory()) 110 throw new RuntimeException ("File.isDirectory() failed"); 111 f = new File(tPath); 112 if (!f.createNewFile()) { 113 throw new RuntimeException ("File.createNewFile() failed"); 114 } 115 116 if (!f.exists()) 117 throw new RuntimeException ("File.exists() failed"); 118 if (!f.isFile()) 119 throw new RuntimeException ("File.isFile() failed"); 120 if (!f.canRead()) 121 throw new RuntimeException ("File.canRead() failed"); 122 if (!f.canWrite()) 123 throw new RuntimeException ("File.canWrite() failed"); 124 125 if (!f.delete()) 126 throw new RuntimeException ("File.delete() failed"); 127 128 FileOutputStream fos = new FileOutputStream(f); 129 fos.write(1); 130 fos.close(); 131 132 if (f.length() != 1) 133 throw new RuntimeException ("File.length() failed"); 134 long time = System.currentTimeMillis(); 135 if (!f.setLastModified(time)) 136 throw new RuntimeException ("File.setLastModified() failed"); 137 if (f.lastModified() == 0) { 138 throw new RuntimeException ("File.lastModified() failed"); 139 } 140 String[] list = dirFile.list(); 141 if (list == null || !fn.equals(list[0])) { 142 throw new RuntimeException ("File.list() failed"); 143 } 144 145 File[] flist = dirFile.listFiles(); 146 if (flist == null || !fn.equals(flist[0].getName())) 147 throw new RuntimeException ("File.listFiles() failed"); 148 149 if (isWindows && 150 !fu.getCanonicalPath().equals(f.getCanonicalPath())) 151 throw new RuntimeException ("getCanonicalPath() failed"); 152 153 char[] cc = tPath.toCharArray(); 154 cc[cc.length-1] = 'B'; 155 File nf = new File(new String(cc)); 156 if (!f.renameTo(nf)) { 157 /*there is a known issue that renameTo fails if 158 (1)the path is a UNC path and 159 (2)the path length is bigger than 1092 160 so don't stop if above are true 161 */ 162 String abPath = f.getAbsolutePath(); 163 if (!abPath.startsWith("\\\\") || 164 abPath.length() < 1093) { 165 throw new RuntimeException ("File.renameTo() failed for lenth=" 166 + abPath.length()); 167 } 168 } else { 169 if (!nf.canRead()) 170 throw new RuntimeException ("Renamed file is not readable"); 171 if (!nf.canWrite()) 172 throw new RuntimeException ("Renamed file is not writable"); 173 if (nf.length() != 1) 174 throw new RuntimeException ("Renamed file's size is not correct"); 175 if (!nf.renameTo(f)) { 176 created[0] = nf.getPath(); 177 } 178 /* add a script to test these two if we got a regression later 179 if (!f.setReadOnly()) 180 throw new RuntimeException ("File.setReadOnly() failed"); 181 f.deleteOnExit(); 182 */ 183 } 184 } finally { 185 // Clean up 186 for (int i = 0; i < max; i++) { 187 Path p = (new File(created[i])).toPath(); 188 try { 189 Files.deleteIfExists(p); 190 // Test if the file is really deleted and wait for 1 second at most 191 for (int j = 0; j < 10 && Files.exists(p); j++) { 192 Thread.sleep(100); 193 } 194 } catch (DirectoryNotEmptyException ex) { 195 // Give up the clean-up, let jtreg handle it. 196 System.err.println("Dir, " + p + ", is not empty"); 197 break; 198 } 199 } 200 } 201 } 202} 203