1 7 8 package java.io; 9 10 import java.security.AccessController; 11 import sun.security.action.GetPropertyAction; 12 13 14 class UnixFileSystem extends FileSystem { 15 16 private final char slash; 17 private final char colon; 18 private final String javaHome; 19 20 public UnixFileSystem() { 21 slash = 22 ((String) AccessController.doPrivileged( 23 new GetPropertyAction("file.separator"))).charAt(0); 24 colon = 25 ((String) AccessController.doPrivileged( 26 new GetPropertyAction("path.separator"))).charAt(0); 27 javaHome = 28 (String) AccessController.doPrivileged( 29 new GetPropertyAction("java.home")); 30 } 31 32 33 34 35 public char getSeparator() { 36 return slash; 37 } 38 39 public char getPathSeparator() { 40 return colon; 41 } 42 43 45 46 48 private String normalize(String pathname, int len, int off) { 49 if (len == 0) return pathname; 50 int n = len; 51 while ((n > 0) && (pathname.charAt(n - 1) == '/')) n--; 52 if (n == 0) return "/"; 53 StringBuffer sb = new StringBuffer(pathname.length()); 54 if (off > 0) sb.append(pathname.substring(0, off)); 55 char prevChar = 0; 56 for (int i = off; i < n; i++) { 57 char c = pathname.charAt(i); 58 if ((prevChar == '/') && (c == '/')) continue; 59 sb.append(c); 60 prevChar = c; 61 } 62 return sb.toString(); 63 } 64 65 68 public String normalize(String pathname) { 69 int n = pathname.length(); 70 char prevChar = 0; 71 for (int i = 0; i < n; i++) { 72 char c = pathname.charAt(i); 73 if ((prevChar == '/') && (c == '/')) 74 return normalize(pathname, n, i - 1); 75 prevChar = c; 76 } 77 if (prevChar == '/') return normalize(pathname, n, n - 1); 78 return pathname; 79 } 80 81 public int prefixLength(String pathname) { 82 if (pathname.length() == 0) return 0; 83 return (pathname.charAt(0) == '/') ? 1 : 0; 84 } 85 86 public String resolve(String parent, String child) { 87 if (child.equals("")) return parent; 88 if (child.charAt(0) == '/') { 89 if (parent.equals("/")) return child; 90 return parent + child; 91 } 92 if (parent.equals("/")) return parent + child; 93 return parent + '/' + child; 94 } 95 96 public String getDefaultParent() { 97 return "/"; 98 } 99 100 public String fromURIPath(String path) { 101 String p = path; 102 if (p.endsWith("/") && (p.length() > 1)) { 103 p = p.substring(0, p.length() - 1); 105 } 106 return p; 107 } 108 109 110 111 112 public boolean isAbsolute(File f) { 113 return (f.getPrefixLength() != 0); 114 } 115 116 public String resolve(File f) { 117 if (isAbsolute(f)) return f.getPath(); 118 return resolve(System.getProperty("user.dir"), f.getPath()); 119 } 120 121 private ExpiringCache cache = new ExpiringCache(); 128 private ExpiringCache javaHomePrefixCache = new ExpiringCache(); 132 133 public String canonicalize(String path) throws IOException { 134 if (!useCanonCaches) { 135 return canonicalize0(path); 136 } else { 137 String res = cache.get(path); 138 if (res == null) { 139 String dir = null; 140 String resDir = null; 141 if (useCanonPrefixCache) { 142 dir = parentOrNull(path); 146 if (dir != null) { 147 resDir = javaHomePrefixCache.get(dir); 148 if (resDir != null) { 149 String filename = path.substring(1 + dir.length()); 151 res = resDir + slash + filename; 152 cache.put(dir + slash + filename, res); 153 } 154 } 155 } 156 if (res == null) { 157 res = canonicalize0(path); 158 cache.put(path, res); 159 if (useCanonPrefixCache && 160 dir != null && dir.startsWith(javaHome)) { 161 resDir = parentOrNull(res); 162 if (resDir != null && resDir.equals(dir)) { 167 File f = new File(res); 168 if (f.exists() && !f.isDirectory()) { 169 javaHomePrefixCache.put(dir, resDir); 170 } 171 } 172 } 173 } 174 } 175 assert canonicalize0(path).equals(res) || path.startsWith(javaHome); 176 return res; 177 } 178 } 179 private native String canonicalize0(String path) throws IOException; 180 static String parentOrNull(String path) { 188 if (path == null) return null; 189 char sep = File.separatorChar; 190 int last = path.length() - 1; 191 int idx = last; 192 int adjacentDots = 0; 193 int nonDotCount = 0; 194 while (idx > 0) { 195 char c = path.charAt(idx); 196 if (c == '.') { 197 if (++adjacentDots >= 2) { 198 return null; 200 } 201 } else if (c == sep) { 202 if (adjacentDots == 1 && nonDotCount == 0) { 203 return null; 205 } 206 if (idx == 0 || 207 idx >= last - 1 || 208 path.charAt(idx - 1) == sep) { 209 return null; 212 } 213 return path.substring(0, idx); 214 } else { 215 ++nonDotCount; 216 adjacentDots = 0; 217 } 218 --idx; 219 } 220 return null; 221 } 222 223 224 225 public native int getBooleanAttributes0(File f); 226 227 public int getBooleanAttributes(File f) { 228 int rv = getBooleanAttributes0(f); 229 String name = f.getName(); 230 boolean hidden = (name.length() > 0) && (name.charAt(0) == '.'); 231 return rv | (hidden ? BA_HIDDEN : 0); 232 } 233 234 public native boolean checkAccess(File f, boolean write); 235 public native long getLastModifiedTime(File f); 236 public native long getLength(File f); 237 238 239 240 241 public native boolean createFileExclusively(String path) 242 throws IOException; 243 public boolean delete(File f) { 244 cache.clear(); 250 javaHomePrefixCache.clear(); 251 return delete0(f); 252 } 253 private native boolean delete0(File f); 254 public synchronized native boolean deleteOnExit(File f); 255 public native String[] list(File f); 256 public native boolean createDirectory(File f); 257 public boolean rename(File f1, File f2) { 258 cache.clear(); 264 javaHomePrefixCache.clear(); 265 return rename0(f1, f2); 266 } 267 private native boolean rename0(File f1, File f2); 268 public native boolean setLastModifiedTime(File f, long time); 269 public native boolean setReadOnly(File f); 270 271 272 273 274 public File[] listRoots() { 275 try { 276 SecurityManager security = System.getSecurityManager(); 277 if (security != null) { 278 security.checkRead("/"); 279 } 280 return new File[] { new File("/") }; 281 } catch (SecurityException x) { 282 return new File[0]; 283 } 284 } 285 286 287 288 289 public int compare(File f1, File f2) { 290 return f1.getPath().compareTo(f2.getPath()); 291 } 292 293 public int hashCode(File f) { 294 return f.getPath().hashCode() ^ 1234321; 295 } 296 297 298 private static native void initIDs(); 299 300 static { 301 initIDs(); 302 } 303 304 } 305 | Popular Tags |