1f859444a27667fc152cdbfd25dd7a67aedeaa8c0Shubham Ajmera/* 22c87ad3a45cecf9e344487cad1abfdebe79f2c7cNarayan Kamath * Copyright (C) 2014 The Android Open Source Project 351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved. 451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is free software; you can redistribute it and/or modify it 751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * under the terms of the GNU General Public License version 2 only, as 851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * published by the Free Software Foundation. Oracle designates this 951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * particular file as subject to the "Classpath" exception as provided 1051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by Oracle in the LICENSE file that accompanied this code. 1151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This code is distributed in the hope that it will be useful, but WITHOUT 1351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * version 2 for more details (a copy is included in the LICENSE file that 1651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accompanied this code). 1751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 1851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * You should have received a copy of the GNU General Public License version 1951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2 along with this work; if not, write to the Free Software Foundation, 2051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 2251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * or visit www.oracle.com if you need additional information or have any 2451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * questions. 2551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 2651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipackage java.io; 2851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 2951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport java.nio.channels.FileChannel; 305873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath 31e31b37859051d3902e06e4ba384995df7188917fHans Boehmimport dalvik.annotation.optimization.ReachabilitySensitive; 325873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamathimport dalvik.system.BlockGuard; 339bd6371468aac3ddaa7057127d5ef152aea1227dNarayan Kamathimport dalvik.system.CloseGuard; 3451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiimport sun.nio.ch.FileChannelImpl; 3502df4b384e42969ad6f9e211989698e4f9fcde6ePrzemyslaw Szczepaniakimport libcore.io.IoBridge; 36118de16ee0529955eaca8cc5ce864cac49598c86Shubham Ajmeraimport libcore.io.IoTracker; 3751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 3851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski/** 3951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * A file output stream is an output stream for writing data to a 4051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>File</code> or to a <code>FileDescriptor</code>. Whether or not 4151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * a file is available or may be created depends upon the underlying 4251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * platform. Some platforms, in particular, allow a file to be opened 4351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * for writing by only one <tt>FileOutputStream</tt> (or other 4451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * file-writing object) at a time. In such situations the constructors in 4551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * this class will fail if the file involved is already open. 4651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 4751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p><code>FileOutputStream</code> is meant for writing streams of raw bytes 4851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * such as image data. For writing streams of characters, consider using 4951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>FileWriter</code>. 5051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 5151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @author Arthur van Hoff 5251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.io.File 5351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.io.FileDescriptor 5451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.io.FileInputStream 5551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.nio.file.Files#newOutputStream 5651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since JDK1.0 5751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 5851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskipublic 5951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebskiclass FileOutputStream extends OutputStream 6051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski{ 6151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 6251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * The system dependent file descriptor. 6351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 64e31b37859051d3902e06e4ba384995df7188917fHans Boehm // Android-added: @ReachabilitySensitive 65e31b37859051d3902e06e4ba384995df7188917fHans Boehm @ReachabilitySensitive 66e59e4c9b59318851e4366ecc732db45ac9e061b0Yi Kong private final FileDescriptor fd; 6751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 6851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 6951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * True if the file is opened for append. 7051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 7151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private final boolean append; 7251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 7351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 744c36dc077823b9fe42a30e09672613d154292628Przemyslaw Szczepaniak * The associated channel, initialized lazily. 7551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 7651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski private FileChannel channel; 7751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 784c36dc077823b9fe42a30e09672613d154292628Przemyslaw Szczepaniak /** 794c36dc077823b9fe42a30e09672613d154292628Przemyslaw Szczepaniak * The path of the referenced file 804c36dc077823b9fe42a30e09672613d154292628Przemyslaw Szczepaniak * (null if the stream is created with a file descriptor) 814c36dc077823b9fe42a30e09672613d154292628Przemyslaw Szczepaniak */ 824c36dc077823b9fe42a30e09672613d154292628Przemyslaw Szczepaniak private final String path; 834c36dc077823b9fe42a30e09672613d154292628Przemyslaw Szczepaniak 84c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller private final Object closeLock = new Object(); 85c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller private volatile boolean closed = false; 86c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller 87c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller // Android-added: CloseGuard support: Log if the stream is not closed. 88e31b37859051d3902e06e4ba384995df7188917fHans Boehm @ReachabilitySensitive 899bd6371468aac3ddaa7057127d5ef152aea1227dNarayan Kamath private final CloseGuard guard = CloseGuard.get(); 90c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller 91c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller // Android-added: Field for tracking whether the stream owns the underlying FileDescriptor. 92b5738be1ca73734ab71a62b537e67bcbbf502f09Przemyslaw Szczepaniak private final boolean isFdOwner; 93c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller 94c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller // Android-added: Tracking of unbuffered I/O. 95118de16ee0529955eaca8cc5ce864cac49598c86Shubham Ajmera private final IoTracker tracker = new IoTracker(); 969bd6371468aac3ddaa7057127d5ef152aea1227dNarayan Kamath 9751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 9851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Creates a file output stream to write to the file with the 9951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * specified name. A new <code>FileDescriptor</code> object is 10051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * created to represent this file connection. 10151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 10251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * First, if there is a security manager, its <code>checkWrite</code> 10351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * method is called with <code>name</code> as its argument. 10451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 10551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * If the file exists but is a directory rather than a regular file, does 10651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * not exist but cannot be created, or cannot be opened for any other 10751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * reason then a <code>FileNotFoundException</code> is thrown. 10851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 10951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param name the system-dependent filename 11051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception FileNotFoundException if the file exists but is a directory 11151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * rather than a regular file, does not exist but cannot 11251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * be created, or cannot be opened for any other reason 11351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception SecurityException if a security manager exists and its 11451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>checkWrite</code> method denies write access 11551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * to the file. 11651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.lang.SecurityManager#checkWrite(java.lang.String) 11751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 11851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public FileOutputStream(String name) throws FileNotFoundException { 11951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this(name != null ? new File(name) : null, false); 12051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 12151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 12251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 12351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Creates a file output stream to write to the file with the specified 12451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * name. If the second argument is <code>true</code>, then 12551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * bytes will be written to the end of the file rather than the beginning. 12651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * A new <code>FileDescriptor</code> object is created to represent this 12751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * file connection. 12851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 12951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * First, if there is a security manager, its <code>checkWrite</code> 13051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * method is called with <code>name</code> as its argument. 13151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 13251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * If the file exists but is a directory rather than a regular file, does 13351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * not exist but cannot be created, or cannot be opened for any other 13451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * reason then a <code>FileNotFoundException</code> is thrown. 13551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 13651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param name the system-dependent file name 13751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param append if <code>true</code>, then bytes will be written 13851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * to the end of the file rather than the beginning 13951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception FileNotFoundException if the file exists but is a directory 14051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * rather than a regular file, does not exist but cannot 14151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * be created, or cannot be opened for any other reason. 14251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception SecurityException if a security manager exists and its 14351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>checkWrite</code> method denies write access 14451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * to the file. 14551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.lang.SecurityManager#checkWrite(java.lang.String) 14651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since JDK1.1 14751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 14851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public FileOutputStream(String name, boolean append) 14951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws FileNotFoundException 15051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 15151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this(name != null ? new File(name) : null, append); 15251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 15351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 15451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 15551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Creates a file output stream to write to the file represented by 15651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the specified <code>File</code> object. A new 15751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>FileDescriptor</code> object is created to represent this 15851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * file connection. 15951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 16051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * First, if there is a security manager, its <code>checkWrite</code> 16151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * method is called with the path represented by the <code>file</code> 16251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * argument as its argument. 16351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 16451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * If the file exists but is a directory rather than a regular file, does 16551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * not exist but cannot be created, or cannot be opened for any other 16651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * reason then a <code>FileNotFoundException</code> is thrown. 16751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 16851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param file the file to be opened for writing. 16951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception FileNotFoundException if the file exists but is a directory 17051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * rather than a regular file, does not exist but cannot 17151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * be created, or cannot be opened for any other reason 17251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception SecurityException if a security manager exists and its 17351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>checkWrite</code> method denies write access 17451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * to the file. 17551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.io.File#getPath() 17651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.lang.SecurityException 17751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.lang.SecurityManager#checkWrite(java.lang.String) 17851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 17951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public FileOutputStream(File file) throws FileNotFoundException { 18051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this(file, false); 18151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 18251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 18351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 18451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Creates a file output stream to write to the file represented by 18551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the specified <code>File</code> object. If the second argument is 18651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>true</code>, then bytes will be written to the end of the file 18751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * rather than the beginning. A new <code>FileDescriptor</code> object is 18851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * created to represent this file connection. 18951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 19051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * First, if there is a security manager, its <code>checkWrite</code> 19151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * method is called with the path represented by the <code>file</code> 19251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * argument as its argument. 19351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 19451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * If the file exists but is a directory rather than a regular file, does 19551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * not exist but cannot be created, or cannot be opened for any other 19651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * reason then a <code>FileNotFoundException</code> is thrown. 19751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 19851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param file the file to be opened for writing. 19951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param append if <code>true</code>, then bytes will be written 20051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * to the end of the file rather than the beginning 20151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception FileNotFoundException if the file exists but is a directory 20251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * rather than a regular file, does not exist but cannot 20351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * be created, or cannot be opened for any other reason 20451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception SecurityException if a security manager exists and its 20551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>checkWrite</code> method denies write access 20651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * to the file. 20751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.io.File#getPath() 20851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.lang.SecurityException 20951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.lang.SecurityManager#checkWrite(java.lang.String) 21051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since 1.4 21151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 21251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public FileOutputStream(File file, boolean append) 21351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws FileNotFoundException 21451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski { 21551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski String name = (file != null ? file.getPath() : null); 21651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski SecurityManager security = System.getSecurityManager(); 21751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (security != null) { 21851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski security.checkWrite(name); 21951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 22051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (name == null) { 22151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new NullPointerException(); 22251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 22351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (file.isInvalid()) { 22451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new FileNotFoundException("Invalid file path"); 22551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 22651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.fd = new FileDescriptor(); 227c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller 228c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller // Android-changed: Tracking mechanism for FileDescriptor sharing. 229c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller // fd.attach(this); 230c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller this.isFdOwner = true; 231c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller 23251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.append = append; 23351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.path = name; 2345873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath 235c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller // Android-added: BlockGuard support. 2365873edf853a48362e8ee4e75181f654d0b88b8efNarayan Kamath BlockGuard.getThreadPolicy().onWriteToDisk(); 237c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller 23851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski open(name, append); 239c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller 240c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller // Android-added: CloseGuard support. 2419bd6371468aac3ddaa7057127d5ef152aea1227dNarayan Kamath guard.open("close"); 24251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 24351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 244c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller // Android-removed: Documentation around SecurityException. Not thrown on Android. 24551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 24651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Creates a file output stream to write to the specified file 24751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * descriptor, which represents an existing connection to an actual 24851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * file in the file system. 24951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 25051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * First, if there is a security manager, its <code>checkWrite</code> 25151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * method is called with the file descriptor <code>fdObj</code> 25251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * argument as its argument. 25351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 25451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * If <code>fdObj</code> is null then a <code>NullPointerException</code> 25551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * is thrown. 25651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> 25751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * This constructor does not throw an exception if <code>fdObj</code> 25851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * is {@link java.io.FileDescriptor#valid() invalid}. 25951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * However, if the methods are invoked on the resulting stream to attempt 26051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * I/O on the stream, an <code>IOException</code> is thrown. 26151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 26251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param fdObj the file descriptor to be opened for writing 26351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 26451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public FileOutputStream(FileDescriptor fdObj) { 265c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller // Android-changed: Delegate to added hidden constructor. 266e9d215bb0811633791ca53199922a8d5512de224Narayan Kamath this(fdObj, false /* isOwner */); 267e9d215bb0811633791ca53199922a8d5512de224Narayan Kamath } 268e9d215bb0811633791ca53199922a8d5512de224Narayan Kamath 269c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller // Android-added: Internal/hidden constructor for specifying FileDescriptor ownership. 270c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller // Android-removed: SecurityManager calls. 271e9d215bb0811633791ca53199922a8d5512de224Narayan Kamath /** 272e9d215bb0811633791ca53199922a8d5512de224Narayan Kamath * Internal constructor for {@code FileOutputStream} objects where the file descriptor 273e9d215bb0811633791ca53199922a8d5512de224Narayan Kamath * is owned by this tream. 274e9d215bb0811633791ca53199922a8d5512de224Narayan Kamath * 275e9d215bb0811633791ca53199922a8d5512de224Narayan Kamath * @hide 276e9d215bb0811633791ca53199922a8d5512de224Narayan Kamath */ 277e9d215bb0811633791ca53199922a8d5512de224Narayan Kamath public FileOutputStream(FileDescriptor fdObj, boolean isFdOwner) { 27851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (fdObj == null) { 279c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller // Android-changed: Improved NullPointerException message. 280e9d215bb0811633791ca53199922a8d5512de224Narayan Kamath throw new NullPointerException("fdObj == null"); 28151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 282e9d215bb0811633791ca53199922a8d5512de224Narayan Kamath 28351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.fd = fdObj; 28451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski this.append = false; 285c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller this.path = null; 286c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller 287c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller // Android-changed: FileDescriptor ownership tracking mechanism. 288c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller // fd.attach(this); 289b5738be1ca73734ab71a62b537e67bcbbf502f09Przemyslaw Szczepaniak this.isFdOwner = isFdOwner; 29051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 29151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 29251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 29351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Opens a file, with the specified name, for overwriting or appending. 29451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param name name of file to be opened 29551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param append whether the file is to be opened in append mode 29651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 2974c36dc077823b9fe42a30e09672613d154292628Przemyslaw Szczepaniak private native void open0(String name, boolean append) 29851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throws FileNotFoundException; 29951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 3004c36dc077823b9fe42a30e09672613d154292628Przemyslaw Szczepaniak // wrap native call to allow instrumentation 3014c36dc077823b9fe42a30e09672613d154292628Przemyslaw Szczepaniak /** 3024c36dc077823b9fe42a30e09672613d154292628Przemyslaw Szczepaniak * Opens a file, with the specified name, for overwriting or appending. 3034c36dc077823b9fe42a30e09672613d154292628Przemyslaw Szczepaniak * @param name name of file to be opened 3044c36dc077823b9fe42a30e09672613d154292628Przemyslaw Szczepaniak * @param append whether the file is to be opened in append mode 3054c36dc077823b9fe42a30e09672613d154292628Przemyslaw Szczepaniak */ 3064c36dc077823b9fe42a30e09672613d154292628Przemyslaw Szczepaniak private void open(String name, boolean append) 3074c36dc077823b9fe42a30e09672613d154292628Przemyslaw Szczepaniak throws FileNotFoundException { 3084c36dc077823b9fe42a30e09672613d154292628Przemyslaw Szczepaniak open0(name, append); 3094c36dc077823b9fe42a30e09672613d154292628Przemyslaw Szczepaniak } 3104c36dc077823b9fe42a30e09672613d154292628Przemyslaw Szczepaniak 311c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller // Android-removed: write(int, boolean), use IoBridge instead. 312c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller /* 313c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller /** 314c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller * Writes the specified byte to this file output stream. 315c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller * 316c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller * @param b the byte to be written. 317c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller * @param append {@code true} if the write operation first 318c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller * advances the position to the end of file 319c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller * 320c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller private native void write(int b, boolean append) throws IOException; 321c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller */ 322c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller 32351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 32451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Writes the specified byte to this file output stream. Implements 32551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the <code>write</code> method of <code>OutputStream</code>. 32651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 32751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param b the byte to be written. 32851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception IOException if an I/O error occurs. 32951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 33051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void write(int b) throws IOException { 331c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller // Android-changed: Write methods delegate to write(byte[],int,int) to share Android logic. 33202df4b384e42969ad6f9e211989698e4f9fcde6ePrzemyslaw Szczepaniak write(new byte[] { (byte) b }, 0, 1); 33351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 33451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 335c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller // Android-removed: Write methods delegate to write(byte[],int,int) to share Android logic. 336c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller /* 337c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller /** 338c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller * Writes a sub array as a sequence of bytes. 339c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller * @param b the data to be written 340c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller * @param off the start offset in the data 341c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller * @param len the number of bytes that are written 342c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller * @param append {@code true} to first advance the position to the 343c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller * end of file 344c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller * @exception IOException If an I/O error has occurred. 345c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller * 346c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller private native void writeBytes(byte b[], int off, int len, boolean append) 347c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller throws IOException; 348c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller */ 349c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller 35051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 35151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Writes <code>b.length</code> bytes from the specified byte array 35251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * to this file output stream. 35351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 35451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param b the data. 35551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception IOException if an I/O error occurs. 35651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 35751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void write(byte b[]) throws IOException { 358c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller // Android-changed: Write methods delegate to write(byte[],int,int) to share Android logic. 35902df4b384e42969ad6f9e211989698e4f9fcde6ePrzemyslaw Szczepaniak write(b, 0, b.length); 36051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 36151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 36251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 36351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Writes <code>len</code> bytes from the specified byte array 36451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * starting at offset <code>off</code> to this file output stream. 36551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 36651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param b the data. 36751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param off the start offset in the data. 36851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @param len the number of bytes to write. 36951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception IOException if an I/O error occurs. 37051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 37151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void write(byte b[], int off, int len) throws IOException { 372c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller // Android-added: close() check before I/O. 37350164c3602af46021e434ff5047352299a36e0f0Yi Kong if (closed && len > 0) { 37450164c3602af46021e434ff5047352299a36e0f0Yi Kong throw new IOException("Stream Closed"); 37550164c3602af46021e434ff5047352299a36e0f0Yi Kong } 376c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller 377c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller // Android-added: Tracking of unbuffered I/O. 378118de16ee0529955eaca8cc5ce864cac49598c86Shubham Ajmera tracker.trackIo(len); 379c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller 380c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller // Android-changed: Use IoBridge instead of calling native method. 381118de16ee0529955eaca8cc5ce864cac49598c86Shubham Ajmera IoBridge.write(fd, b, off, len); 38251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 38351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 38451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 38551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Closes this file output stream and releases any system resources 38651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * associated with this stream. This file output stream may no longer 38751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * be used for writing bytes. 38851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 38951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> If this stream has an associated channel then the channel is closed 39051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * as well. 39151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 39251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception IOException if an I/O error occurs. 39351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 39451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @revised 1.4 39551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @spec JSR-51 39651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 39751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public void close() throws IOException { 39851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (closeLock) { 39951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (closed) { 40051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return; 40151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 40251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski closed = true; 40351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 40451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 405c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller // Android-added: CloseGuard support. 4069bd6371468aac3ddaa7057127d5ef152aea1227dNarayan Kamath guard.close(); 4079bd6371468aac3ddaa7057127d5ef152aea1227dNarayan Kamath 40851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (channel != null) { 40951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski channel.close(); 41051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 41151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 412c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller // BEGIN Android-changed: Close handling / notification of blocked threads. 413b5738be1ca73734ab71a62b537e67bcbbf502f09Przemyslaw Szczepaniak if (isFdOwner) { 41402df4b384e42969ad6f9e211989698e4f9fcde6ePrzemyslaw Szczepaniak IoBridge.closeAndSignalBlockedThreads(fd); 41551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 416c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller // END Android-changed: Close handling / notification of blocked threads. 41751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 41851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 41951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 42051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns the file descriptor associated with this stream. 42151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 42251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the <code>FileDescriptor</code> object that represents 42351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * the connection to the file in the file system being used 42451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * by this <code>FileOutputStream</code> object. 42551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 42651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception IOException if an I/O error occurs. 42751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.io.FileDescriptor 42851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 429e31b37859051d3902e06e4ba384995df7188917fHans Boehm // Android-added: @ReachabilitySensitive 430e31b37859051d3902e06e4ba384995df7188917fHans Boehm @ReachabilitySensitive 43151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public final FileDescriptor getFD() throws IOException { 4324c36dc077823b9fe42a30e09672613d154292628Przemyslaw Szczepaniak if (fd != null) { 4334c36dc077823b9fe42a30e09672613d154292628Przemyslaw Szczepaniak return fd; 4344c36dc077823b9fe42a30e09672613d154292628Przemyslaw Szczepaniak } 43551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski throw new IOException(); 43651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 43751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 43851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 43951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Returns the unique {@link java.nio.channels.FileChannel FileChannel} 4404c36dc077823b9fe42a30e09672613d154292628Przemyslaw Szczepaniak * object associated with this file output stream. 44151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 44251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <p> The initial {@link java.nio.channels.FileChannel#position() 4434c36dc077823b9fe42a30e09672613d154292628Przemyslaw Szczepaniak * position} of the returned channel will be equal to the 44451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * number of bytes written to the file so far unless this stream is in 44551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * append mode, in which case it will be equal to the size of the file. 44651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Writing bytes to this stream will increment the channel's position 44751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * accordingly. Changing the channel's position, either explicitly or by 44851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * writing, will change this stream's file position. 44951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 45051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @return the file channel associated with this file output stream 45151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 45251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @since 1.4 45351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @spec JSR-51 45451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 45551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski public FileChannel getChannel() { 45651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski synchronized (this) { 45751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (channel == null) { 45851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski channel = FileChannelImpl.open(fd, path, false, true, append, this); 45951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 46051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski return channel; 46151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 46251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 46351b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski 46451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski /** 46551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * Cleans up the connection to the file, and ensures that the 46651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * <code>close</code> method of this file output stream is 46751b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * called when there are no more references to this stream. 46851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * 46951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @exception IOException if an I/O error occurs. 47051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski * @see java.io.FileInputStream#close() 47151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski */ 47251b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski protected void finalize() throws IOException { 473c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller // Android-added: CloseGuard support. 4749bd6371468aac3ddaa7057127d5ef152aea1227dNarayan Kamath if (guard != null) { 4759bd6371468aac3ddaa7057127d5ef152aea1227dNarayan Kamath guard.warnIfOpen(); 4769bd6371468aac3ddaa7057127d5ef152aea1227dNarayan Kamath } 4779bd6371468aac3ddaa7057127d5ef152aea1227dNarayan Kamath 47851b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (fd != null) { 47951b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski if (fd == FileDescriptor.out || fd == FileDescriptor.err) { 48051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski flush(); 48151b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } else { 482c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller // Android-removed: Obsoleted comment about shared FileDescriptor handling. 4839c3a641e294abdaadda9299a2e1b49863de45ed9Narayan Kamath close(); 48451b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 48551b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 48651b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski } 487c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller 488c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller // BEGIN Android-removed: Unused code. 489c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller /* 490c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller private native void close0() throws IOException; 491c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller 492c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller private static native void initIDs(); 493c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller 494c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller static { 495c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller initIDs(); 496c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller } 497c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller */ 498c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller // END Android-removed: Unused code. 499c52f3fe3ba9e1d31e27c06f45bfc44c2aa8a8f96Neil Fuller 50051b1b6997fd3f980076b8081f7f1165ccc2a4008Piotr Jastrzebski} 501