File.java revision e32b21f14d52bac429a9c54fe031f9e92c911d64
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; 35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.security.AccessController; 36f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilsonimport java.security.SecureRandom; 37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.ArrayList; 38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.util.List; 39f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilsonimport org.apache.harmony.luni.util.DeleteOnExit; 40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.luni.util.PriviAction; 41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/** 43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * An "abstract" representation of a file system entity identified by a 44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * pathname. The pathname may be absolute (relative to the root directory 45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * of the file system) or relative to the current directory in which the program 46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * is running. 47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 480af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * The actual file referenced by a {@code File} may or may not exist. It may 490af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * also, despite the name {@code File}, be a directory or other non-regular 500af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * file. 51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 520af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * This class provides limited functionality for getting/setting file 530af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * permissions, file type, and last modified time. 540af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * <p> 550af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * Although Java doesn't specify a character encoding for filenames, on Android 560af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * Java strings are converted to UTF-8 byte sequences when sending filenames to 570af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * the operating system, and byte sequences returned by the operating system 580af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * (from the various {@code list} methods) are converted to Java strings by 590af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * decoding them as UTF-8 byte sequences. 60f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.io.Serializable 62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.lang.Comparable 63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class File implements Serializable, Comparable<File> { 65f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static final long serialVersionUID = 301077366599181567L; 67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 68c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes private static final Charset UTF_8 = Charset.forName("UTF-8"); 69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 71f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * The system dependent file separator character. 72070f14c41b2494fd008afc4d96b873873692945fElliott Hughes * This field is initialized from the system property "file.separator". 73070f14c41b2494fd008afc4d96b873873692945fElliott Hughes * Later changes to that property will have no effect on this field or this class. 74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static final char separatorChar; 76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 78070f14c41b2494fd008afc4d96b873873692945fElliott Hughes * The system dependent file separator string. 79070f14c41b2494fd008afc4d96b873873692945fElliott Hughes * This field is a single-character string equal to String.valueOf(separatorChar). 80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static final String separator; 82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 84f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * The system dependent path separator character. 85070f14c41b2494fd008afc4d96b873873692945fElliott Hughes * This field is initialized from the system property "path.separator". 86070f14c41b2494fd008afc4d96b873873692945fElliott Hughes * Later changes to that property will have no effect on this field or this class. 87adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static final char pathSeparatorChar; 89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 91070f14c41b2494fd008afc4d96b873873692945fElliott Hughes * The system dependent path separator string. 92070f14c41b2494fd008afc4d96b873873692945fElliott Hughes * This field is a single-character string equal to String.valueOf(pathSeparatorChar). 93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static final String pathSeparator; 95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* Temp file counter */ 97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static int counter; 98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 99070f14c41b2494fd008afc4d96b873873692945fElliott Hughes /** 100070f14c41b2494fd008afc4d96b873873692945fElliott Hughes * The path we return from getPath. This is almost the path we were 101070f14c41b2494fd008afc4d96b873873692945fElliott Hughes * given, but without duplicate adjacent slashes and without trailing 102070f14c41b2494fd008afc4d96b873873692945fElliott Hughes * slashes (except for the special case of the root directory). This 103070f14c41b2494fd008afc4d96b873873692945fElliott Hughes * path may be the empty string. 104070f14c41b2494fd008afc4d96b873873692945fElliott Hughes */ 105070f14c41b2494fd008afc4d96b873873692945fElliott Hughes private String path; 106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 107070f14c41b2494fd008afc4d96b873873692945fElliott Hughes /** 108070f14c41b2494fd008afc4d96b873873692945fElliott Hughes * The cached UTF-8 byte sequence corresponding to 'path'. 109070f14c41b2494fd008afc4d96b873873692945fElliott Hughes * This is suitable for direct use by our JNI, and includes a trailing NUL. 110070f14c41b2494fd008afc4d96b873873692945fElliott Hughes * For non-absolute paths, the "user.dir" property is prepended: that is, 111070f14c41b2494fd008afc4d96b873873692945fElliott Hughes * this byte sequence usually represents an absolute path (the exception 112070f14c41b2494fd008afc4d96b873873692945fElliott Hughes * being if the user overwrites the "user.dir" property with a non-absolute 113070f14c41b2494fd008afc4d96b873873692945fElliott Hughes * path). 114070f14c41b2494fd008afc4d96b873873692945fElliott Hughes */ 115070f14c41b2494fd008afc4d96b873873692945fElliott Hughes transient byte[] pathBytes; 116adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project static { 118070f14c41b2494fd008afc4d96b873873692945fElliott Hughes // The default protection domain grants access to these properties. 119f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes separatorChar = System.getProperty("file.separator", "/").charAt(0); 120f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes pathSeparatorChar = System.getProperty("path.separator", ":").charAt(0); 121070f14c41b2494fd008afc4d96b873873692945fElliott Hughes separator = String.valueOf(separatorChar); 122070f14c41b2494fd008afc4d96b873873692945fElliott Hughes pathSeparator = String.valueOf(pathSeparatorChar); 123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Constructs a new file using the specified directory and name. 127f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param dir 129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the directory where the file is stored. 130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param name 131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the file's name. 132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NullPointerException 133f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * if {@code name} is {@code null}. 134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public File(File dir, String name) { 13693a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes this(dir == null ? null : dir.getPath(), name); 137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Constructs a new file using the specified path. 141f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param path 143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the path to be used for the file. 144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public File(String path) { 146070f14c41b2494fd008afc4d96b873873692945fElliott Hughes init(path); 147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Constructs a new File using the specified directory path and file name, 151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * placing a path separator between the two. 152f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param dirPath 154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the path to the directory where the file is stored. 155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param name 156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the file's name. 157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws NullPointerException 158f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * if {@code name} is {@code null}. 159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public File(String dirPath, String name) { 161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (name == null) { 162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throw new NullPointerException(); 163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 164ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes if (dirPath == null || dirPath.isEmpty()) { 165070f14c41b2494fd008afc4d96b873873692945fElliott Hughes init(name); 166ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes } else if (name.isEmpty()) { 167070f14c41b2494fd008afc4d96b873873692945fElliott Hughes init(dirPath); 168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 169070f14c41b2494fd008afc4d96b873873692945fElliott Hughes init(join(dirPath, name)); 170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Constructs a new File using the path of the specified URI. {@code uri} 175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * needs to be an absolute and hierarchical Unified Resource Identifier with 176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * file scheme and non-empty path component, but with undefined authority, 177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * query or fragment components. 178f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param uri 180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the Unified Resource Identifier that is used to construct this 181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * file. 182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code uri} does not comply with the conditions above. 184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #toURI 185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.net.URI 186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public File(URI uri) { 188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // check pre-conditions 189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project checkURI(uri); 190070f14c41b2494fd008afc4d96b873873692945fElliott Hughes init(uri.getPath()); 19193a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes } 19293a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes 193070f14c41b2494fd008afc4d96b873873692945fElliott Hughes private void init(String dirtyPath) { 194070f14c41b2494fd008afc4d96b873873692945fElliott Hughes // Keep a copy of the cleaned-up string path. 195070f14c41b2494fd008afc4d96b873873692945fElliott Hughes this.path = fixSlashes(dirtyPath); 19693a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes // Cache the UTF-8 bytes we need for the JNI. 197028794d8a42840233d3cb316feb09b5593f19d1dElliott Hughes // TODO: we shouldn't do this caching at all; the RI demonstrably doesn't. 198028794d8a42840233d3cb316feb09b5593f19d1dElliott Hughes if (path.length() > 0 && path.charAt(0) == separatorChar) { // http://b/2486943 19993a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes this.pathBytes = newCString(path); 20093a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes return; 20193a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes } 20293a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes String userDir = AccessController.doPrivileged( 203f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes new PriviAction<String>("user.dir")); 204ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes this.pathBytes = newCString(path.isEmpty() ? userDir : join(userDir, path)); 20593a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes } 20693a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes 20793a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes private byte[] newCString(String s) { 208c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes ByteBuffer buffer = UTF_8.encode(s); 20993a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes // Add a trailing NUL, because this byte[] is going to be used as a char*. 21093a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes int byteCount = buffer.limit() + 1; 21193a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes byte[] bytes = new byte[byteCount]; 21293a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes buffer.get(bytes, 0, byteCount - 1); 21393a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes // This is an awful mistake, because '\' is a perfectly acceptable 21493a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes // character on Linux/Android. But we've shipped so many versions 21593a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes // that behaved like this, I'm too scared to change it. 21693a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes for (int i = 0; i < bytes.length; ++i) { 21793a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes if (bytes[i] == '\\') { 21893a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes bytes[i] = '/'; 21993a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes } 22093a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes } 22193a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes return bytes; 222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 224070f14c41b2494fd008afc4d96b873873692945fElliott Hughes // Removes duplicate adjacent slashes and any trailing slash. 225070f14c41b2494fd008afc4d96b873873692945fElliott Hughes private String fixSlashes(String origPath) { 226070f14c41b2494fd008afc4d96b873873692945fElliott Hughes // Remove duplicate adjacent slashes. 227070f14c41b2494fd008afc4d96b873873692945fElliott Hughes boolean lastWasSlash = false; 228070f14c41b2494fd008afc4d96b873873692945fElliott Hughes char[] newPath = origPath.toCharArray(); 229070f14c41b2494fd008afc4d96b873873692945fElliott Hughes int length = newPath.length; 230070f14c41b2494fd008afc4d96b873873692945fElliott Hughes int newLength = 0; 231070f14c41b2494fd008afc4d96b873873692945fElliott Hughes for (int i = 0; i < length; ++i) { 232070f14c41b2494fd008afc4d96b873873692945fElliott Hughes char ch = newPath[i]; 233070f14c41b2494fd008afc4d96b873873692945fElliott Hughes if (ch == '/') { 234070f14c41b2494fd008afc4d96b873873692945fElliott Hughes if (!lastWasSlash) { 235070f14c41b2494fd008afc4d96b873873692945fElliott Hughes newPath[newLength++] = separatorChar; 236070f14c41b2494fd008afc4d96b873873692945fElliott Hughes lastWasSlash = true; 237070f14c41b2494fd008afc4d96b873873692945fElliott Hughes } 238070f14c41b2494fd008afc4d96b873873692945fElliott Hughes } else { 239070f14c41b2494fd008afc4d96b873873692945fElliott Hughes newPath[newLength++] = ch; 240070f14c41b2494fd008afc4d96b873873692945fElliott Hughes lastWasSlash = false; 241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 243070f14c41b2494fd008afc4d96b873873692945fElliott Hughes // Remove any trailing slash (unless this is the root of the file system). 244070f14c41b2494fd008afc4d96b873873692945fElliott Hughes if (lastWasSlash && newLength > 1) { 245070f14c41b2494fd008afc4d96b873873692945fElliott Hughes newLength--; 246070f14c41b2494fd008afc4d96b873873692945fElliott Hughes } 247070f14c41b2494fd008afc4d96b873873692945fElliott Hughes // Reuse the original string if possible. 248070f14c41b2494fd008afc4d96b873873692945fElliott Hughes return (newLength != length) ? new String(newPath, 0, newLength) : origPath; 249070f14c41b2494fd008afc4d96b873873692945fElliott Hughes } 250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 251070f14c41b2494fd008afc4d96b873873692945fElliott Hughes // Joins two path components, adding a separator only if necessary. 252070f14c41b2494fd008afc4d96b873873692945fElliott Hughes private String join(String prefix, String suffix) { 253070f14c41b2494fd008afc4d96b873873692945fElliott Hughes int prefixLength = prefix.length(); 254070f14c41b2494fd008afc4d96b873873692945fElliott Hughes boolean haveSlash = (prefixLength > 0 && prefix.charAt(prefixLength - 1) == separatorChar); 255070f14c41b2494fd008afc4d96b873873692945fElliott Hughes if (!haveSlash) { 256070f14c41b2494fd008afc4d96b873873692945fElliott Hughes haveSlash = (suffix.length() > 0 && suffix.charAt(0) == separatorChar); 257070f14c41b2494fd008afc4d96b873873692945fElliott Hughes } 258070f14c41b2494fd008afc4d96b873873692945fElliott Hughes return haveSlash ? (prefix + suffix) : (prefix + separatorChar + suffix); 259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void checkURI(URI uri) { 262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!uri.isAbsolute()) { 263b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new IllegalArgumentException("URI is not absolute: " + uri); 264f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } else if (!uri.getRawSchemeSpecificPart().startsWith("/")) { 265b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new IllegalArgumentException("URI is not hierarchical: " + uri); 266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 267e32b21f14d52bac429a9c54fe031f9e92c911d64Jesse Wilson if (!"file".equals(uri.getScheme())) { 268b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new IllegalArgumentException("Expected file scheme in URI: " + uri); 269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 270e32b21f14d52bac429a9c54fe031f9e92c911d64Jesse Wilson String rawPath = uri.getRawPath(); 271e32b21f14d52bac429a9c54fe031f9e92c911d64Jesse Wilson if (rawPath == null || rawPath.isEmpty()) { 272b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new IllegalArgumentException("Expected non-empty path in URI: " + uri); 273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (uri.getRawAuthority() != null) { 275b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new IllegalArgumentException("Found authority in URI: " + uri); 276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (uri.getRawQuery() != null) { 278b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new IllegalArgumentException("Found query in URI: " + uri); 279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (uri.getRawFragment() != null) { 281b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new IllegalArgumentException("Found fragment in URI: " + uri); 282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Lists the file system roots. The Java platform may support zero or more 287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * file systems, each with its own platform-dependent root. Further, the 288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * canonical pathname of any file on the system will always begin with one 289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * of the returned file system roots. 290f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the array of file system roots. 292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static File[] listRoots() { 29487415b1521402398d4470aecbef7c126a6948290Elliott Hughes return new File[] { new File("/") }; 295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 29808ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * Tests whether or not this process is allowed to execute this file. 29908ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * Note that this is a best-effort result; the only way to be certain is 30008ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * to actually attempt the operation. 30108ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * 30208ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * @return {@code true} if this file can be executed, {@code false} otherwise. 30308ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * @throws SecurityException 30408ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * If a security manager exists and 30508ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * SecurityManager.checkExec(java.lang.String) disallows read 30608ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * permission to this file object 30708ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * @see java.lang.SecurityManager#checkExec(String) 30808ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * 30908ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * @since 1.6 31008ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes */ 31108ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes public boolean canExecute() { 312ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes if (path.isEmpty()) { 31308ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes return false; 31408ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes } 31508ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes SecurityManager security = System.getSecurityManager(); 31608ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes if (security != null) { 31708ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes security.checkExec(path); // Seems bogus, but this is what the RI does. 31808ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes } 31908ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes return canExecuteImpl(pathBytes); 32008ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes } 32108ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes private native boolean canExecuteImpl(byte[] filePath); 32208ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes 32308ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes /** 324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Indicates whether the current context is allowed to read from this file. 325f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if this file can be read, {@code false} otherwise. 327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws SecurityException 328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if a {@code SecurityManager} is installed and it denies the 329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * read request. 330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean canRead() { 332ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes if (path.isEmpty()) { 333f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson return false; 334f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SecurityManager security = System.getSecurityManager(); 336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (security != null) { 337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project security.checkRead(path); 338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 33908ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes return canReadImpl(pathBytes); 340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 34108ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes private native boolean canReadImpl(byte[] filePath); 3420af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes 343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Indicates whether the current context is allowed to write to this file. 345f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if this file can be written, {@code false} 347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * otherwise. 348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws SecurityException 349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if a {@code SecurityManager} is installed and it denies the 350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * write request. 351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean canWrite() { 353ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes if (path.isEmpty()) { 354c5c9c667028146ab5f5e446c44f911c2fdd7dd30Elliott Hughes return false; 355c5c9c667028146ab5f5e446c44f911c2fdd7dd30Elliott Hughes } 356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SecurityManager security = System.getSecurityManager(); 357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (security != null) { 358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project security.checkWrite(path); 359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 36008ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes return canWriteImpl(pathBytes); 361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 36208ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes private native boolean canWriteImpl(byte[] filePath); 3630af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes 364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the relative sort ordering of the paths for this file and the 366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * file {@code another}. The ordering is platform dependent. 367f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param another 369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * a file to compare this file to 370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return an int determined by comparing the two paths. Possible values are 371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * described in the Comparable interface. 372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see Comparable 373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int compareTo(File another) { 375070f14c41b2494fd008afc4d96b873873692945fElliott Hughes return this.getPath().compareTo(another.getPath()); 376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Deletes this file. Directories must be empty before they will be deleted. 380f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 381ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * <p>Note that this method does <i>not</i> throw {@code IOException} on failure. 382ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * Callers must check the return value. 383ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * 384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if this file was deleted, {@code false} otherwise. 385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws SecurityException 386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if a {@code SecurityManager} is installed and it denies the 387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * request. 388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.lang.SecurityManager#checkDelete 389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 390adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean delete() { 391ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes if (path.isEmpty()) { 392c5c9c667028146ab5f5e446c44f911c2fdd7dd30Elliott Hughes return false; 393c5c9c667028146ab5f5e446c44f911c2fdd7dd30Elliott Hughes } 394adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SecurityManager security = System.getSecurityManager(); 395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (security != null) { 396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project security.checkDelete(path); 397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 39893a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes return deleteImpl(pathBytes); 399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 401c5c9c667028146ab5f5e446c44f911c2fdd7dd30Elliott Hughes private native boolean deleteImpl(byte[] filePath); 402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Schedules this file to be automatically deleted once the virtual machine 405f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * terminates. This will only happen when the virtual machine terminates 406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * normally as described by the Java Language Specification section 12.9. 407f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws SecurityException 409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if a {@code SecurityManager} is installed and it denies the 410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * request. 411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public void deleteOnExit() { 413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SecurityManager security = System.getSecurityManager(); 414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (security != null) { 415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project security.checkDelete(path); 416adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project DeleteOnExit.getInstance().addFile(getAbsoluteName()); 418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Compares {@code obj} to this file and returns {@code true} if they 422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * represent the <em>same</em> object using a path specific comparison. 423f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 424adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param obj 425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the object to compare this file with. 426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if {@code obj} is the same as this object, 427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code false} otherwise. 428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean equals(Object obj) { 431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (!(obj instanceof File)) { 432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return path.equals(((File) obj).getPath()); 435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns a boolean indicating whether this file can be found on the 439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * underlying file system. 440f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if this file exists, {@code false} otherwise. 442adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws SecurityException 443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if a {@code SecurityManager} is installed and it denies read 444adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * access to this file. 445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #getPath 446f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @see java.lang.SecurityManager#checkRead(FileDescriptor) 447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 448adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean exists() { 449ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes if (path.isEmpty()) { 450adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 451adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SecurityManager security = System.getSecurityManager(); 453adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (security != null) { 454adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project security.checkRead(path); 455adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 45693a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes return existsImpl(pathBytes); 457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 458adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private native boolean existsImpl(byte[] filePath); 460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 462adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the absolute path of this file. 463f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 464adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the absolute file path. 465adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String getAbsolutePath() { 467c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes return new String(pathBytes, 0, pathBytes.length - 1, UTF_8); 468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 469adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns a new file constructed using the absolute path of this file. 472f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 473adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return a new file from this file's absolute path. 474adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.lang.SecurityManager#checkPropertyAccess 475adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 476adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public File getAbsoluteFile() { 477adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new File(this.getAbsolutePath()); 478adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 479adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 480adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 481adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the absolute path of this file with all references resolved. An 482adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <em>absolute</em> path is one that begins at the root of the file 483adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * system. The canonical path is one in which all references have been 484adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * resolved. For the cases of '..' and '.', where the file system supports 485adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * parent and working directory respectively, these are removed and replaced 486adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * with a direct directory reference. If the file does not exist, 487adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * getCanonicalPath() may not resolve any references and simply returns an 488adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * absolute path name or throws an IOException. 489f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 490adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the canonical path of this file. 491adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 492adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an I/O error occurs. 493adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 494adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String getCanonicalPath() throws IOException { 4954030ad60f305d1f23e9b681dca7a181ab4f09276Jesse Wilson // BEGIN android-removed 4961072631d16a5e5ffd97ae346e20dcd112df9dc13Jesse Wilson // Caching the canonical path is bogus. Users facing specific 4971072631d16a5e5ffd97ae346e20dcd112df9dc13Jesse Wilson // performance problems can perform their own caching, with 4981072631d16a5e5ffd97ae346e20dcd112df9dc13Jesse Wilson // eviction strategies that are appropriate for their application. 4991072631d16a5e5ffd97ae346e20dcd112df9dc13Jesse Wilson // A VM-wide cache with no mechanism to evict stale elements is a 5001072631d16a5e5ffd97ae346e20dcd112df9dc13Jesse Wilson // disservice to applications that need up-to-date data. 5014030ad60f305d1f23e9b681dca7a181ab4f09276Jesse Wilson // String canonPath = FileCanonPathCache.get(absPath); 5024030ad60f305d1f23e9b681dca7a181ab4f09276Jesse Wilson // if (canonPath != null) { 5034030ad60f305d1f23e9b681dca7a181ab4f09276Jesse Wilson // return canonPath; 5044030ad60f305d1f23e9b681dca7a181ab4f09276Jesse Wilson // } 5054030ad60f305d1f23e9b681dca7a181ab4f09276Jesse Wilson // END android-removed 5064030ad60f305d1f23e9b681dca7a181ab4f09276Jesse Wilson 50793a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes byte[] result = pathBytes; 508f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if(separatorChar == '/') { 509f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // resolve the full path first 510f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson result = resolveLink(result, result.length, false); 511f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // resolve the parent directories 512f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson result = resolve(result); 513adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 514adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int numSeparators = 1; 515adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i < result.length; i++) { 516adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (result[i] == separatorChar) { 517adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project numSeparators++; 518adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 519adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 520adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int sepLocations[] = new int[numSeparators]; 521adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int rootLoc = 0; 522adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (separatorChar != '/') { 523adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (result[0] == '\\') { 524adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project rootLoc = (result.length > 1 && result[1] == '\\') ? 1 : 0; 525adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 526adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project rootLoc = 2; // skip drive i.e. c: 527adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 528adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 529adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project byte newResult[] = new byte[result.length + 1]; 530adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int newLength = 0, lastSlash = 0, foundDots = 0; 531adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project sepLocations[lastSlash] = rootLoc; 532adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int i = 0; i <= result.length; i++) { 533adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (i < rootLoc) { 534adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project newResult[newLength++] = result[i]; 535adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } else { 536adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (i == result.length || result[i] == separatorChar) { 537adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (i == result.length && foundDots == 0) { 538adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project break; 539adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 540adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (foundDots == 1) { 541adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* Don't write anything, just reset and continue */ 542adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project foundDots = 0; 543adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project continue; 544adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 545adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (foundDots > 1) { 546adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* Go back N levels */ 547adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project lastSlash = lastSlash > (foundDots - 1) ? lastSlash 548adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project - (foundDots - 1) : 0; 549adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project newLength = sepLocations[lastSlash] + 1; 550adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project foundDots = 0; 551adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project continue; 552adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 553adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project sepLocations[++lastSlash] = newLength; 554adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project newResult[newLength++] = (byte) separatorChar; 555adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project continue; 556adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 557adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (result[i] == '.') { 558adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project foundDots++; 559adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project continue; 560adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 561adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* Found some dots within text, write them out */ 562adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (foundDots > 0) { 563adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project for (int j = 0; j < foundDots; j++) { 564adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project newResult[newLength++] = (byte) '.'; 565adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 566adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 567adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project newResult[newLength++] = result[i]; 568adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project foundDots = 0; 569adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 570adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 571adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // remove trailing slash 572adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (newLength > (rootLoc + 1) 573adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project && newResult[newLength - 1] == separatorChar) { 574adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project newLength--; 575adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 576adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project newResult[newLength] = 0; 577adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project newResult = getCanonImpl(newResult); 578adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project newLength = newResult.length; 579c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes return new String(newResult, 0, newLength, UTF_8); 580f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 581f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 582f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson /* 583f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * Resolve symbolic links in the parent directories. 584f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson */ 585f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson private byte[] resolve(byte[] newResult) throws IOException { 586f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson int last = 1, nextSize, linkSize; 587f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson byte[] linkPath = newResult, bytes; 588f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson boolean done, inPlace; 589f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson for (int i = 1; i <= newResult.length; i++) { 590f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if (i == newResult.length || newResult[i] == separatorChar) { 591f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson done = i >= newResult.length - 1; 592f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // if there is only one segment, do nothing 593f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if (done && linkPath.length == 1) { 594f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson return newResult; 595f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 596f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson inPlace = false; 597f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if (linkPath == newResult) { 598f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson bytes = newResult; 599f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // if there are no symbolic links, terminate the C string 600f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // instead of copying 601f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if (!done) { 602f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson inPlace = true; 603f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson newResult[i] = '\0'; 604f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 605f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } else { 606f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson nextSize = i - last + 1; 607f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson linkSize = linkPath.length; 608f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if (linkPath[linkSize - 1] == separatorChar) { 609f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson linkSize--; 610f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 611f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson bytes = new byte[linkSize + nextSize]; 612f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson System.arraycopy(linkPath, 0, bytes, 0, linkSize); 613f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson System.arraycopy(newResult, last - 1, bytes, linkSize, 614f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson nextSize); 615f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // the full path has already been resolved 616f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 617f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if (done) { 618f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson return bytes; 619f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 620f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson linkPath = resolveLink(bytes, inPlace ? i : bytes.length, true); 621f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if (inPlace) { 622f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson newResult[i] = '/'; 623f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 624f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson last = i + 1; 625f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 626f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 627f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson throw new InternalError(); 628f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 629f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson 630f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson /* 631f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * Resolve a symbolic link. While the path resolves to an existing path, 632f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * keep resolving. If an absolute link is found, resolve the parent 633f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * directories if resolveAbsolute is true. 634f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson */ 635f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson private byte[] resolveLink(byte[] pathBytes, int length, 636f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson boolean resolveAbsolute) throws IOException { 637f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson boolean restart = false; 638f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson byte[] linkBytes, temp; 639f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson do { 640f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson linkBytes = getLinkImpl(pathBytes); 641f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if (linkBytes == pathBytes) { 642f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson break; 643f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 644f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if (linkBytes[0] == separatorChar) { 645f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // link to an absolute path, if resolving absolute paths, 646f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // resolve the parent dirs again 647f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson restart = resolveAbsolute; 648f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson pathBytes = linkBytes; 649f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } else { 650f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson int last = length - 1; 651f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson while (pathBytes[last] != separatorChar) { 652f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson last--; 653f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 654f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson last++; 655f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson temp = new byte[last + linkBytes.length]; 656f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson System.arraycopy(pathBytes, 0, temp, 0, last); 657f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson System.arraycopy(linkBytes, 0, temp, last, linkBytes.length); 658f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson pathBytes = temp; 659f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 660f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson length = pathBytes.length; 661f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } while (existsImpl(pathBytes)); 662f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson // resolve the parent directories 663f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if (restart) { 664f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson return resolve(pathBytes); 665f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 666f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson return pathBytes; 667adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 668adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 6690af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes private native byte[] getLinkImpl(byte[] filePath); 6700af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes 671adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 672adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns a new file created using the canonical path of this file. 673adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Equivalent to {@code new File(this.getCanonicalPath())}. 674f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 675adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the new file constructed from this file's canonical path. 676adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 677adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an I/O error occurs. 678adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see java.lang.SecurityManager#checkPropertyAccess 679adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 680adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public File getCanonicalFile() throws IOException { 681adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new File(getCanonicalPath()); 682adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 683adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 684adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private native byte[] getCanonImpl(byte[] filePath); 685adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 686adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 687adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the name of the file or directory represented by this file. 688f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 689adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return this file's name or an empty string if there is no name part in 690adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the file's path. 691adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 692adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String getName() { 693adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int separatorIndex = path.lastIndexOf(separator); 694adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return (separatorIndex < 0) ? path : path.substring(separatorIndex + 1, 695adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project path.length()); 696adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 697adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 698adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 699adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the pathname of the parent of this file. This is the path up to 700adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * but not including the last name. {@code null} is returned if there is no 701adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * parent. 702f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 703adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return this file's parent pathname or {@code null}. 704adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 705adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String getParent() { 706adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int length = path.length(), firstInPath = 0; 707adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (separatorChar == '\\' && length > 2 && path.charAt(1) == ':') { 708adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project firstInPath = 2; 709adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 710adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project int index = path.lastIndexOf(separatorChar); 711adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (index == -1 && firstInPath > 0) { 712adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project index = 2; 713adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 714adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (index == -1 || path.charAt(length - 1) == separatorChar) { 715adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 716adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 717adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (path.indexOf(separatorChar) == index 718adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project && path.charAt(firstInPath) == separatorChar) { 719adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return path.substring(0, index + 1); 720adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 721adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return path.substring(0, index); 722adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 723adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 724adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 725adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns a new file made from the pathname of the parent of this file. 726adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * This is the path up to but not including the last name. {@code null} is 727adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * returned when there is no parent. 728f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 729adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return a new file representing this file's parent or {@code null}. 730adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 731adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public File getParentFile() { 732adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String tempParent = getParent(); 733adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (tempParent == null) { 734adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 735adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 736adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new File(tempParent); 737adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 738adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 739adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 740adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the path of this file. 741f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 742adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return this file's path. 743adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 744adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String getPath() { 745adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return path; 746adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 747adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 748adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 749adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns an integer hash code for the receiver. Any two objects for which 750adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code equals} returns {@code true} must return the same hash code. 751f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 752adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return this files's hash value. 753adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #equals 754adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 755adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 756adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public int hashCode() { 757070f14c41b2494fd008afc4d96b873873692945fElliott Hughes return getPath().hashCode() ^ 1234321; 758adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 759adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 760adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 761adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Indicates if this file's pathname is absolute. Whether a pathname is 7620af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * absolute is platform specific. On Android, absolute paths start with 7630af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * the character '/'. 76408ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * 765adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if this file's pathname is absolute, {@code false} 766adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * otherwise. 767adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #getPath 768adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 769adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean isAbsolute() { 770adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return path.length() > 0 && path.charAt(0) == separatorChar; 771adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 772adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 773adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 774adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Indicates if this file represents a <em>directory</em> on the 775adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * underlying file system. 776f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 777adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if this file is a directory, {@code false} 778adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * otherwise. 779adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws SecurityException 780adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if a {@code SecurityManager} is installed and it denies read 781adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * access to this file. 782adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 783adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean isDirectory() { 784ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes if (path.isEmpty()) { 785adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 786adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 787adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SecurityManager security = System.getSecurityManager(); 788adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (security != null) { 789adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project security.checkRead(path); 790adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 79193a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes return isDirectoryImpl(pathBytes); 792adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 793adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 794adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private native boolean isDirectoryImpl(byte[] filePath); 795adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 796adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 797adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Indicates if this file represents a <em>file</em> on the underlying 798adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * file system. 799f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 800adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if this file is a file, {@code false} otherwise. 801adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws SecurityException 802adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if a {@code SecurityManager} is installed and it denies read 803adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * access to this file. 804adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 805adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean isFile() { 806ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes if (path.isEmpty()) { 807adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 808adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 809adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SecurityManager security = System.getSecurityManager(); 810adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (security != null) { 811adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project security.checkRead(path); 812adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 81393a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes return isFileImpl(pathBytes); 814adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 815adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 816adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private native boolean isFileImpl(byte[] filePath); 817adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 818adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 819adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns whether or not this file is a hidden file as defined by the 820f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * operating system. The notion of "hidden" is system-dependent. For Unix 821f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * systems a file is considered hidden if its name starts with a ".". For 822f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * Windows systems there is an explicit flag in the file system for this 823f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * purpose. 824f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 825adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if the file is hidden, {@code false} otherwise. 826adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws SecurityException 827adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if a {@code SecurityManager} is installed and it denies read 828adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * access to this file. 829adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 830adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean isHidden() { 831ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes if (path.isEmpty()) { 832adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 833adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 834adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SecurityManager security = System.getSecurityManager(); 835adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (security != null) { 836adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project security.checkRead(path); 837adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 83887415b1521402398d4470aecbef7c126a6948290Elliott Hughes return getName().startsWith("."); 839adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 840adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 841adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 842adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the time when this file was last modified, measured in 843adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * milliseconds since January 1st, 1970, midnight. 8441326cfc6f105f6c8fd5ffd83793223e1a797409dElliott Hughes * Returns 0 if the file does not exist. 845f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 846adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the time when this file was last modified. 847adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws SecurityException 848adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if a {@code SecurityManager} is installed and it denies read 849adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * access to this file. 850adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 851adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public long lastModified() { 852ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes if (path.isEmpty()) { 853c5c9c667028146ab5f5e446c44f911c2fdd7dd30Elliott Hughes return 0; 854c5c9c667028146ab5f5e446c44f911c2fdd7dd30Elliott Hughes } 855adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SecurityManager security = System.getSecurityManager(); 856adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (security != null) { 857adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project security.checkRead(path); 858adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 85993a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes return lastModifiedImpl(pathBytes); 860adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 861adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 862adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private native long lastModifiedImpl(byte[] filePath); 863adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 864adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 865adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Sets the time this file was last modified, measured in milliseconds since 866adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * January 1st, 1970, midnight. 867f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 868ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * <p>Note that this method does <i>not</i> throw {@code IOException} on failure. 869ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * Callers must check the return value. 870ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * 871adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param time 872adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the last modification time for this file. 873adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if the operation is successful, {@code false} 874adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * otherwise. 875adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 876adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if {@code time < 0}. 877adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws SecurityException 878adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if a {@code SecurityManager} is installed and it denies write 879adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * access to this file. 880adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 881adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean setLastModified(long time) { 882ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes if (path.isEmpty()) { 883c5c9c667028146ab5f5e446c44f911c2fdd7dd30Elliott Hughes return false; 884c5c9c667028146ab5f5e446c44f911c2fdd7dd30Elliott Hughes } 885adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (time < 0) { 886b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new IllegalArgumentException("time < 0"); 887adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 888adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SecurityManager security = System.getSecurityManager(); 889adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (security != null) { 890adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project security.checkWrite(path); 891adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 89293a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes return setLastModifiedImpl(pathBytes, time); 893adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 894adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 895adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private native boolean setLastModifiedImpl(byte[] path, long time); 896adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 897adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 89808ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * Equivalent to setWritable(false, false). 899f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 90008ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * @see #setWritable(boolean, boolean) 901adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 902adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean setReadOnly() { 90308ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes return setWritable(false, false); 90408ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes } 90508ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes 90608ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes /** 90708ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * Manipulates the execute permissions for the abstract path designated by 90808ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * this file. 90908ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * 910ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * <p>Note that this method does <i>not</i> throw {@code IOException} on failure. 911ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * Callers must check the return value. 912ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * 91308ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * @param executable 91408ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * To allow execute permission if true, otherwise disallow 91508ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * @param ownerOnly 91608ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * To manipulate execute permission only for owner if true, 91708ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * otherwise for everyone. The manipulation will apply to 91808ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * everyone regardless of this value if the underlying system 91908ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * does not distinguish owner and other users. 92008ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * @return true if and only if the operation succeeded. If the user does not 92108ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * have permission to change the access permissions of this abstract 92208ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * pathname the operation will fail. If the underlying file system 92308ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * does not support execute permission and the value of executable 92408ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * is false, this operation will fail. 92508ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * @throws SecurityException - 92608ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * If a security manager exists and 92708ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * SecurityManager.checkWrite(java.lang.String) disallows write 92808ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * permission to this file object 92908ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * @since 1.6 93008ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes */ 93108ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes public boolean setExecutable(boolean executable, boolean ownerOnly) { 932ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes if (path.isEmpty()) { 933c5c9c667028146ab5f5e446c44f911c2fdd7dd30Elliott Hughes return false; 934c5c9c667028146ab5f5e446c44f911c2fdd7dd30Elliott Hughes } 935adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SecurityManager security = System.getSecurityManager(); 936adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (security != null) { 937adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project security.checkWrite(path); 938adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 93908ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes return setExecutableImpl(pathBytes, executable, ownerOnly); 94008ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes } 94108ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes 94208ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes /** 94308ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * Equivalent to setExecutable(executable, true). 944ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * @see #setExecutable(boolean, boolean) 94508ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * @since 1.6 94608ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes */ 94708ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes public boolean setExecutable(boolean executable) { 94808ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes return setExecutable(executable, true); 949adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 950adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 95108ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes private native boolean setExecutableImpl(byte[] path, boolean executable, boolean ownerOnly); 95208ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes 95308ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes /** 95408ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * Manipulates the read permissions for the abstract path designated by this 95508ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * file. 95608ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * 95708ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * @param readable 95808ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * To allow read permission if true, otherwise disallow 95908ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * @param ownerOnly 96008ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * To manipulate read permission only for owner if true, 96108ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * otherwise for everyone. The manipulation will apply to 96208ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * everyone regardless of this value if the underlying system 96308ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * does not distinguish owner and other users. 96408ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * @return true if and only if the operation succeeded. If the user does not 96508ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * have permission to change the access permissions of this abstract 96608ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * pathname the operation will fail. If the underlying file system 96708ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * does not support read permission and the value of readable is 96808ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * false, this operation will fail. 96908ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * @throws SecurityException - 97008ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * If a security manager exists and 97108ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * SecurityManager.checkWrite(java.lang.String) disallows write 97208ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * permission to this file object 97308ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * @since 1.6 97408ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes */ 97508ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes public boolean setReadable(boolean readable, boolean ownerOnly) { 976ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes if (path.isEmpty()) { 97708ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes return false; 97808ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes } 97908ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes SecurityManager security = System.getSecurityManager(); 98008ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes if (security != null) { 98108ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes security.checkWrite(path); 98208ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes } 98308ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes return setReadableImpl(pathBytes, readable, ownerOnly); 98408ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes } 98508ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes 98608ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes /** 98708ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * Equivalent to setReadable(readable, true). 988ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * @see #setReadable(boolean, boolean) 98908ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * @since 1.6 99008ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes */ 99108ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes public boolean setReadable(boolean readable) { 99208ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes return setReadable(readable, true); 99308ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes } 99408ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes 99508ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes private native boolean setReadableImpl(byte[] path, boolean readable, boolean ownerOnly); 99608ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes 99708ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes /** 99808ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * Manipulates the write permissions for the abstract path designated by this 99908ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * file. 100008ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * 100108ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * @param writable 100208ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * To allow write permission if true, otherwise disallow 100308ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * @param ownerOnly 100408ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * To manipulate write permission only for owner if true, 100508ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * otherwise for everyone. The manipulation will apply to 100608ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * everyone regardless of this value if the underlying system 100708ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * does not distinguish owner and other users. 100808ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * @return true if and only if the operation succeeded. If the user does not 100908ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * have permission to change the access permissions of this abstract 101008ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * pathname the operation will fail. 101108ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * @throws SecurityException - 101208ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * If a security manager exists and 101308ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * SecurityManager.checkWrite(java.lang.String) disallows write 101408ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * permission to this file object 101508ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * @since 1.6 101608ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes */ 101708ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes public boolean setWritable(boolean writable, boolean ownerOnly) { 1018ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes if (path.isEmpty()) { 101908ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes return false; 102008ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes } 102108ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes SecurityManager security = System.getSecurityManager(); 102208ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes if (security != null) { 102308ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes security.checkWrite(path); 102408ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes } 102508ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes return setWritableImpl(pathBytes, writable, ownerOnly); 102608ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes } 102708ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes 102808ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes /** 102908ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * Equivalent to setWritable(writable, true). 1030ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * @see #setWritable(boolean, boolean) 103108ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * @since 1.6 103208ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes */ 103308ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes public boolean setWritable(boolean writable) { 103408ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes return setWritable(writable, true); 103508ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes } 103608ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes 103708ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes private native boolean setWritableImpl(byte[] path, boolean writable, boolean ownerOnly); 1038adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1039adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1040adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns the length of this file in bytes. 10411326cfc6f105f6c8fd5ffd83793223e1a797409dElliott Hughes * Returns 0 if the file does not exist. 10421326cfc6f105f6c8fd5ffd83793223e1a797409dElliott Hughes * The result for a directory is not defined. 1043f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1044adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the number of bytes in this file. 1045adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws SecurityException 1046adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if a {@code SecurityManager} is installed and it denies read 1047adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * access to this file. 1048adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1049adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public long length() { 1050adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SecurityManager security = System.getSecurityManager(); 1051adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (security != null) { 1052adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project security.checkRead(path); 1053adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 105493a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes return lengthImpl(pathBytes); 1055adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1056adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1057adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private native long lengthImpl(byte[] filePath); 1058adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1059adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1060adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns an array of strings with the file names in the directory 1061f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * represented by this file. The result is {@code null} if this file is not 1062f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * a directory. 1063adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 1064adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The entries {@code .} and {@code ..} representing the current and parent 1065adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * directory are not returned as part of the list. 1066f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1067adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return an array of strings with file names or {@code null}. 1068adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws SecurityException 1069adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if a {@code SecurityManager} is installed and it denies read 1070adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * access to this file. 1071adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #isDirectory 1072f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @see java.lang.SecurityManager#checkRead(FileDescriptor) 1073adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 10740af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes public String[] list() { 1075adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SecurityManager security = System.getSecurityManager(); 1076adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (security != null) { 1077adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project security.checkRead(path); 1078adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1079ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes if (path.isEmpty()) { 1080adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 1081adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1082f226fd4060db45a0738cbbc1bb49bebe5963ac11Elliott Hughes return listImpl(pathBytes); 1083adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1084adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1085f226fd4060db45a0738cbbc1bb49bebe5963ac11Elliott Hughes private native String[] listImpl(byte[] path); 10860af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes 10870af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes /** 10880af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * Gets a list of the files in the directory represented by this file. This 10890af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * list is then filtered through a FilenameFilter and the names of files 10900af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * with matching names are returned as an array of strings. Returns 10910af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * {@code null} if this file is not a directory. If {@code filter} is 10920af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * {@code null} then all filenames match. 10930af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * <p> 10940af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * The entries {@code .} and {@code ..} representing the current and parent 10950af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * directories are not returned as part of the list. 10960af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * 10970af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * @param filter 10980af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * the filter to match names against, may be {@code null}. 10990af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * @return an array of files or {@code null}. 11000af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * @throws SecurityException 11010af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * if a {@code SecurityManager} is installed and it denies read 11020af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * access to this file. 11030af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * @see #getPath 11040af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * @see #isDirectory 11050af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * @see java.lang.SecurityManager#checkRead(FileDescriptor) 11060af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes */ 11070af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes public String[] list(FilenameFilter filter) { 11080af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes String[] filenames = list(); 11090af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes if (filter == null || filenames == null) { 11100af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes return filenames; 11110af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes } 11120af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes List<String> result = new ArrayList<String>(filenames.length); 11130af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes for (String filename : filenames) { 11140af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes if (filter.accept(this, filename)) { 11150af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes result.add(filename); 11160af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes } 11170af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes } 11180af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes return result.toArray(new String[result.size()]); 11190af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes } 11200af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes 1121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns an array of files contained in the directory represented by this 1123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * file. The result is {@code null} if this file is not a directory. The 1124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * paths of the files in the array are absolute if the path of this file is 1125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * absolute, they are relative otherwise. 1126f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return an array of files or {@code null}. 1128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws SecurityException 1129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if a {@code SecurityManager} is installed and it denies read 1130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * access to this file. 1131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #list 1132f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @see #isDirectory 1133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public File[] listFiles() { 11350af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes return filenamesToFiles(list()); 1136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Gets a list of the files in the directory represented by this file. This 1140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * list is then filtered through a FilenameFilter and files with matching 1141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * names are returned as an array of files. Returns {@code null} if this 1142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * file is not a directory. If {@code filter} is {@code null} then all 1143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * filenames match. 1144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 1145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The entries {@code .} and {@code ..} representing the current and parent 1146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * directories are not returned as part of the list. 1147f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param filter 1149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the filter to match names against, may be {@code null}. 1150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return an array of files or {@code null}. 1151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws SecurityException 1152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if a {@code SecurityManager} is installed and it denies read 1153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * access to this file. 1154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #list(FilenameFilter filter) 1155f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @see #getPath 1156f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @see #isDirectory 1157f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @see java.lang.SecurityManager#checkRead(FileDescriptor) 1158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1159adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public File[] listFiles(FilenameFilter filter) { 11600af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes return filenamesToFiles(list(filter)); 1161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Gets a list of the files in the directory represented by this file. This 1165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * list is then filtered through a FileFilter and matching files are 1166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * returned as an array of files. Returns {@code null} if this file is not a 1167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * directory. If {@code filter} is {@code null} then all files match. 1168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <p> 1169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * The entries {@code .} and {@code ..} representing the current and parent 1170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * directories are not returned as part of the list. 1171f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param filter 1173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the filter to match names against, may be {@code null}. 1174adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return an array of files or {@code null}. 1175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws SecurityException 1176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if a {@code SecurityManager} is installed and it denies read 1177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * access to this file. 1178f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @see #getPath 1179f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @see #isDirectory 1180f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @see java.lang.SecurityManager#checkRead(FileDescriptor) 1181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public File[] listFiles(FileFilter filter) { 11830af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes File[] files = listFiles(); 11840af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes if (filter == null || files == null) { 11850af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes return files; 11860af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes } 11870af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes List<File> result = new ArrayList<File>(files.length); 11880af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes for (File file : files) { 11890af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes if (filter.accept(file)) { 11900af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes result.add(file); 1191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 11930af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes return result.toArray(new File[result.size()]); 1194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 11970af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * Converts a String[] containing filenames to a File[]. 11980af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * Note that the filenames must not contain slashes. 11990af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * This method is to remove duplication in the implementation 12000af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes * of File.list's overloads. 1201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 12020af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes private File[] filenamesToFiles(String[] filenames) { 12030af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes if (filenames == null) { 1204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 1205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 12060af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes int count = filenames.length; 12070af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes File[] result = new File[count]; 12080af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes for (int i = 0; i < count; ++i) { 12090af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes result[i] = new File(this, filenames[i]); 1210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 12110af4ef265f1e67edfcc5e34bcb68ee42a791beefElliott Hughes return result; 1212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Creates the directory named by the trailing filename of this file. Does 1216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * not create the complete path required to create this directory. 1217f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1218ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * <p>Note that this method does <i>not</i> throw {@code IOException} on failure. 1219ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * Callers must check the return value. 1220ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * 1221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if the directory has been created, {@code false} 1222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * otherwise. 1223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws SecurityException 1224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if a {@code SecurityManager} is installed and it denies write 1225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * access for this file. 1226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #mkdirs 1227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean mkdir() { 1229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SecurityManager security = System.getSecurityManager(); 1230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (security != null) { 1231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project security.checkWrite(path); 1232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 123393a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes return mkdirImpl(pathBytes); 1234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private native boolean mkdirImpl(byte[] filePath); 1237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Creates the directory named by the trailing filename of this file, 1240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * including the complete directory path required to create this directory. 1241f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1242ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * <p>Note that this method does <i>not</i> throw {@code IOException} on failure. 1243ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * Callers must check the return value. 1244ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * 1245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if the necessary directories have been created, 1246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code false} if the target directory already exists or one of 1247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the directories can not be created. 1248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws SecurityException 1249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if a {@code SecurityManager} is installed and it denies write 1250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * access for this file. 1251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see #mkdir 1252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean mkdirs() { 1254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* If the terminal directory already exists, answer false */ 1255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (exists()) { 1256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 1257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* If the receiver can be created, answer true */ 1260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (mkdir()) { 1261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return true; 1262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String parentDir = getParent(); 1265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* If there is no parent and we were not created, answer false */ 1266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (parentDir == null) { 1267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return false; 1268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /* Otherwise, try to create a parent directory and then this directory */ 1271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return (new File(parentDir).mkdirs() && mkdir()); 1272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Creates a new, empty file on the file system according to the path 1276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * information stored in this file. 1277f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1278ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * <p>Note that this method does <i>not</i> throw {@code IOException} on failure. 1279ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * Callers must check the return value. 1280ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * 1281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return {@code true} if the file has been created, {@code false} if it 1282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * already exists. 128393a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes * @throws IOException if it's not possible to create the file. 1284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws SecurityException 1285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if a {@code SecurityManager} is installed and it denies write 1286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * access for this file. 1287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public boolean createNewFile() throws IOException { 1289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SecurityManager security = System.getSecurityManager(); 1290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (security != null) { 1291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project security.checkWrite(path); 1292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1293ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes if (path.isEmpty()) { 1294b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new IOException("No such file or directory"); 1295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 129693a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes return createNewFileImpl(pathBytes); 1297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 129993a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes private native boolean createNewFileImpl(byte[] filePath); 1300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Creates an empty temporary file using the given prefix and suffix as part 1303f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * of the file name. If suffix is {@code null}, {@code .tmp} is used. This 1304f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * method is a convenience method that calls 1305f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * {@link #createTempFile(String, String, File)} with the third argument 1306f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * being {@code null}. 1307f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param prefix 1309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the prefix to the temp file name. 1310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param suffix 1311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the suffix to the temp file name. 1312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the temporary file. 1313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 1314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs when writing the file. 1315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static File createTempFile(String prefix, String suffix) 1317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project throws IOException { 1318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return createTempFile(prefix, suffix, null); 1319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Creates an empty temporary file in the given directory using the given 1323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * prefix and suffix as part of the file name. 1324f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param prefix 1326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the prefix to the temp file name. 1327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param suffix 1328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the suffix to the temp file name. 1329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param directory 1330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * the location to which the temp file is to be written, or 1331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * {@code null} for the default location for temporary files, 1332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * which is taken from the "java.io.tmpdir" system property. It 1333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * may be necessary to set this property to an existing, writable 1334f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * directory for this method to work properly. 1335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return the temporary file. 1336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IllegalArgumentException 1337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if the length of {@code prefix} is less than 3. 1338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws IOException 1339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if an error occurs when writing the file. 1340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1341f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson @SuppressWarnings("nls") 1342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public static File createTempFile(String prefix, String suffix, 1343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project File directory) throws IOException { 1344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Force a prefix null check first 1345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (prefix.length() < 3) { 1346b1396870f92135aa140bd2b86221768dea5bc11dElliott Hughes throw new IllegalArgumentException("prefix must be at least 3 characters"); 1347f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 1348f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson String newSuffix = suffix == null ? ".tmp" : suffix; 1349f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson File tmpDirFile; 1350f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if (directory == null) { 1351f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson String tmpDir = AccessController.doPrivileged( 1352f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson new PriviAction<String>("java.io.tmpdir", ".")); 1353f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson tmpDirFile = new File(tmpDir); 1354f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } else { 1355f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson tmpDirFile = directory; 1356f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } 1357f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson File result; 1358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project do { 1359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project result = genTempFile(prefix, newSuffix, tmpDirFile); 1360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } while (!result.createNewFile()); 1361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return result; 1362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private static File genTempFile(String prefix, String suffix, File directory) { 1365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (counter == 0) { 1366070f14c41b2494fd008afc4d96b873873692945fElliott Hughes // TODO: this doesn't make a lot of sense. SecureRandom for the seed, but then always just add one? 1367f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson int newInt = new SecureRandom().nextInt(); 1368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project counter = ((newInt / 65535) & 0xFFFF) + 0x2710; 1369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project StringBuilder newName = new StringBuilder(); 1371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project newName.append(prefix); 1372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project newName.append(counter++); 1373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project newName.append(suffix); 1374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return new File(directory, newName.toString()); 1375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1378ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * Renames this file to {@code dest}. This operation is supported for both 1379ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * files and directories. 1380ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * 1381ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * <p>Many failures are possible. Some of the more likely failures include: 1382ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * <ul> 1383ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * <li>Write permission is required on the directories containing both the source and 1384ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * destination paths. 1385ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * <li>Search permission is required for all parents of both paths. 1386ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * <li>Both paths be on the same mount point. On Android, applications are most likely to hit 1387ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * this restriction when attempting to copy between internal storage and an SD card. 1388ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * </ul> 1389ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * 1390ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * <p>Note that this method does <i>not</i> throw {@code IOException} on failure. 1391ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * Callers must check the return value. 1392f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1393ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * @param dest the new name. 1394ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes * @return true on success. 1395adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws SecurityException 1396adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * if a {@code SecurityManager} is installed and it denies write 1397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * access for this file or the {@code dest} file. 1398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1399ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes public boolean renameTo(File dest) { 1400ab3683bce6e370c946598bfad54387fa38ce69dfElliott Hughes if (path.isEmpty() || dest.path.isEmpty()) { 1401c5c9c667028146ab5f5e446c44f911c2fdd7dd30Elliott Hughes return false; 1402c5c9c667028146ab5f5e446c44f911c2fdd7dd30Elliott Hughes } 1403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project SecurityManager security = System.getSecurityManager(); 1404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (security != null) { 1405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project security.checkWrite(path); 1406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project security.checkWrite(dest.path); 1407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 140893a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes return renameToImpl(pathBytes, dest.pathBytes); 1409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1410adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1411adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private native boolean renameToImpl(byte[] pathExist, byte[] pathNew); 1412adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1413adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1414adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns a string containing a concise, human-readable description of this 1415adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * file. 1416f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1417adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return a printable representation of this file. 1418adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1419adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project @Override 1420adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public String toString() { 1421adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return path; 1422adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1423adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1424adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1425adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns a Uniform Resource Identifier for this file. The URI is system 1426adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * dependent and may not be transferable between different operating / file 1427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * systems. 1428f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @return an URI for this file. 1430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 1431f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson @SuppressWarnings("nls") 1432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public URI toURI() { 1433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String name = getAbsoluteName(); 1434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project try { 1435f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if (!name.startsWith("/")) { 1436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // start with sep. 1437f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson return new URI("file", null, new StringBuilder( 1438f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson name.length() + 1).append('/').append(name).toString(), 1439f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson null, null); 1440f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } else if (name.startsWith("//")) { 1441f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson return new URI("file", "", name, null); // UNC path 1442adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1443f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson return new URI("file", null, name, null, null); 1444adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } catch (URISyntaxException e) { 1445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // this should never happen 1446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return null; 1447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1448adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1449adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1450adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project /** 1451adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Returns a Uniform Resource Locator for this file. The URL is system 1452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * dependent and may not be transferable between different operating / file 1453adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * systems. 1454f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * 1455f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * @return a URL for this file. 1456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @throws java.net.MalformedURLException 1457f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson * if the path cannot be transformed into a URL. 145808ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * @deprecated use {@link #toURI} and {@link java.net.URI#toURL} to get 145908ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * correct escaping of illegal characters. 1460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */ 146108ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes @Deprecated 1462f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson @SuppressWarnings("nls") 1463adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project public URL toURL() throws java.net.MalformedURLException { 1464adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String name = getAbsoluteName(); 1465f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson if (!name.startsWith("/")) { 1466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // start with sep. 1467c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes return new URL("file", "", -1, 1468c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes new StringBuilder(name.length() + 1).append('/').append(name).toString(), null); 1469f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson } else if (name.startsWith("//")) { 1470f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson return new URL("file:" + name); // UNC path 1471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1472c903e6720bbbf6540c29f141bd2fa559813ea20aElliott Hughes return new URL("file", "", -1, name, null); 1473adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1474adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1475adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private String getAbsoluteName() { 1476adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project File f = getAbsoluteFile(); 1477adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project String name = f.getPath(); 1478adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1479adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (f.isDirectory() && name.charAt(name.length() - 1) != separatorChar) { 1480adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project // Directories must end with a slash 1481adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project name = new StringBuilder(name.length() + 1).append(name) 1482adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project .append('/').toString(); 1483adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1484adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project if (separatorChar != '/') { // Must convert slashes. 1485adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project name = name.replace(separatorChar, '/'); 1486adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1487adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project return name; 1488adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1489adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 1490adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project private void writeObject(ObjectOutputStream stream) throws IOException { 1491adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project stream.defaultWriteObject(); 1492adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project stream.writeChar(separatorChar); 1493adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 1494adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project 149508ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { 1496adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project stream.defaultReadObject(); 1497adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project char inSeparator = stream.readChar(); 149893a4b2a6cc35a72aa5a58027025f3e18c0ec2e64Elliott Hughes init(path.replace(inSeparator, separatorChar)); 1499adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project } 150008ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes 150108ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes /** 150208ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * Returns the total size in bytes of the partition containing this path. 150308ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * Returns 0 if this path does not exist. 150408ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * 150508ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * @since 1.6 150608ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes */ 150708ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes public long getTotalSpace() { 150808ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes SecurityManager security = System.getSecurityManager(); 150908ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes if (security != null) { 151008ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes security.checkPermission(new RuntimePermission("getFileSystemAttributes")); 151108ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes } 151208ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes return getTotalSpaceImpl(pathBytes); 151308ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes } 151408ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes private native long getTotalSpaceImpl(byte[] filePath); 151508ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes 151608ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes /** 151708ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * Returns the number of usable free bytes on the partition containing this path. 151808ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * Returns 0 if this path does not exist. 151908ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * 152008ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * <p>Note that this is likely to be an optimistic over-estimate and should not 152108ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * be taken as a guarantee your application can actually write this many bytes. 152208ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * On Android (and other Unix-based systems), this method returns the number of free bytes 152308ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * available to non-root users, regardless of whether you're actually running as root, 152408ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * and regardless of any quota or other restrictions that might apply to the user. 152508ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * (The {@code getFreeSpace} method returns the number of bytes potentially available to root.) 152608ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * 152708ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * @since 1.6 152808ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes */ 152908ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes public long getUsableSpace() { 153008ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes SecurityManager security = System.getSecurityManager(); 153108ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes if (security != null) { 153208ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes security.checkPermission(new RuntimePermission("getFileSystemAttributes")); 153308ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes } 153408ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes return getUsableSpaceImpl(pathBytes); 153508ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes } 153608ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes private native long getUsableSpaceImpl(byte[] filePath); 153708ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes 153808ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes /** 153908ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * Returns the number of free bytes on the partition containing this path. 154008ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * Returns 0 if this path does not exist. 154108ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * 154208ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * <p>Note that this is likely to be an optimistic over-estimate and should not 154308ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * be taken as a guarantee your application can actually write this many bytes. 154408ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * 154508ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes * @since 1.6 154608ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes */ 154708ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes public long getFreeSpace() { 154808ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes SecurityManager security = System.getSecurityManager(); 154908ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes if (security != null) { 155008ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes security.checkPermission(new RuntimePermission("getFileSystemAttributes")); 155108ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes } 155208ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes return getFreeSpaceImpl(pathBytes); 155308ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes } 155408ec8fd5c950cb94e12aefa08c89d78762acf18aElliott Hughes private native long getFreeSpaceImpl(byte[] filePath); 1555adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project} 1556