FileOutputStream.java revision f5597e626ecf7949d249dea08c1a2964d890ec11
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
18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.io;
19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.nio.channels.FileChannel;
21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.luni.platform.IFileSystem;
23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.luni.platform.Platform;
24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.luni.util.Msg;
25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport org.apache.harmony.nio.FileChannelFactory;
26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * A specialized {@link OutputStream} that writes to a file in the file system.
29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * All write requests made by calling methods in this class are directly
30adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * forwarded to the equivalent function of the underlying operating system.
31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Since this may induce some performance penalty, in particular if many small
32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * write requests are made, a FileOutputStream is often wrapped by a
33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * BufferedOutputStream.
34f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson *
35adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see BufferedOutputStream
36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @see FileInputStream
37f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson *
38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @since Android 1.0
39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class FileOutputStream extends OutputStream implements Closeable {
41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
42adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The FileDescriptor representing this FileOutputStream.
44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    FileDescriptor fd;
46adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    boolean innerFD;
48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // The unique file channel associated with this FileInputStream (lazily
50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // initialized).
51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private FileChannel channel;
52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private IFileSystem fileSystem = Platform.getFileSystem();
54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Constructs a new FileOutputStream on the File {@code file}. If the file
57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * exists, it is overwritten.
58f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param file
60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the file to which this stream writes.
61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws FileNotFoundException
62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code file} cannot be opened for writing.
63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SecurityException
64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if a {@code SecurityManager} is installed and it denies the
65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             write request.
66f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @see java.lang.SecurityManager#checkWrite(FileDescriptor)
67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public FileOutputStream(File file) throws FileNotFoundException {
69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this(file, false);
70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Constructs a new FileOutputStream on the File {@code file}. The
74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * parameter {@code append} determines whether or not the file is opened and
75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * appended to or just opened and overwritten.
76f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
77adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param file
78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the file to which this stream writes.
79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param append
80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            indicates whether or not to append to an existing file.
81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws FileNotFoundException
82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the {@code file} cannot be opened for writing.
83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SecurityException
84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if a {@code SecurityManager} is installed and it denies the
85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             write request.
86f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @see java.lang.SecurityManager#checkWrite(FileDescriptor)
87f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @see java.lang.SecurityManager#checkWrite(String)
88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public FileOutputStream(File file, boolean append)
90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws FileNotFoundException {
91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        super();
92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        SecurityManager security = System.getSecurityManager();
93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (security != null) {
94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            security.checkWrite(file.getPath());
95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        fd = new FileDescriptor();
97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        fd.descriptor = fileSystem.open(file.properPath(true),
98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                append ? IFileSystem.O_APPEND : IFileSystem.O_WRONLY);
99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        innerFD = true;
100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        channel = FileChannelFactory.getFileChannel(this, fd.descriptor,
101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                append ? IFileSystem.O_APPEND : IFileSystem.O_WRONLY);
102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Constructs a new FileOutputStream on the FileDescriptor {@code fd}. The
106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * file must already be open, therefore no {@code FileNotFoundException}
107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * will be thrown.
108f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param fd
110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the FileDescriptor to which this stream writes.
111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NullPointerException
112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code fd} is {@code null}.
113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SecurityException
114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if a {@code SecurityManager} is installed and it denies the
115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             write request.
116f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @see java.lang.SecurityManager#checkWrite(FileDescriptor)
117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public FileOutputStream(FileDescriptor fd) {
119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        super();
120adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (fd == null) {
121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new NullPointerException(Msg.getString("K006c")); //$NON-NLS-1$
122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        SecurityManager security = System.getSecurityManager();
124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (security != null) {
125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            security.checkWrite(fd);
126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.fd = fd;
128adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        innerFD = false;
129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        channel = FileChannelFactory.getFileChannel(this, fd.descriptor,
130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                IFileSystem.O_WRONLY);
131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
132adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
134adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Constructs a new FileOutputStream on the file named {@code filename}. If
135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * the file exists, it is overwritten. The {@code filename} may be absolute
136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * or relative to the system property {@code "user.dir"}.
137f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param filename
139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the name of the file to which this stream writes.
140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws FileNotFoundException
141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the file cannot be opened for writing.
142adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SecurityException
143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if a {@code SecurityManager} is installed and it denies the
144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             write request.
145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
146adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public FileOutputStream(String filename) throws FileNotFoundException {
147adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this(filename, false);
148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
150adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Constructs a new FileOutputStream on the file named {@code filename}.
152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The parameter {@code append} determines whether or not the file is opened
153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * and appended to or just opened and overwritten. The {@code filename} may
154adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * be absolute or relative to the system property {@code "user.dir"}.
155f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param filename
157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the name of the file to which this stream writes.
158f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     * @param append
159f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *            indicates whether or not to append to an existing file.
160adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws FileNotFoundException
161adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if the file cannot be opened for writing.
162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws SecurityException
163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if a {@code SecurityManager} is installed and it denies the
164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             write request.
165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
166adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public FileOutputStream(String filename, boolean append)
167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throws FileNotFoundException {
168adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this(new File(filename), append);
169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
170adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Closes this stream. This implementation closes the underlying operating
173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * system resources allocated to represent this stream.
174f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
175adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs attempting to close this stream.
177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
178adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void close() throws IOException {
180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (fd == null) {
181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // if fd is null, then the underlying file is not opened, so nothing
182adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // to close
183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return;
184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
186adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (channel != null) {
187adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            synchronized (channel) {
188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                if (channel.isOpen() && fd.descriptor >= 0) {
189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    channel.close();
190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                }
191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
194adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        synchronized (this) {
195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (fd.descriptor >= 0 && innerFD) {
196adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                fileSystem.close(fd.descriptor);
197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                fd.descriptor = -1;
198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
200adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Frees any resources allocated for this stream before it is garbage
204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * collected. This method is called from the Java Virtual Machine.
205f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs attempting to finalize this stream.
208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    protected void finalize() throws IOException {
211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        close();
212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
214adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns the FileChannel equivalent to this output stream.
216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * <p>
217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * The file channel is write-only and has an initial position within the
218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * file that is the same as the current position of this stream within the
219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * file. All changes made to the underlying file descriptor state via the
220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * channel are visible by the output stream and vice versa.
221f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return the file channel representation for this stream.
223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public FileChannel getChannel() {
225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return channel;
226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Returns a FileDescriptor which represents the lowest level representation
230adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * of an operating system stream resource.
231f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @return a FileDescriptor representing this stream.
233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if an error occurs attempting to get the FileDescriptor of
235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             this stream.
236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public final FileDescriptor getFD() throws IOException {
238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return fd;
239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Writes the entire contents of the byte array {@code buffer} to this
243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * stream.
244f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param buffer
246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the buffer to be written to the file.
247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if this stream is closed or an error occurs attempting to
249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             write to this stream.
250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void write(byte[] buffer) throws IOException {
253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        write(buffer, 0, buffer.length);
254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Writes {@code count} bytes from the byte array {@code buffer} starting at
258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * {@code offset} to this stream.
259f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param buffer
261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the buffer to write to this stream.
262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param offset
263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the index of the first byte in {@code buffer} to write.
264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param count
265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the number of bytes from {@code buffer} to write.
266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IndexOutOfBoundsException
267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code count < 0} or {@code offset < 0}, or if
268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             {@code count + offset} is greater than the length of
269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             {@code buffer}.
270adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if this stream is closed or an error occurs attempting to
272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             write to this stream.
273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws NullPointerException
274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if {@code buffer} is {@code null}.
275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void write(byte[] buffer, int offset, int count) throws IOException {
278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // BEGIN android-changed
279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Exception priorities (in case of multiple errors) differ from
280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // RI, but are spec-compliant.
281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // removed redundant check, made implicit null check explicit,
282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // used (offset | count) < 0 instead of (offset < 0) || (count < 0)
283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // to safe one operation
284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (buffer == null) {
285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new NullPointerException(Msg.getString("K0047")); //$NON-NLS-1$
286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if ((count | offset) < 0 || count > buffer.length - offset) {
288adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new IndexOutOfBoundsException(Msg.getString("K002f")); //$NON-NLS-1$
289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // END android-changed
291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (count == 0) {
293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return;
294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        openCheck();
297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        fileSystem.write(fd.descriptor, buffer, offset, count);
298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Writes the specified byte {@code oneByte} to this stream. Only the low
302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * order byte of the integer {@code oneByte} is written.
303f5597e626ecf7949d249dea08c1a2964d890ec11Jesse Wilson     *
304adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param oneByte
305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *            the byte to be written.
306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @throws IOException
307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             if this stream is closed an error occurs attempting to write
308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     *             to this stream.
309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    @Override
311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public void write(int oneByte) throws IOException {
312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        openCheck();
313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        byte[] byteArray = new byte[1];
314adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        byteArray[0] = (byte) oneByte;
315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        fileSystem.write(fd.descriptor, byteArray, 0, 1);
316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private synchronized void openCheck() throws IOException {
319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (fd.descriptor < 0) {
320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new IOException();
321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
324