File.java revision ccbe3404e0691dab506d017550658e8e5974c83e
1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/* 2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more 3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * contributor license agreements. See the NOTICE file distributed with 4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * this work for additional information regarding copyright ownership. 5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0 6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * (the "License"); you may not use this file except in compliance with 7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the License. You may obtain a copy of the License at 8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * 11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * See the License for the specific language governing permissions and 15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * limitations under the License. 16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 18070f14c41b2494fd008afc4d96b873873692945fElliott Hughes// BEGIN android-note 19070f14c41b2494fd008afc4d96b873873692945fElliott Hughes// We've dropped Windows support, except where it's exposed: we still support 20070f14c41b2494fd008afc4d96b873873692945fElliott Hughes// non-Unix separators in serialized File objects, for example, but we don't 21070f14c41b2494fd008afc4d96b873873692945fElliott Hughes// have any code for UNC paths or case-insensitivity. 22070f14c41b2494fd008afc4d96b873873692945fElliott Hughes// We've also changed the JNI interface to better match what the Java actually wants. 23070f14c41b2494fd008afc4d96b873873692945fElliott Hughes// (The JNI implementation is also much simpler.) 24070f14c41b2494fd008afc4d96b873873692945fElliott Hughes// Some methods have been rewritten to reduce unnecessary allocation. 25070f14c41b2494fd008afc4d96b873873692945fElliott Hughes// Some duplication has been factored out. 26070f14c41b2494fd008afc4d96b873873692945fElliott Hughes// END android-note 27070f14c41b2494fd008afc4d96b873873692945fElliott Hughes 28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.io; 29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.net.URI; 31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.net.URISyntaxException; 32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.net.URL; 3393a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughesimport java.nio.ByteBuffer; 3493a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughesimport java.nio.charset.Charset; 352da83dc205e701b8dbe2cb84c54c2f8bb1073869Elliott Hughesimport java.nio.charset.Charsets; 36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.AccessController; 37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.ArrayList; 38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.List; 395d40b59c6bba79dc978f173ad64cdfbd8a937018Elliott Hughesimport java.util.Random; 40f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilsonimport org.apache.harmony.luni.util.DeleteOnExit; 41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.luni.util.PriviAction; 42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * An "abstract" representation of a file system entity identified by a 45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * pathname. The pathname may be absolute (relative to the root directory 46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * of the file system) or relative to the current directory in which the program 47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * is running. 48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 490af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * The actual file referenced by a {@code File} may or may not exist. It may 500af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * also, despite the name {@code File}, be a directory or other non-regular 510af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * file. 52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 530af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * This class provides limited functionality for getting/setting file 540af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * permissions, file type, and last modified time. 550af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * <p> 560af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * Although Java doesn't specify a character encoding for filenames, on Android 570af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * Java strings are converted to UTF-8 byte sequences when sending filenames to 580af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * the operating system, and byte sequences returned by the operating system 590af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * (from the various {@code list} methods) are converted to Java strings by 600af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * decoding them as UTF-8 byte sequences. 61f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.io.Serializable 63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.lang.Comparable 64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class File implements Serializable, Comparable<File> { 66f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final long serialVersionUID = 301077366599181567L; 68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 70f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * The system dependent file separator character. 71070f14c41b2494fd008afc4d96b873873692945fElliott Hughes * This field is initialized from the system property "file.separator". 72070f14c41b2494fd008afc4d96b873873692945fElliott Hughes * Later changes to that property will have no effect on this field or this class. 73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static final char separatorChar; 75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 77070f14c41b2494fd008afc4d96b873873692945fElliott Hughes * The system dependent file separator string. 78070f14c41b2494fd008afc4d96b873873692945fElliott Hughes * This field is a single-character string equal to String.valueOf(separatorChar). 79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static final String separator; 81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 83f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * The system dependent path separator character. 84070f14c41b2494fd008afc4d96b873873692945fElliott Hughes * This field is initialized from the system property "path.separator". 85070f14c41b2494fd008afc4d96b873873692945fElliott Hughes * Later changes to that property will have no effect on this field or this class. 86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static final char pathSeparatorChar; 88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 90070f14c41b2494fd008afc4d96b873873692945fElliott Hughes * The system dependent path separator string. 91070f14c41b2494fd008afc4d96b873873692945fElliott Hughes * This field is a single-character string equal to String.valueOf(pathSeparatorChar). 92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static final String pathSeparator; 94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 95070f14c41b2494fd008afc4d96b873873692945fElliott Hughes /** 96070f14c41b2494fd008afc4d96b873873692945fElliott Hughes * The path we return from getPath. This is almost the path we were 97070f14c41b2494fd008afc4d96b873873692945fElliott Hughes * given, but without duplicate adjacent slashes and without trailing 98070f14c41b2494fd008afc4d96b873873692945fElliott Hughes * slashes (except for the special case of the root directory). This 99070f14c41b2494fd008afc4d96b873873692945fElliott Hughes * path may be the empty string. 100070f14c41b2494fd008afc4d96b873873692945fElliott Hughes */ 101070f14c41b2494fd008afc4d96b873873692945fElliott Hughes private String path; 102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 103070f14c41b2494fd008afc4d96b873873692945fElliott Hughes /** 104070f14c41b2494fd008afc4d96b873873692945fElliott Hughes * The cached UTF-8 byte sequence corresponding to 'path'. 105070f14c41b2494fd008afc4d96b873873692945fElliott Hughes * This is suitable for direct use by our JNI, and includes a trailing NUL. 106070f14c41b2494fd008afc4d96b873873692945fElliott Hughes * For non-absolute paths, the "user.dir" property is prepended: that is, 107070f14c41b2494fd008afc4d96b873873692945fElliott Hughes * this byte sequence usually represents an absolute path (the exception 108070f14c41b2494fd008afc4d96b873873692945fElliott Hughes * being if the user overwrites the "user.dir" property with a non-absolute 109070f14c41b2494fd008afc4d96b873873692945fElliott Hughes * path). 110070f14c41b2494fd008afc4d96b873873692945fElliott Hughes */ 111070f14c41b2494fd008afc4d96b873873692945fElliott Hughes transient byte[] pathBytes; 112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project static { 114070f14c41b2494fd008afc4d96b873873692945fElliott Hughes // The default protection domain grants access to these properties. 115f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes separatorChar = System.getProperty("file.separator", "/").charAt(0); 116f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes pathSeparatorChar = System.getProperty("path.separator", ":").charAt(0); 117070f14c41b2494fd008afc4d96b873873692945fElliott Hughes separator = String.valueOf(separatorChar); 118070f14c41b2494fd008afc4d96b873873692945fElliott Hughes pathSeparator = String.valueOf(pathSeparatorChar); 119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Constructs a new file using the specified directory and name. 123f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param dir 125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the directory where the file is stored. 126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param name 127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the file's name. 128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NullPointerException 129f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * if {@code name} is {@code null}. 130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public File(File dir, String name) { 13293a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes this(dir == null ? null : dir.getPath(), name); 133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Constructs a new file using the specified path. 137f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param path 139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the path to be used for the file. 140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public File(String path) { 142070f14c41b2494fd008afc4d96b873873692945fElliott Hughes init(path); 143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Constructs a new File using the specified directory path and file name, 147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * placing a path separator between the two. 148f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param dirPath 150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the path to the directory where the file is stored. 151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param name 152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the file's name. 153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NullPointerException 154f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * if {@code name} is {@code null}. 155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public File(String dirPath, String name) { 157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (name == null) { 158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new NullPointerException(); 159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 160ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes if (dirPath == null || dirPath.isEmpty()) { 161070f14c41b2494fd008afc4d96b873873692945fElliott Hughes init(name); 162ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes } else if (name.isEmpty()) { 163070f14c41b2494fd008afc4d96b873873692945fElliott Hughes init(dirPath); 164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 165070f14c41b2494fd008afc4d96b873873692945fElliott Hughes init(join(dirPath, name)); 166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Constructs a new File using the path of the specified URI. {@code uri} 171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * needs to be an absolute and hierarchical Unified Resource Identifier with 172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * file scheme and non-empty path component, but with undefined authority, 173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * query or fragment components. 174f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param uri 176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the Unified Resource Identifier that is used to construct this 177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * file. 178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code uri} does not comply with the conditions above. 180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #toURI 181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.net.URI 182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public File(URI uri) { 184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // check pre-conditions 185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkURI(uri); 186070f14c41b2494fd008afc4d96b873873692945fElliott Hughes init(uri.getPath()); 18793a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes } 18893a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes 189070f14c41b2494fd008afc4d96b873873692945fElliott Hughes private void init(String dirtyPath) { 190070f14c41b2494fd008afc4d96b873873692945fElliott Hughes // Keep a copy of the cleaned-up string path. 191070f14c41b2494fd008afc4d96b873873692945fElliott Hughes this.path = fixSlashes(dirtyPath); 19293a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes // Cache the UTF-8 bytes we need for the JNI. 193028794d8a42840233d3cb316feb09b5593f19d1dElliott Hughes // TODO: we shouldn't do this caching at all; the RI demonstrably doesn't. 194028794d8a42840233d3cb316feb09b5593f19d1dElliott Hughes if (path.length() > 0 && path.charAt(0) == separatorChar) { // http://b/2486943 19593a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes this.pathBytes = newCString(path); 19693a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes return; 19793a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes } 19893a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes String userDir = AccessController.doPrivileged( 199f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes new PriviAction<String>("user.dir")); 200ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes this.pathBytes = newCString(path.isEmpty() ? userDir : join(userDir, path)); 20193a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes } 20293a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes 20393a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes private byte[] newCString(String s) { 2042da83dc205e701b8dbe2cb84c54c2f8bb1073869Elliott Hughes byte[] bytes = s.getBytes(Charsets.UTF_8); 20593a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes // This is an awful mistake, because '\' is a perfectly acceptable 20693a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes // character on Linux/Android. But we've shipped so many versions 20793a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes // that behaved like this, I'm too scared to change it. 20893a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes for (int i = 0; i < bytes.length; ++i) { 20993a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes if (bytes[i] == '\\') { 21093a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes bytes[i] = '/'; 21193a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes } 21293a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes } 2132da83dc205e701b8dbe2cb84c54c2f8bb1073869Elliott Hughes // Add a trailing NUL, because this byte[] is going to be used as a char*. 2142da83dc205e701b8dbe2cb84c54c2f8bb1073869Elliott Hughes int byteCount = bytes.length + 1; 2152da83dc205e701b8dbe2cb84c54c2f8bb1073869Elliott Hughes byte[] result = new byte[byteCount]; 2162da83dc205e701b8dbe2cb84c54c2f8bb1073869Elliott Hughes System.arraycopy(bytes, 0, result, 0, bytes.length); 2172da83dc205e701b8dbe2cb84c54c2f8bb1073869Elliott Hughes return result; 218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 220070f14c41b2494fd008afc4d96b873873692945fElliott Hughes // Removes duplicate adjacent slashes and any trailing slash. 221070f14c41b2494fd008afc4d96b873873692945fElliott Hughes private String fixSlashes(String origPath) { 222070f14c41b2494fd008afc4d96b873873692945fElliott Hughes // Remove duplicate adjacent slashes. 223070f14c41b2494fd008afc4d96b873873692945fElliott Hughes boolean lastWasSlash = false; 224070f14c41b2494fd008afc4d96b873873692945fElliott Hughes char[] newPath = origPath.toCharArray(); 225070f14c41b2494fd008afc4d96b873873692945fElliott Hughes int length = newPath.length; 226070f14c41b2494fd008afc4d96b873873692945fElliott Hughes int newLength = 0; 227070f14c41b2494fd008afc4d96b873873692945fElliott Hughes for (int i = 0; i < length; ++i) { 228070f14c41b2494fd008afc4d96b873873692945fElliott Hughes char ch = newPath[i]; 229070f14c41b2494fd008afc4d96b873873692945fElliott Hughes if (ch == '/') { 230070f14c41b2494fd008afc4d96b873873692945fElliott Hughes if (!lastWasSlash) { 231070f14c41b2494fd008afc4d96b873873692945fElliott Hughes newPath[newLength++] = separatorChar; 232070f14c41b2494fd008afc4d96b873873692945fElliott Hughes lastWasSlash = true; 233070f14c41b2494fd008afc4d96b873873692945fElliott Hughes } 234070f14c41b2494fd008afc4d96b873873692945fElliott Hughes } else { 235070f14c41b2494fd008afc4d96b873873692945fElliott Hughes newPath[newLength++] = ch; 236070f14c41b2494fd008afc4d96b873873692945fElliott Hughes lastWasSlash = false; 237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 239070f14c41b2494fd008afc4d96b873873692945fElliott Hughes // Remove any trailing slash (unless this is the root of the file system). 240070f14c41b2494fd008afc4d96b873873692945fElliott Hughes if (lastWasSlash && newLength > 1) { 241070f14c41b2494fd008afc4d96b873873692945fElliott Hughes newLength--; 242070f14c41b2494fd008afc4d96b873873692945fElliott Hughes } 243070f14c41b2494fd008afc4d96b873873692945fElliott Hughes // Reuse the original string if possible. 244070f14c41b2494fd008afc4d96b873873692945fElliott Hughes return (newLength != length) ? new String(newPath, 0, newLength) : origPath; 245070f14c41b2494fd008afc4d96b873873692945fElliott Hughes } 246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 247070f14c41b2494fd008afc4d96b873873692945fElliott Hughes // Joins two path components, adding a separator only if necessary. 248070f14c41b2494fd008afc4d96b873873692945fElliott Hughes private String join(String prefix, String suffix) { 249070f14c41b2494fd008afc4d96b873873692945fElliott Hughes int prefixLength = prefix.length(); 250070f14c41b2494fd008afc4d96b873873692945fElliott Hughes boolean haveSlash = (prefixLength > 0 && prefix.charAt(prefixLength - 1) == separatorChar); 251070f14c41b2494fd008afc4d96b873873692945fElliott Hughes if (!haveSlash) { 252070f14c41b2494fd008afc4d96b873873692945fElliott Hughes haveSlash = (suffix.length() > 0 && suffix.charAt(0) == separatorChar); 253070f14c41b2494fd008afc4d96b873873692945fElliott Hughes } 254070f14c41b2494fd008afc4d96b873873692945fElliott Hughes return haveSlash ? (prefix + suffix) : (prefix + separatorChar + suffix); 255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void checkURI(URI uri) { 258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!uri.isAbsolute()) { 259b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new IllegalArgumentException("URI is not absolute: " + uri); 260f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } else if (!uri.getRawSchemeSpecificPart().startsWith("/")) { 261b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new IllegalArgumentException("URI is not hierarchical: " + uri); 262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 263e32b21f14d52bac429a9c54fe031f9e92c911d64Jesse Wilson if (!"file".equals(uri.getScheme())) { 264b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new IllegalArgumentException("Expected file scheme in URI: " + uri); 265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 266e32b21f14d52bac429a9c54fe031f9e92c911d64Jesse Wilson String rawPath = uri.getRawPath(); 267e32b21f14d52bac429a9c54fe031f9e92c911d64Jesse Wilson if (rawPath == null || rawPath.isEmpty()) { 268b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new IllegalArgumentException("Expected non-empty path in URI: " + uri); 269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (uri.getRawAuthority() != null) { 271b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new IllegalArgumentException("Found authority in URI: " + uri); 272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (uri.getRawQuery() != null) { 274b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new IllegalArgumentException("Found query in URI: " + uri); 275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (uri.getRawFragment() != null) { 277b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new IllegalArgumentException("Found fragment in URI: " + uri); 278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Lists the file system roots. The Java platform may support zero or more 283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * file systems, each with its own platform-dependent root. Further, the 284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * canonical pathname of any file on the system will always begin with one 285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * of the returned file system roots. 286f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the array of file system roots. 288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static File[] listRoots() { 29087415b1521402398d4470aecbef7c126a6948290Elliott Hughes return new File[] { new File("/") }; 291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 29408ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * Tests whether or not this process is allowed to execute this file. 29508ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * Note that this is a best-effort result; the only way to be certain is 29608ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * to actually attempt the operation. 29708ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * 29808ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * @return {@code true} if this file can be executed, {@code false} otherwise. 29908ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * @throws SecurityException 30008ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * If a security manager exists and 30108ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * SecurityManager.checkExec(java.lang.String) disallows read 30208ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * permission to this file object 30308ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * @see java.lang.SecurityManager#checkExec(String) 30408ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * 30508ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * @since 1.6 30608ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes */ 30708ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes public boolean canExecute() { 308ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes if (path.isEmpty()) { 30908ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes return false; 31008ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes } 31108ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes SecurityManager security = System.getSecurityManager(); 31208ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes if (security != null) { 31308ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes security.checkExec(path); // Seems bogus, but this is what the RI does. 31408ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes } 31508ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes return canExecuteImpl(pathBytes); 31608ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes } 31708ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes private native boolean canExecuteImpl(byte[] filePath); 31808ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes 31908ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes /** 320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Indicates whether the current context is allowed to read from this file. 321f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if this file can be read, {@code false} otherwise. 323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws SecurityException 324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if a {@code SecurityManager} is installed and it denies the 325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * read request. 326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean canRead() { 328ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes if (path.isEmpty()) { 329f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson return false; 330f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SecurityManager security = System.getSecurityManager(); 332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (security != null) { 333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project security.checkRead(path); 334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 33508ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes return canReadImpl(pathBytes); 336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 33708ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes private native boolean canReadImpl(byte[] filePath); 3380af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes 339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Indicates whether the current context is allowed to write to this file. 341f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if this file can be written, {@code false} 343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * otherwise. 344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws SecurityException 345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if a {@code SecurityManager} is installed and it denies the 346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * write request. 347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean canWrite() { 349ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes if (path.isEmpty()) { 350c5c9c667028146ab5f5e446c44f911c2fdd7dd30Elliott Hughes return false; 351c5c9c667028146ab5f5e446c44f911c2fdd7dd30Elliott Hughes } 352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SecurityManager security = System.getSecurityManager(); 353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (security != null) { 354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project security.checkWrite(path); 355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 35608ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes return canWriteImpl(pathBytes); 357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 35808ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes private native boolean canWriteImpl(byte[] filePath); 3590af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes 360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the relative sort ordering of the paths for this file and the 362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * file {@code another}. The ordering is platform dependent. 363f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param another 365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * a file to compare this file to 366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return an int determined by comparing the two paths. Possible values are 367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * described in the Comparable interface. 368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see Comparable 369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int compareTo(File another) { 371070f14c41b2494fd008afc4d96b873873692945fElliott Hughes return this.getPath().compareTo(another.getPath()); 372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Deletes this file. Directories must be empty before they will be deleted. 376f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 377ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * <p>Note that this method does <i>not</i> throw {@code IOException} on failure. 378ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * Callers must check the return value. 379ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * 380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if this file was deleted, {@code false} otherwise. 381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws SecurityException 382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if a {@code SecurityManager} is installed and it denies the 383adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * request. 384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.lang.SecurityManager#checkDelete 385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean delete() { 387ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes if (path.isEmpty()) { 388c5c9c667028146ab5f5e446c44f911c2fdd7dd30Elliott Hughes return false; 389c5c9c667028146ab5f5e446c44f911c2fdd7dd30Elliott Hughes } 390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SecurityManager security = System.getSecurityManager(); 391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (security != null) { 392adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project security.checkDelete(path); 393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 39493a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes return deleteImpl(pathBytes); 395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 397c5c9c667028146ab5f5e446c44f911c2fdd7dd30Elliott Hughes private native boolean deleteImpl(byte[] filePath); 398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Schedules this file to be automatically deleted once the virtual machine 401f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * terminates. This will only happen when the virtual machine terminates 402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * normally as described by the Java Language Specification section 12.9. 403f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws SecurityException 405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if a {@code SecurityManager} is installed and it denies the 406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * request. 407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void deleteOnExit() { 409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SecurityManager security = System.getSecurityManager(); 410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (security != null) { 411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project security.checkDelete(path); 412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project DeleteOnExit.getInstance().addFile(getAbsoluteName()); 414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Compares {@code obj} to this file and returns {@code true} if they 418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * represent the <em>same</em> object using a path specific comparison. 419f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param obj 421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the object to compare this file with. 422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if {@code obj} is the same as this object, 423adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code false} otherwise. 424adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean equals(Object obj) { 427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!(obj instanceof File)) { 428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return path.equals(((File) obj).getPath()); 431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns a boolean indicating whether this file can be found on the 435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * underlying file system. 436f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if this file exists, {@code false} otherwise. 438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws SecurityException 439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if a {@code SecurityManager} is installed and it denies read 440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * access to this file. 441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #getPath 442f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @see java.lang.SecurityManager#checkRead(FileDescriptor) 443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 444adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean exists() { 445ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes if (path.isEmpty()) { 446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 448adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SecurityManager security = System.getSecurityManager(); 449adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (security != null) { 450adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project security.checkRead(path); 451adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 45293a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes return existsImpl(pathBytes); 453adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 454adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 455adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private native boolean existsImpl(byte[] filePath); 456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 458adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the absolute path of this file. 459f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the absolute file path. 461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 462adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String getAbsolutePath() { 4632da83dc205e701b8dbe2cb84c54c2f8bb1073869Elliott Hughes return new String(pathBytes, 0, pathBytes.length - 1, Charsets.UTF_8); 464adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 465adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 467adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns a new file constructed using the absolute path of this file. 468f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 469adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return a new file from this file's absolute path. 470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.lang.SecurityManager#checkPropertyAccess 471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 472adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public File getAbsoluteFile() { 473adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new File(this.getAbsolutePath()); 474adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 475adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 476adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 477adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the absolute path of this file with all references resolved. An 478adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <em>absolute</em> path is one that begins at the root of the file 479adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * system. The canonical path is one in which all references have been 480adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * resolved. For the cases of '..' and '.', where the file system supports 481adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * parent and working directory respectively, these are removed and replaced 482adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * with a direct directory reference. If the file does not exist, 483adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * getCanonicalPath() may not resolve any references and simply returns an 484adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * absolute path name or throws an IOException. 485f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 486adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the canonical path of this file. 487adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 488adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an I/O error occurs. 489adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 490adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String getCanonicalPath() throws IOException { 4914030ad60f305d1f23e9b681dca7a181ab4f09276Jesse Wilson // BEGIN android-removed 4921072631d16a5e5ffd97ae346e20dcd112df9dc13Jesse Wilson // Caching the canonical path is bogus. Users facing specific 4931072631d16a5e5ffd97ae346e20dcd112df9dc13Jesse Wilson // performance problems can perform their own caching, with 4941072631d16a5e5ffd97ae346e20dcd112df9dc13Jesse Wilson // eviction strategies that are appropriate for their application. 4951072631d16a5e5ffd97ae346e20dcd112df9dc13Jesse Wilson // A VM-wide cache with no mechanism to evict stale elements is a 4961072631d16a5e5ffd97ae346e20dcd112df9dc13Jesse Wilson // disservice to applications that need up-to-date data. 4974030ad60f305d1f23e9b681dca7a181ab4f09276Jesse Wilson // String canonPath = FileCanonPathCache.get(absPath); 4984030ad60f305d1f23e9b681dca7a181ab4f09276Jesse Wilson // if (canonPath != null) { 4994030ad60f305d1f23e9b681dca7a181ab4f09276Jesse Wilson // return canonPath; 5004030ad60f305d1f23e9b681dca7a181ab4f09276Jesse Wilson // } 5014030ad60f305d1f23e9b681dca7a181ab4f09276Jesse Wilson // END android-removed 5024030ad60f305d1f23e9b681dca7a181ab4f09276Jesse Wilson 50393a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes byte[] result = pathBytes; 504f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if(separatorChar == '/') { 505f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // resolve the full path first 506f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson result = resolveLink(result, result.length, false); 507f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // resolve the parent directories 508f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson result = resolve(result); 509adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 510adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int numSeparators = 1; 511adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < result.length; i++) { 512adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (result[i] == separatorChar) { 513adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project numSeparators++; 514adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 515adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 516adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int sepLocations[] = new int[numSeparators]; 517adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int rootLoc = 0; 518adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (separatorChar != '/') { 519adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (result[0] == '\\') { 520adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project rootLoc = (result.length > 1 && result[1] == '\\') ? 1 : 0; 521adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 522adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project rootLoc = 2; // skip drive i.e. c: 523adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 524adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 525adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project byte newResult[] = new byte[result.length + 1]; 526adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int newLength = 0, lastSlash = 0, foundDots = 0; 527adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project sepLocations[lastSlash] = rootLoc; 528adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i <= result.length; i++) { 529adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (i < rootLoc) { 530adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project newResult[newLength++] = result[i]; 531adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 532adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (i == result.length || result[i] == separatorChar) { 533adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (i == result.length && foundDots == 0) { 534adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 535adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 536adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (foundDots == 1) { 537adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* Don't write anything, just reset and continue */ 538adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project foundDots = 0; 539adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project continue; 540adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 541adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (foundDots > 1) { 542adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* Go back N levels */ 543adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lastSlash = lastSlash > (foundDots - 1) ? lastSlash 544adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project - (foundDots - 1) : 0; 545adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project newLength = sepLocations[lastSlash] + 1; 546adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project foundDots = 0; 547adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project continue; 548adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 549adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project sepLocations[++lastSlash] = newLength; 550adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project newResult[newLength++] = (byte) separatorChar; 551adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project continue; 552adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 553adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (result[i] == '.') { 554adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project foundDots++; 555adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project continue; 556adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 557adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* Found some dots within text, write them out */ 558adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (foundDots > 0) { 559adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int j = 0; j < foundDots; j++) { 560adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project newResult[newLength++] = (byte) '.'; 561adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 562adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 563adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project newResult[newLength++] = result[i]; 564adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project foundDots = 0; 565adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 566adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 567adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // remove trailing slash 568adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (newLength > (rootLoc + 1) 569adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project && newResult[newLength - 1] == separatorChar) { 570adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project newLength--; 571adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 572adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project newResult[newLength] = 0; 573adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project newResult = getCanonImpl(newResult); 574adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project newLength = newResult.length; 5752da83dc205e701b8dbe2cb84c54c2f8bb1073869Elliott Hughes return new String(newResult, 0, newLength, Charsets.UTF_8); 576f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 577f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 578f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson /* 579f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * Resolve symbolic links in the parent directories. 580f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson */ 581f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson private byte[] resolve(byte[] newResult) throws IOException { 582f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson int last = 1, nextSize, linkSize; 583f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson byte[] linkPath = newResult, bytes; 584f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson boolean done, inPlace; 585f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson for (int i = 1; i <= newResult.length; i++) { 586f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if (i == newResult.length || newResult[i] == separatorChar) { 587f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson done = i >= newResult.length - 1; 588f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // if there is only one segment, do nothing 589f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if (done && linkPath.length == 1) { 590f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson return newResult; 591f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 592f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson inPlace = false; 593f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if (linkPath == newResult) { 594f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson bytes = newResult; 595f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // if there are no symbolic links, terminate the C string 596f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // instead of copying 597f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if (!done) { 598f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson inPlace = true; 599f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson newResult[i] = '\0'; 600f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 601f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } else { 602f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson nextSize = i - last + 1; 603f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson linkSize = linkPath.length; 604f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if (linkPath[linkSize - 1] == separatorChar) { 605f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson linkSize--; 606f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 607f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson bytes = new byte[linkSize + nextSize]; 608f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson System.arraycopy(linkPath, 0, bytes, 0, linkSize); 609f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson System.arraycopy(newResult, last - 1, bytes, linkSize, 610f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson nextSize); 611f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // the full path has already been resolved 612f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 613f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if (done) { 614f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson return bytes; 615f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 616f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson linkPath = resolveLink(bytes, inPlace ? i : bytes.length, true); 617f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if (inPlace) { 618f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson newResult[i] = '/'; 619f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 620f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson last = i + 1; 621f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 622f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 623f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson throw new InternalError(); 624f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 625f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 626f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson /* 627f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * Resolve a symbolic link. While the path resolves to an existing path, 628f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * keep resolving. If an absolute link is found, resolve the parent 629f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * directories if resolveAbsolute is true. 630f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson */ 631f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson private byte[] resolveLink(byte[] pathBytes, int length, 632f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson boolean resolveAbsolute) throws IOException { 633f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson boolean restart = false; 634f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson byte[] linkBytes, temp; 635f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson do { 636f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson linkBytes = getLinkImpl(pathBytes); 637f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if (linkBytes == pathBytes) { 638f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson break; 639f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 640f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if (linkBytes[0] == separatorChar) { 641f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // link to an absolute path, if resolving absolute paths, 642f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // resolve the parent dirs again 643f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson restart = resolveAbsolute; 644f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson pathBytes = linkBytes; 645f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } else { 646f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson int last = length - 1; 647f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson while (pathBytes[last] != separatorChar) { 648f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson last--; 649f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 650f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson last++; 651f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson temp = new byte[last + linkBytes.length]; 652f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson System.arraycopy(pathBytes, 0, temp, 0, last); 653f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson System.arraycopy(linkBytes, 0, temp, last, linkBytes.length); 654f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson pathBytes = temp; 655f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 656f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson length = pathBytes.length; 657f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } while (existsImpl(pathBytes)); 658f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // resolve the parent directories 659f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if (restart) { 660f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson return resolve(pathBytes); 661f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 662f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson return pathBytes; 663adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 664adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 6650af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes private native byte[] getLinkImpl(byte[] filePath); 6660af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes 667adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 668adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns a new file created using the canonical path of this file. 669adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Equivalent to {@code new File(this.getCanonicalPath())}. 670f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 671adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the new file constructed from this file's canonical path. 672adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 673adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an I/O error occurs. 674adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.lang.SecurityManager#checkPropertyAccess 675adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 676adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public File getCanonicalFile() throws IOException { 677adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new File(getCanonicalPath()); 678adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 679adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 680adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private native byte[] getCanonImpl(byte[] filePath); 681adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 682adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 683adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the name of the file or directory represented by this file. 684f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 685adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return this file's name or an empty string if there is no name part in 686adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the file's path. 687adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 688adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String getName() { 689adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int separatorIndex = path.lastIndexOf(separator); 690adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return (separatorIndex < 0) ? path : path.substring(separatorIndex + 1, 691adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project path.length()); 692adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 693adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 694adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 695adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the pathname of the parent of this file. This is the path up to 696adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * but not including the last name. {@code null} is returned if there is no 697adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * parent. 698f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 699adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return this file's parent pathname or {@code null}. 700adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 701adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String getParent() { 702adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int length = path.length(), firstInPath = 0; 703adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (separatorChar == '\\' && length > 2 && path.charAt(1) == ':') { 704adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project firstInPath = 2; 705adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 706adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int index = path.lastIndexOf(separatorChar); 707adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (index == -1 && firstInPath > 0) { 708adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project index = 2; 709adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 710adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (index == -1 || path.charAt(length - 1) == separatorChar) { 711adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 712adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 713adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (path.indexOf(separatorChar) == index 714adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project && path.charAt(firstInPath) == separatorChar) { 715adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return path.substring(0, index + 1); 716adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 717adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return path.substring(0, index); 718adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 719adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 720adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 721adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns a new file made from the pathname of the parent of this file. 722adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This is the path up to but not including the last name. {@code null} is 723adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * returned when there is no parent. 724f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 725adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return a new file representing this file's parent or {@code null}. 726adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 727adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public File getParentFile() { 728adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String tempParent = getParent(); 729adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (tempParent == null) { 730adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 731adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 732adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new File(tempParent); 733adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 734adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 735adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 736adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the path of this file. 737f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 738adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return this file's path. 739adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 740adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String getPath() { 741adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return path; 742adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 743adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 744adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 745adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns an integer hash code for the receiver. Any two objects for which 746adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code equals} returns {@code true} must return the same hash code. 747f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 748adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return this files's hash value. 749adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #equals 750adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 751adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 752adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int hashCode() { 753070f14c41b2494fd008afc4d96b873873692945fElliott Hughes return getPath().hashCode() ^ 1234321; 754adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 755adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 756adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 757adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Indicates if this file's pathname is absolute. Whether a pathname is 7580af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * absolute is platform specific. On Android, absolute paths start with 7590af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * the character '/'. 76008ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * 761adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if this file's pathname is absolute, {@code false} 762adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * otherwise. 763adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #getPath 764adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 765adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean isAbsolute() { 766adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return path.length() > 0 && path.charAt(0) == separatorChar; 767adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 768adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 769adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 770adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Indicates if this file represents a <em>directory</em> on the 771adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * underlying file system. 772f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 773adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if this file is a directory, {@code false} 774adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * otherwise. 775adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws SecurityException 776adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if a {@code SecurityManager} is installed and it denies read 777adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * access to this file. 778adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 779adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean isDirectory() { 780ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes if (path.isEmpty()) { 781adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 782adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 783adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SecurityManager security = System.getSecurityManager(); 784adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (security != null) { 785adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project security.checkRead(path); 786adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 78793a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes return isDirectoryImpl(pathBytes); 788adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 789adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 790adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private native boolean isDirectoryImpl(byte[] filePath); 791adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 792adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 793adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Indicates if this file represents a <em>file</em> on the underlying 794adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * file system. 795f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 796adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if this file is a file, {@code false} otherwise. 797adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws SecurityException 798adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if a {@code SecurityManager} is installed and it denies read 799adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * access to this file. 800adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 801adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean isFile() { 802ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes if (path.isEmpty()) { 803adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 804adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 805adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SecurityManager security = System.getSecurityManager(); 806adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (security != null) { 807adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project security.checkRead(path); 808adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 80993a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes return isFileImpl(pathBytes); 810adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 811adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 812adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private native boolean isFileImpl(byte[] filePath); 813adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 814adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 815adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns whether or not this file is a hidden file as defined by the 816f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * operating system. The notion of "hidden" is system-dependent. For Unix 817f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * systems a file is considered hidden if its name starts with a ".". For 818f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * Windows systems there is an explicit flag in the file system for this 819f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * purpose. 820f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 821adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if the file is hidden, {@code false} otherwise. 822adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws SecurityException 823adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if a {@code SecurityManager} is installed and it denies read 824adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * access to this file. 825adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 826adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean isHidden() { 827ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes if (path.isEmpty()) { 828adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 829adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 830adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SecurityManager security = System.getSecurityManager(); 831adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (security != null) { 832adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project security.checkRead(path); 833adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 83487415b1521402398d4470aecbef7c126a6948290Elliott Hughes return getName().startsWith("."); 835adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 836adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 837adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 838adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the time when this file was last modified, measured in 839adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * milliseconds since January 1st, 1970, midnight. 8401326cfc6f105f6c8fd5ffd83793223e1a797409dElliott Hughes * Returns 0 if the file does not exist. 841f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 842adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the time when this file was last modified. 843adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws SecurityException 844adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if a {@code SecurityManager} is installed and it denies read 845adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * access to this file. 846adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 847adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public long lastModified() { 848ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes if (path.isEmpty()) { 849c5c9c667028146ab5f5e446c44f911c2fdd7dd30Elliott Hughes return 0; 850c5c9c667028146ab5f5e446c44f911c2fdd7dd30Elliott Hughes } 851adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SecurityManager security = System.getSecurityManager(); 852adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (security != null) { 853adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project security.checkRead(path); 854adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 85593a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes return lastModifiedImpl(pathBytes); 856adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 857adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 858adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private native long lastModifiedImpl(byte[] filePath); 859adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 860adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 861adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Sets the time this file was last modified, measured in milliseconds since 862adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * January 1st, 1970, midnight. 863f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 864ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * <p>Note that this method does <i>not</i> throw {@code IOException} on failure. 865ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * Callers must check the return value. 866ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * 867adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param time 868adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the last modification time for this file. 869adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if the operation is successful, {@code false} 870adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * otherwise. 871adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 872adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code time < 0}. 873adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws SecurityException 874adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if a {@code SecurityManager} is installed and it denies write 875adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * access to this file. 876adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 877adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean setLastModified(long time) { 878ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes if (path.isEmpty()) { 879c5c9c667028146ab5f5e446c44f911c2fdd7dd30Elliott Hughes return false; 880c5c9c667028146ab5f5e446c44f911c2fdd7dd30Elliott Hughes } 881adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (time < 0) { 882b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new IllegalArgumentException("time < 0"); 883adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 884adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SecurityManager security = System.getSecurityManager(); 885adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (security != null) { 886adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project security.checkWrite(path); 887adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 88893a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes return setLastModifiedImpl(pathBytes, time); 889adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 890adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 891adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private native boolean setLastModifiedImpl(byte[] path, long time); 892adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 893adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 89408ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * Equivalent to setWritable(false, false). 895f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 89608ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * @see #setWritable(boolean, boolean) 897adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 898adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean setReadOnly() { 89908ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes return setWritable(false, false); 90008ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes } 90108ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes 90208ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes /** 90308ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * Manipulates the execute permissions for the abstract path designated by 90408ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * this file. 90508ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * 906ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * <p>Note that this method does <i>not</i> throw {@code IOException} on failure. 907ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * Callers must check the return value. 908ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * 90908ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * @param executable 91008ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * To allow execute permission if true, otherwise disallow 91108ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * @param ownerOnly 91208ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * To manipulate execute permission only for owner if true, 91308ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * otherwise for everyone. The manipulation will apply to 91408ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * everyone regardless of this value if the underlying system 91508ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * does not distinguish owner and other users. 91608ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * @return true if and only if the operation succeeded. If the user does not 91708ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * have permission to change the access permissions of this abstract 91808ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * pathname the operation will fail. If the underlying file system 91908ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * does not support execute permission and the value of executable 92008ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * is false, this operation will fail. 92108ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * @throws SecurityException - 92208ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * If a security manager exists and 92308ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * SecurityManager.checkWrite(java.lang.String) disallows write 92408ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * permission to this file object 92508ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * @since 1.6 92608ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes */ 92708ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes public boolean setExecutable(boolean executable, boolean ownerOnly) { 928ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes if (path.isEmpty()) { 929c5c9c667028146ab5f5e446c44f911c2fdd7dd30Elliott Hughes return false; 930c5c9c667028146ab5f5e446c44f911c2fdd7dd30Elliott Hughes } 931adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SecurityManager security = System.getSecurityManager(); 932adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (security != null) { 933adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project security.checkWrite(path); 934adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 93508ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes return setExecutableImpl(pathBytes, executable, ownerOnly); 93608ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes } 93708ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes 93808ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes /** 93908ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * Equivalent to setExecutable(executable, true). 940ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * @see #setExecutable(boolean, boolean) 94108ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * @since 1.6 94208ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes */ 94308ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes public boolean setExecutable(boolean executable) { 94408ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes return setExecutable(executable, true); 945adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 946adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 94708ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes private native boolean setExecutableImpl(byte[] path, boolean executable, boolean ownerOnly); 94808ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes 94908ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes /** 95008ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * Manipulates the read permissions for the abstract path designated by this 95108ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * file. 95208ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * 95308ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * @param readable 95408ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * To allow read permission if true, otherwise disallow 95508ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * @param ownerOnly 95608ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * To manipulate read permission only for owner if true, 95708ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * otherwise for everyone. The manipulation will apply to 95808ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * everyone regardless of this value if the underlying system 95908ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * does not distinguish owner and other users. 96008ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * @return true if and only if the operation succeeded. If the user does not 96108ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * have permission to change the access permissions of this abstract 96208ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * pathname the operation will fail. If the underlying file system 96308ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * does not support read permission and the value of readable is 96408ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * false, this operation will fail. 96508ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * @throws SecurityException - 96608ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * If a security manager exists and 96708ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * SecurityManager.checkWrite(java.lang.String) disallows write 96808ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * permission to this file object 96908ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * @since 1.6 97008ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes */ 97108ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes public boolean setReadable(boolean readable, boolean ownerOnly) { 972ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes if (path.isEmpty()) { 97308ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes return false; 97408ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes } 97508ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes SecurityManager security = System.getSecurityManager(); 97608ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes if (security != null) { 97708ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes security.checkWrite(path); 97808ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes } 97908ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes return setReadableImpl(pathBytes, readable, ownerOnly); 98008ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes } 98108ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes 98208ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes /** 98308ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * Equivalent to setReadable(readable, true). 984ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * @see #setReadable(boolean, boolean) 98508ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * @since 1.6 98608ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes */ 98708ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes public boolean setReadable(boolean readable) { 98808ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes return setReadable(readable, true); 98908ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes } 99008ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes 99108ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes private native boolean setReadableImpl(byte[] path, boolean readable, boolean ownerOnly); 99208ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes 99308ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes /** 99408ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * Manipulates the write permissions for the abstract path designated by this 99508ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * file. 99608ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * 99708ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * @param writable 99808ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * To allow write permission if true, otherwise disallow 99908ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * @param ownerOnly 100008ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * To manipulate write permission only for owner if true, 100108ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * otherwise for everyone. The manipulation will apply to 100208ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * everyone regardless of this value if the underlying system 100308ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * does not distinguish owner and other users. 100408ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * @return true if and only if the operation succeeded. If the user does not 100508ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * have permission to change the access permissions of this abstract 100608ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * pathname the operation will fail. 100708ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * @throws SecurityException - 100808ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * If a security manager exists and 100908ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * SecurityManager.checkWrite(java.lang.String) disallows write 101008ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * permission to this file object 101108ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * @since 1.6 101208ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes */ 101308ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes public boolean setWritable(boolean writable, boolean ownerOnly) { 1014ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes if (path.isEmpty()) { 101508ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes return false; 101608ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes } 101708ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes SecurityManager security = System.getSecurityManager(); 101808ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes if (security != null) { 101908ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes security.checkWrite(path); 102008ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes } 102108ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes return setWritableImpl(pathBytes, writable, ownerOnly); 102208ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes } 102308ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes 102408ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes /** 102508ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * Equivalent to setWritable(writable, true). 1026ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * @see #setWritable(boolean, boolean) 102708ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * @since 1.6 102808ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes */ 102908ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes public boolean setWritable(boolean writable) { 103008ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes return setWritable(writable, true); 103108ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes } 103208ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes 103308ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes private native boolean setWritableImpl(byte[] path, boolean writable, boolean ownerOnly); 1034adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1035adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1036adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the length of this file in bytes. 10371326cfc6f105f6c8fd5ffd83793223e1a797409dElliott Hughes * Returns 0 if the file does not exist. 10381326cfc6f105f6c8fd5ffd83793223e1a797409dElliott Hughes * The result for a directory is not defined. 1039f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1040adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the number of bytes in this file. 1041adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws SecurityException 1042adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if a {@code SecurityManager} is installed and it denies read 1043adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * access to this file. 1044adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1045adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public long length() { 1046adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SecurityManager security = System.getSecurityManager(); 1047adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (security != null) { 1048adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project security.checkRead(path); 1049adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 105093a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes return lengthImpl(pathBytes); 1051adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1052adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1053adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private native long lengthImpl(byte[] filePath); 1054adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1055adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1056adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns an array of strings with the file names in the directory 1057f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * represented by this file. The result is {@code null} if this file is not 1058f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * a directory. 1059adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 1060adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The entries {@code .} and {@code ..} representing the current and parent 1061adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * directory are not returned as part of the list. 1062f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1063adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return an array of strings with file names or {@code null}. 1064adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws SecurityException 1065adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if a {@code SecurityManager} is installed and it denies read 1066adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * access to this file. 1067adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #isDirectory 1068f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @see java.lang.SecurityManager#checkRead(FileDescriptor) 1069adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 10700af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes public String[] list() { 1071adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SecurityManager security = System.getSecurityManager(); 1072adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (security != null) { 1073adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project security.checkRead(path); 1074adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1075ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes if (path.isEmpty()) { 1076adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 1077adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1078f226fd4060db45a0738cbbc1bb49bebe5963ac11Elliott Hughes return listImpl(pathBytes); 1079adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1080adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1081f226fd4060db45a0738cbbc1bb49bebe5963ac11Elliott Hughes private native String[] listImpl(byte[] path); 10820af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes 10830af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes /** 10840af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * Gets a list of the files in the directory represented by this file. This 10850af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * list is then filtered through a FilenameFilter and the names of files 10860af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * with matching names are returned as an array of strings. Returns 10870af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * {@code null} if this file is not a directory. If {@code filter} is 10880af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * {@code null} then all filenames match. 10890af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * <p> 10900af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * The entries {@code .} and {@code ..} representing the current and parent 10910af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * directories are not returned as part of the list. 10920af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * 10930af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * @param filter 10940af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * the filter to match names against, may be {@code null}. 10950af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * @return an array of files or {@code null}. 10960af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * @throws SecurityException 10970af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * if a {@code SecurityManager} is installed and it denies read 10980af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * access to this file. 10990af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * @see #getPath 11000af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * @see #isDirectory 11010af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * @see java.lang.SecurityManager#checkRead(FileDescriptor) 11020af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes */ 11030af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes public String[] list(FilenameFilter filter) { 11040af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes String[] filenames = list(); 11050af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes if (filter == null || filenames == null) { 11060af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes return filenames; 11070af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes } 11080af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes List<String> result = new ArrayList<String>(filenames.length); 11090af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes for (String filename : filenames) { 11100af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes if (filter.accept(this, filename)) { 11110af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes result.add(filename); 11120af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes } 11130af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes } 11140af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes return result.toArray(new String[result.size()]); 11150af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes } 11160af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes 1117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns an array of files contained in the directory represented by this 1119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * file. The result is {@code null} if this file is not a directory. The 1120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * paths of the files in the array are absolute if the path of this file is 1121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * absolute, they are relative otherwise. 1122f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return an array of files or {@code null}. 1124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws SecurityException 1125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if a {@code SecurityManager} is installed and it denies read 1126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * access to this file. 1127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #list 1128f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @see #isDirectory 1129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public File[] listFiles() { 11310af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes return filenamesToFiles(list()); 1132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Gets a list of the files in the directory represented by this file. This 1136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * list is then filtered through a FilenameFilter and files with matching 1137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * names are returned as an array of files. Returns {@code null} if this 1138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * file is not a directory. If {@code filter} is {@code null} then all 1139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * filenames match. 1140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 1141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The entries {@code .} and {@code ..} representing the current and parent 1142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * directories are not returned as part of the list. 1143f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param filter 1145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the filter to match names against, may be {@code null}. 1146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return an array of files or {@code null}. 1147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws SecurityException 1148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if a {@code SecurityManager} is installed and it denies read 1149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * access to this file. 1150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #list(FilenameFilter filter) 1151f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @see #getPath 1152f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @see #isDirectory 1153f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @see java.lang.SecurityManager#checkRead(FileDescriptor) 1154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public File[] listFiles(FilenameFilter filter) { 11560af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes return filenamesToFiles(list(filter)); 1157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Gets a list of the files in the directory represented by this file. This 1161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * list is then filtered through a FileFilter and matching files are 1162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * returned as an array of files. Returns {@code null} if this file is not a 1163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * directory. If {@code filter} is {@code null} then all files match. 1164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 1165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The entries {@code .} and {@code ..} representing the current and parent 1166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * directories are not returned as part of the list. 1167f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param filter 1169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the filter to match names against, may be {@code null}. 1170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return an array of files or {@code null}. 1171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws SecurityException 1172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if a {@code SecurityManager} is installed and it denies read 1173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * access to this file. 1174f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @see #getPath 1175f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @see #isDirectory 1176f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @see java.lang.SecurityManager#checkRead(FileDescriptor) 1177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public File[] listFiles(FileFilter filter) { 11790af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes File[] files = listFiles(); 11800af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes if (filter == null || files == null) { 11810af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes return files; 11820af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes } 11830af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes List<File> result = new ArrayList<File>(files.length); 11840af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes for (File file : files) { 11850af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes if (filter.accept(file)) { 11860af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes result.add(file); 1187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 11890af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes return result.toArray(new File[result.size()]); 1190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 11930af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * Converts a String[] containing filenames to a File[]. 11940af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * Note that the filenames must not contain slashes. 11950af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * This method is to remove duplication in the implementation 11960af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * of File.list's overloads. 1197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 11980af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes private File[] filenamesToFiles(String[] filenames) { 11990af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes if (filenames == null) { 1200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 1201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 12020af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes int count = filenames.length; 12030af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes File[] result = new File[count]; 12040af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes for (int i = 0; i < count; ++i) { 12050af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes result[i] = new File(this, filenames[i]); 1206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 12070af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes return result; 1208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Creates the directory named by the trailing filename of this file. Does 1212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * not create the complete path required to create this directory. 1213f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1214ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * <p>Note that this method does <i>not</i> throw {@code IOException} on failure. 1215ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * Callers must check the return value. 1216ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * 1217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if the directory has been created, {@code false} 1218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * otherwise. 1219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws SecurityException 1220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if a {@code SecurityManager} is installed and it denies write 1221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * access for this file. 1222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #mkdirs 1223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean mkdir() { 1225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SecurityManager security = System.getSecurityManager(); 1226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (security != null) { 1227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project security.checkWrite(path); 1228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 122993a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes return mkdirImpl(pathBytes); 1230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private native boolean mkdirImpl(byte[] filePath); 1233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Creates the directory named by the trailing filename of this file, 1236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * including the complete directory path required to create this directory. 1237f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1238ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * <p>Note that this method does <i>not</i> throw {@code IOException} on failure. 1239ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * Callers must check the return value. 1240ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * 1241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if the necessary directories have been created, 1242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code false} if the target directory already exists or one of 1243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the directories can not be created. 1244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws SecurityException 1245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if a {@code SecurityManager} is installed and it denies write 1246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * access for this file. 1247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #mkdir 1248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean mkdirs() { 1250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* If the terminal directory already exists, answer false */ 1251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (exists()) { 1252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 1253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* If the receiver can be created, answer true */ 1256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (mkdir()) { 1257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return true; 1258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String parentDir = getParent(); 1261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* If there is no parent and we were not created, answer false */ 1262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (parentDir == null) { 1263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 1264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* Otherwise, try to create a parent directory and then this directory */ 1267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return (new File(parentDir).mkdirs() && mkdir()); 1268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Creates a new, empty file on the file system according to the path 1272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * information stored in this file. 1273f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1274ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * <p>Note that this method does <i>not</i> throw {@code IOException} on failure. 1275ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * Callers must check the return value. 1276ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * 1277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if the file has been created, {@code false} if it 1278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * already exists. 127993a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes * @throws IOException if it's not possible to create the file. 1280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws SecurityException 1281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if a {@code SecurityManager} is installed and it denies write 1282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * access for this file. 1283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean createNewFile() throws IOException { 1285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SecurityManager security = System.getSecurityManager(); 1286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (security != null) { 1287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project security.checkWrite(path); 1288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1289ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes if (path.isEmpty()) { 1290b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new IOException("No such file or directory"); 1291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 129293a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes return createNewFileImpl(pathBytes); 1293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 129593a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes private native boolean createNewFileImpl(byte[] filePath); 1296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Creates an empty temporary file using the given prefix and suffix as part 12995d40b59c6bba79dc978f173ad64cdfbd8a937018Elliott Hughes * of the file name. If {@code suffix} is null, {@code .tmp} is used. This 1300f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * method is a convenience method that calls 1301f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * {@link #createTempFile(String, String, File)} with the third argument 1302f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * being {@code null}. 1303f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param prefix 1305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the prefix to the temp file name. 1306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param suffix 1307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the suffix to the temp file name. 1308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the temporary file. 1309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 1310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs when writing the file. 1311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 13125d40b59c6bba79dc978f173ad64cdfbd8a937018Elliott Hughes public static File createTempFile(String prefix, String suffix) throws IOException { 1313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return createTempFile(prefix, suffix, null); 1314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Creates an empty temporary file in the given directory using the given 13185d40b59c6bba79dc978f173ad64cdfbd8a937018Elliott Hughes * prefix and suffix as part of the file name. If {@code suffix} is null, {@code .tmp} is used. 13195d40b59c6bba79dc978f173ad64cdfbd8a937018Elliott Hughes * 13205d40b59c6bba79dc978f173ad64cdfbd8a937018Elliott Hughes * <p>Note that this method does <i>not</i> call {@link #deleteOnExit}. 1321f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param prefix 1323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the prefix to the temp file name. 1324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param suffix 1325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the suffix to the temp file name. 1326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param directory 1327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the location to which the temp file is to be written, or 1328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code null} for the default location for temporary files, 1329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * which is taken from the "java.io.tmpdir" system property. It 1330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * may be necessary to set this property to an existing, writable 1331f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * directory for this method to work properly. 1332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the temporary file. 1333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 1334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the length of {@code prefix} is less than 3. 1335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 1336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs when writing the file. 1337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1338f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson @SuppressWarnings("nls") 1339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static File createTempFile(String prefix, String suffix, 1340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project File directory) throws IOException { 1341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Force a prefix null check first 1342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (prefix.length() < 3) { 1343b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new IllegalArgumentException("prefix must be at least 3 characters"); 1344f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 13455d40b59c6bba79dc978f173ad64cdfbd8a937018Elliott Hughes if (suffix == null) { 13465d40b59c6bba79dc978f173ad64cdfbd8a937018Elliott Hughes suffix = ".tmp"; 13475d40b59c6bba79dc978f173ad64cdfbd8a937018Elliott Hughes } 13485d40b59c6bba79dc978f173ad64cdfbd8a937018Elliott Hughes File tmpDirFile = directory; 13495d40b59c6bba79dc978f173ad64cdfbd8a937018Elliott Hughes if (tmpDirFile == null) { 1350f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson String tmpDir = AccessController.doPrivileged( 1351f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson new PriviAction<String>("java.io.tmpdir", ".")); 1352f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson tmpDirFile = new File(tmpDir); 1353f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 1354f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson File result; 1355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project do { 13565d40b59c6bba79dc978f173ad64cdfbd8a937018Elliott Hughes result = new File(tmpDirFile, prefix + new Random().nextInt() + suffix); 1357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } while (!result.createNewFile()); 1358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return result; 1359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1362ccbe3404e0691dab506d017550658e8e5974c83eElliott Hughes * Renames this file to {@code newPath}. This operation is supported for both 1363ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * files and directories. 1364ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * 1365ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * <p>Many failures are possible. Some of the more likely failures include: 1366ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * <ul> 1367ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * <li>Write permission is required on the directories containing both the source and 1368ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * destination paths. 1369ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * <li>Search permission is required for all parents of both paths. 1370ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * <li>Both paths be on the same mount point. On Android, applications are most likely to hit 1371ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * this restriction when attempting to copy between internal storage and an SD card. 1372ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * </ul> 1373ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * 1374ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * <p>Note that this method does <i>not</i> throw {@code IOException} on failure. 1375ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * Callers must check the return value. 1376f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1377ccbe3404e0691dab506d017550658e8e5974c83eElliott Hughes * @param newPath the new path. 1378ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * @return true on success. 1379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws SecurityException 1380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if a {@code SecurityManager} is installed and it denies write 1381ccbe3404e0691dab506d017550658e8e5974c83eElliott Hughes * access for this file or {@code newPath}. 1382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1383ccbe3404e0691dab506d017550658e8e5974c83eElliott Hughes public boolean renameTo(File newPath) { 1384ccbe3404e0691dab506d017550658e8e5974c83eElliott Hughes if (path.isEmpty() || newPath.path.isEmpty()) { 1385c5c9c667028146ab5f5e446c44f911c2fdd7dd30Elliott Hughes return false; 1386c5c9c667028146ab5f5e446c44f911c2fdd7dd30Elliott Hughes } 1387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SecurityManager security = System.getSecurityManager(); 1388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (security != null) { 1389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project security.checkWrite(path); 1390ccbe3404e0691dab506d017550658e8e5974c83eElliott Hughes security.checkWrite(newPath.path); 1391adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1392ccbe3404e0691dab506d017550658e8e5974c83eElliott Hughes return renameToImpl(pathBytes, newPath.pathBytes); 1393adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private native boolean renameToImpl(byte[] pathExist, byte[] pathNew); 1396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns a string containing a concise, human-readable description of this 1399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * file. 1400f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return a printable representation of this file. 1402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 1404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String toString() { 1405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return path; 1406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns a Uniform Resource Identifier for this file. The URI is system 1410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * dependent and may not be transferable between different operating / file 1411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * systems. 1412f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return an URI for this file. 1414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1415f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson @SuppressWarnings("nls") 1416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public URI toURI() { 1417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String name = getAbsoluteName(); 1418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 1419f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if (!name.startsWith("/")) { 1420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // start with sep. 1421f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson return new URI("file", null, new StringBuilder( 1422f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson name.length() + 1).append('/').append(name).toString(), 1423f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson null, null); 1424f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } else if (name.startsWith("//")) { 1425f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson return new URI("file", "", name, null); // UNC path 1426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1427f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson return new URI("file", null, name, null, null); 1428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (URISyntaxException e) { 1429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // this should never happen 1430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 1431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns a Uniform Resource Locator for this file. The URL is system 1436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * dependent and may not be transferable between different operating / file 1437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * systems. 1438f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1439f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @return a URL for this file. 1440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws java.net.MalformedURLException 1441f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * if the path cannot be transformed into a URL. 144208ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * @deprecated use {@link #toURI} and {@link java.net.URI#toURL} to get 144308ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * correct escaping of illegal characters. 1444adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 144508ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes @Deprecated 1446f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson @SuppressWarnings("nls") 1447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public URL toURL() throws java.net.MalformedURLException { 1448adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String name = getAbsoluteName(); 1449f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if (!name.startsWith("/")) { 1450adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // start with sep. 1451c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes return new URL("file", "", -1, 1452c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes new StringBuilder(name.length() + 1).append('/').append(name).toString(), null); 1453f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } else if (name.startsWith("//")) { 1454f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson return new URL("file:" + name); // UNC path 1455adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1456c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes return new URL("file", "", -1, name, null); 1457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1458adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private String getAbsoluteName() { 1460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project File f = getAbsoluteFile(); 1461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String name = f.getPath(); 1462adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1463adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (f.isDirectory() && name.charAt(name.length() - 1) != separatorChar) { 1464adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Directories must end with a slash 1465adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project name = new StringBuilder(name.length() + 1).append(name) 1466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project .append('/').toString(); 1467adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (separatorChar != '/') { // Must convert slashes. 1469adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project name = name.replace(separatorChar, '/'); 1470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return name; 1472adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1473adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1474adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void writeObject(ObjectOutputStream stream) throws IOException { 1475adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project stream.defaultWriteObject(); 1476adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project stream.writeChar(separatorChar); 1477adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1478adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 147908ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { 1480adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project stream.defaultReadObject(); 1481adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project char inSeparator = stream.readChar(); 148293a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes init(path.replace(inSeparator, separatorChar)); 1483adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 148408ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes 148508ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes /** 148608ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * Returns the total size in bytes of the partition containing this path. 148708ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * Returns 0 if this path does not exist. 148808ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * 148908ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * @since 1.6 149008ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes */ 149108ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes public long getTotalSpace() { 149208ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes SecurityManager security = System.getSecurityManager(); 149308ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes if (security != null) { 149408ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes security.checkPermission(new RuntimePermission("getFileSystemAttributes")); 149508ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes } 149608ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes return getTotalSpaceImpl(pathBytes); 149708ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes } 149808ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes private native long getTotalSpaceImpl(byte[] filePath); 149908ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes 150008ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes /** 150108ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * Returns the number of usable free bytes on the partition containing this path. 150208ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * Returns 0 if this path does not exist. 150308ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * 150408ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * <p>Note that this is likely to be an optimistic over-estimate and should not 150508ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * be taken as a guarantee your application can actually write this many bytes. 150608ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * On Android (and other Unix-based systems), this method returns the number of free bytes 150708ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * available to non-root users, regardless of whether you're actually running as root, 150808ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * and regardless of any quota or other restrictions that might apply to the user. 150908ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * (The {@code getFreeSpace} method returns the number of bytes potentially available to root.) 151008ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * 151108ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * @since 1.6 151208ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes */ 151308ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes public long getUsableSpace() { 151408ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes SecurityManager security = System.getSecurityManager(); 151508ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes if (security != null) { 151608ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes security.checkPermission(new RuntimePermission("getFileSystemAttributes")); 151708ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes } 151808ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes return getUsableSpaceImpl(pathBytes); 151908ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes } 152008ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes private native long getUsableSpaceImpl(byte[] filePath); 152108ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes 152208ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes /** 152308ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * Returns the number of free bytes on the partition containing this path. 152408ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * Returns 0 if this path does not exist. 152508ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * 152608ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * <p>Note that this is likely to be an optimistic over-estimate and should not 152708ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * be taken as a guarantee your application can actually write this many bytes. 152808ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * 152908ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * @since 1.6 153008ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes */ 153108ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes public long getFreeSpace() { 153208ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes SecurityManager security = System.getSecurityManager(); 153308ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes if (security != null) { 153408ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes security.checkPermission(new RuntimePermission("getFileSystemAttributes")); 153508ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes } 153608ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes return getFreeSpaceImpl(pathBytes); 153708ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes } 153808ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes private native long getFreeSpaceImpl(byte[] filePath); 1539adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 1540