199a89dd6f0a0e1396aa9b3feebf15ea31f703d3aElliott Hughes/* 299a89dd6f0a0e1396aa9b3feebf15ea31f703d3aElliott Hughes * Copyright (C) 2010 The Android Open Source Project 399a89dd6f0a0e1396aa9b3feebf15ea31f703d3aElliott Hughes * 499a89dd6f0a0e1396aa9b3feebf15ea31f703d3aElliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 599a89dd6f0a0e1396aa9b3feebf15ea31f703d3aElliott Hughes * you may not use this file except in compliance with the License. 699a89dd6f0a0e1396aa9b3feebf15ea31f703d3aElliott Hughes * You may obtain a copy of the License at 799a89dd6f0a0e1396aa9b3feebf15ea31f703d3aElliott Hughes * 899a89dd6f0a0e1396aa9b3feebf15ea31f703d3aElliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 999a89dd6f0a0e1396aa9b3feebf15ea31f703d3aElliott Hughes * 1099a89dd6f0a0e1396aa9b3feebf15ea31f703d3aElliott Hughes * Unless required by applicable law or agreed to in writing, software 1199a89dd6f0a0e1396aa9b3feebf15ea31f703d3aElliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 1299a89dd6f0a0e1396aa9b3feebf15ea31f703d3aElliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1399a89dd6f0a0e1396aa9b3feebf15ea31f703d3aElliott Hughes * See the License for the specific language governing permissions and 1499a89dd6f0a0e1396aa9b3feebf15ea31f703d3aElliott Hughes * limitations under the License. 1599a89dd6f0a0e1396aa9b3feebf15ea31f703d3aElliott Hughes */ 1699a89dd6f0a0e1396aa9b3feebf15ea31f703d3aElliott Hughes 1799a89dd6f0a0e1396aa9b3feebf15ea31f703d3aElliott Hughespackage libcore.io; 1899a89dd6f0a0e1396aa9b3feebf15ea31f703d3aElliott Hughes 19433e3fac172d0c4449051b0c61c0c63b298a0903Jesse Wilsonimport java.io.File; 2099a89dd6f0a0e1396aa9b3feebf15ea31f703d3aElliott Hughesimport java.io.FileDescriptor; 21c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamathimport java.io.FileNotFoundException; 2299a89dd6f0a0e1396aa9b3feebf15ea31f703d3aElliott Hughesimport java.io.IOException; 239726be51ed6f9695357bc8f11a547d9beaa79fceBrian Carlstromimport java.io.InterruptedIOException; 24a7a70410e26802f3ab480b08a1ab499338cb6f7eJesse Wilsonimport java.net.Socket; 25c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamathimport java.nio.charset.Charset; 262a6f23ff8690ac2f025588a360547ce96cde0943Elliott Hughesimport java.nio.charset.StandardCharsets; 274f97bfe0d9e6f4bdb43fff91f341f4722af16301Elliott Hughesimport java.util.Random; 280ac77ac8e915bff1a863e371f9b363033f9cf759Elliott Hughesimport static libcore.io.OsConstants.*; 2999a89dd6f0a0e1396aa9b3feebf15ea31f703d3aElliott Hughes 3099a89dd6f0a0e1396aa9b3feebf15ea31f703d3aElliott Hughespublic final class IoUtils { 314f97bfe0d9e6f4bdb43fff91f341f4722af16301Elliott Hughes private static final Random TEMPORARY_DIRECTORY_PRNG = new Random(); 324f97bfe0d9e6f4bdb43fff91f341f4722af16301Elliott Hughes 3399a89dd6f0a0e1396aa9b3feebf15ea31f703d3aElliott Hughes private IoUtils() { 3499a89dd6f0a0e1396aa9b3feebf15ea31f703d3aElliott Hughes } 3599a89dd6f0a0e1396aa9b3feebf15ea31f703d3aElliott Hughes 3699a89dd6f0a0e1396aa9b3feebf15ea31f703d3aElliott Hughes /** 37e8fad0e2a8787fd46654d1cc9e477b353a958451Elliott Hughes * Calls close(2) on 'fd'. Also resets the internal int to -1. Does nothing if 'fd' is null 38e8fad0e2a8787fd46654d1cc9e477b353a958451Elliott Hughes * or invalid. 3999a89dd6f0a0e1396aa9b3feebf15ea31f703d3aElliott Hughes */ 40462bdac45c10f43d88d8f07f6994e272a27c14a2Elliott Hughes public static void close(FileDescriptor fd) throws IOException { 41462bdac45c10f43d88d8f07f6994e272a27c14a2Elliott Hughes try { 42462bdac45c10f43d88d8f07f6994e272a27c14a2Elliott Hughes if (fd != null && fd.valid()) { 43462bdac45c10f43d88d8f07f6994e272a27c14a2Elliott Hughes Libcore.os.close(fd); 44462bdac45c10f43d88d8f07f6994e272a27c14a2Elliott Hughes } 45462bdac45c10f43d88d8f07f6994e272a27c14a2Elliott Hughes } catch (ErrnoException errnoException) { 46462bdac45c10f43d88d8f07f6994e272a27c14a2Elliott Hughes throw errnoException.rethrowAsIOException(); 47462bdac45c10f43d88d8f07f6994e272a27c14a2Elliott Hughes } 48462bdac45c10f43d88d8f07f6994e272a27c14a2Elliott Hughes } 4999a89dd6f0a0e1396aa9b3feebf15ea31f703d3aElliott Hughes 5099a89dd6f0a0e1396aa9b3feebf15ea31f703d3aElliott Hughes /** 519b510df35b57946d843ffc34cf23fdcfc84c5220Elliott Hughes * Closes 'closeable', ignoring any checked exceptions. Does nothing if 'closeable' is null. 52f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes */ 539b510df35b57946d843ffc34cf23fdcfc84c5220Elliott Hughes public static void closeQuietly(AutoCloseable closeable) { 54f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes if (closeable != null) { 55f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes try { 56f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes closeable.close(); 579b510df35b57946d843ffc34cf23fdcfc84c5220Elliott Hughes } catch (RuntimeException rethrown) { 589b510df35b57946d843ffc34cf23fdcfc84c5220Elliott Hughes throw rethrown; 599b510df35b57946d843ffc34cf23fdcfc84c5220Elliott Hughes } catch (Exception ignored) { 60f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes } 61f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes } 62f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes } 63f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes 64f14cadb15b06371fb9a6daf885dc1c4bccf975b9Elliott Hughes /** 65e8fad0e2a8787fd46654d1cc9e477b353a958451Elliott Hughes * Closes 'fd', ignoring any exceptions. Does nothing if 'fd' is null or invalid. 66e8fad0e2a8787fd46654d1cc9e477b353a958451Elliott Hughes */ 67e8fad0e2a8787fd46654d1cc9e477b353a958451Elliott Hughes public static void closeQuietly(FileDescriptor fd) { 68e8fad0e2a8787fd46654d1cc9e477b353a958451Elliott Hughes try { 69e8fad0e2a8787fd46654d1cc9e477b353a958451Elliott Hughes IoUtils.close(fd); 70e8fad0e2a8787fd46654d1cc9e477b353a958451Elliott Hughes } catch (IOException ignored) { 71e8fad0e2a8787fd46654d1cc9e477b353a958451Elliott Hughes } 72e8fad0e2a8787fd46654d1cc9e477b353a958451Elliott Hughes } 73e8fad0e2a8787fd46654d1cc9e477b353a958451Elliott Hughes 74e8fad0e2a8787fd46654d1cc9e477b353a958451Elliott Hughes /** 75a7a70410e26802f3ab480b08a1ab499338cb6f7eJesse Wilson * Closes 'socket', ignoring any exceptions. Does nothing if 'socket' is null. 76a7a70410e26802f3ab480b08a1ab499338cb6f7eJesse Wilson */ 77a7a70410e26802f3ab480b08a1ab499338cb6f7eJesse Wilson public static void closeQuietly(Socket socket) { 78a7a70410e26802f3ab480b08a1ab499338cb6f7eJesse Wilson if (socket != null) { 79a7a70410e26802f3ab480b08a1ab499338cb6f7eJesse Wilson try { 80a7a70410e26802f3ab480b08a1ab499338cb6f7eJesse Wilson socket.close(); 81a7a70410e26802f3ab480b08a1ab499338cb6f7eJesse Wilson } catch (Exception ignored) { 82a7a70410e26802f3ab480b08a1ab499338cb6f7eJesse Wilson } 83a7a70410e26802f3ab480b08a1ab499338cb6f7eJesse Wilson } 84a7a70410e26802f3ab480b08a1ab499338cb6f7eJesse Wilson } 85a7a70410e26802f3ab480b08a1ab499338cb6f7eJesse Wilson 86220c0af1763283b75617226efe3919c3e3b044c8Elliott Hughes /** 87440ba565fa5384bc23255fbc412f7b97fcbdccd9Elliott Hughes * Sets 'fd' to be blocking or non-blocking, according to the state of 'blocking'. 8899a89dd6f0a0e1396aa9b3feebf15ea31f703d3aElliott Hughes */ 89fc549a0b0388987b26dea524894d75a63d14783bElliott Hughes public static void setBlocking(FileDescriptor fd, boolean blocking) throws IOException { 90fc549a0b0388987b26dea524894d75a63d14783bElliott Hughes try { 91fc549a0b0388987b26dea524894d75a63d14783bElliott Hughes int flags = Libcore.os.fcntlVoid(fd, F_GETFL); 92fc549a0b0388987b26dea524894d75a63d14783bElliott Hughes if (!blocking) { 93fc549a0b0388987b26dea524894d75a63d14783bElliott Hughes flags |= O_NONBLOCK; 94fc549a0b0388987b26dea524894d75a63d14783bElliott Hughes } else { 95fc549a0b0388987b26dea524894d75a63d14783bElliott Hughes flags &= ~O_NONBLOCK; 96fc549a0b0388987b26dea524894d75a63d14783bElliott Hughes } 97fc549a0b0388987b26dea524894d75a63d14783bElliott Hughes Libcore.os.fcntlLong(fd, F_SETFL, flags); 98fc549a0b0388987b26dea524894d75a63d14783bElliott Hughes } catch (ErrnoException errnoException) { 99fc549a0b0388987b26dea524894d75a63d14783bElliott Hughes throw errnoException.rethrowAsIOException(); 100fc549a0b0388987b26dea524894d75a63d14783bElliott Hughes } 101fc549a0b0388987b26dea524894d75a63d14783bElliott Hughes } 102bffb058e565a97f838247f1e092b0d17b26cb68eElliott Hughes 1030a9d1ee45a9884a9616624d747172e18734e8fe0Elliott Hughes /** 104bffb058e565a97f838247f1e092b0d17b26cb68eElliott Hughes * Returns the contents of 'path' as a byte array. 105bffb058e565a97f838247f1e092b0d17b26cb68eElliott Hughes */ 106c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath public static byte[] readFileAsByteArray(String absolutePath) throws IOException { 107c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath return new FileReader(absolutePath).readFully().toByteArray(); 108a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes } 109a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes 110a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes /** 111a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes * Returns the contents of 'path' as a string. The contents are assumed to be UTF-8. 112a37e971343883bb582a93ffbd9f0ba84f10e55baElliott Hughes */ 113c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath public static String readFileAsString(String absolutePath) throws IOException { 114c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath return new FileReader(absolutePath).readFully().toString(StandardCharsets.UTF_8); 115bffb058e565a97f838247f1e092b0d17b26cb68eElliott Hughes } 116433e3fac172d0c4449051b0c61c0c63b298a0903Jesse Wilson 117433e3fac172d0c4449051b0c61c0c63b298a0903Jesse Wilson /** 1184f97bfe0d9e6f4bdb43fff91f341f4722af16301Elliott Hughes * Do not use. Use createTemporaryDirectory instead. 1194f97bfe0d9e6f4bdb43fff91f341f4722af16301Elliott Hughes * 1204f97bfe0d9e6f4bdb43fff91f341f4722af16301Elliott Hughes * Used by frameworks/base unit tests to clean up a temporary directory. 1214f97bfe0d9e6f4bdb43fff91f341f4722af16301Elliott Hughes * Deliberately ignores errors, on the assumption that test cleanup is only 1224f97bfe0d9e6f4bdb43fff91f341f4722af16301Elliott Hughes * supposed to be best-effort. 1234f97bfe0d9e6f4bdb43fff91f341f4722af16301Elliott Hughes * 12499b4489d0555c6e0e5df941cbfad4cf250c8f0b8Elliott Hughes * @deprecated Use {@link #createTemporaryDirectory} instead. 1257653089cb7609f6269aecd68e839c40941cb1a46Elliott Hughes */ 1267653089cb7609f6269aecd68e839c40941cb1a46Elliott Hughes public static void deleteContents(File dir) throws IOException { 1277653089cb7609f6269aecd68e839c40941cb1a46Elliott Hughes File[] files = dir.listFiles(); 1284f97bfe0d9e6f4bdb43fff91f341f4722af16301Elliott Hughes if (files != null) { 1294f97bfe0d9e6f4bdb43fff91f341f4722af16301Elliott Hughes for (File file : files) { 1304f97bfe0d9e6f4bdb43fff91f341f4722af16301Elliott Hughes if (file.isDirectory()) { 1314f97bfe0d9e6f4bdb43fff91f341f4722af16301Elliott Hughes deleteContents(file); 1324f97bfe0d9e6f4bdb43fff91f341f4722af16301Elliott Hughes } 1334f97bfe0d9e6f4bdb43fff91f341f4722af16301Elliott Hughes file.delete(); 1347653089cb7609f6269aecd68e839c40941cb1a46Elliott Hughes } 1354f97bfe0d9e6f4bdb43fff91f341f4722af16301Elliott Hughes } 1364f97bfe0d9e6f4bdb43fff91f341f4722af16301Elliott Hughes } 1374f97bfe0d9e6f4bdb43fff91f341f4722af16301Elliott Hughes 1384f97bfe0d9e6f4bdb43fff91f341f4722af16301Elliott Hughes /** 1394f97bfe0d9e6f4bdb43fff91f341f4722af16301Elliott Hughes * Creates a unique new temporary directory under "java.io.tmpdir". 1404f97bfe0d9e6f4bdb43fff91f341f4722af16301Elliott Hughes */ 1414f97bfe0d9e6f4bdb43fff91f341f4722af16301Elliott Hughes public static File createTemporaryDirectory(String prefix) { 1424f97bfe0d9e6f4bdb43fff91f341f4722af16301Elliott Hughes while (true) { 1434f97bfe0d9e6f4bdb43fff91f341f4722af16301Elliott Hughes String candidateName = prefix + TEMPORARY_DIRECTORY_PRNG.nextInt(); 1444f97bfe0d9e6f4bdb43fff91f341f4722af16301Elliott Hughes File result = new File(System.getProperty("java.io.tmpdir"), candidateName); 1454f97bfe0d9e6f4bdb43fff91f341f4722af16301Elliott Hughes if (result.mkdir()) { 1464f97bfe0d9e6f4bdb43fff91f341f4722af16301Elliott Hughes return result; 1477653089cb7609f6269aecd68e839c40941cb1a46Elliott Hughes } 1487653089cb7609f6269aecd68e839c40941cb1a46Elliott Hughes } 1497653089cb7609f6269aecd68e839c40941cb1a46Elliott Hughes } 1507653089cb7609f6269aecd68e839c40941cb1a46Elliott Hughes 1517653089cb7609f6269aecd68e839c40941cb1a46Elliott Hughes /** 1524f97bfe0d9e6f4bdb43fff91f341f4722af16301Elliott Hughes * Do not use. This is for System.loadLibrary use only. 1534f97bfe0d9e6f4bdb43fff91f341f4722af16301Elliott Hughes * 1546d17baa25d349e2659eb16fe5eef3088d48e5e22Elliott Hughes * Checks whether {@code path} can be opened read-only. Similar to File.exists, but doesn't 1556d17baa25d349e2659eb16fe5eef3088d48e5e22Elliott Hughes * require read permission on the parent, so it'll work in more cases, and allow you to 1564f97bfe0d9e6f4bdb43fff91f341f4722af16301Elliott Hughes * remove read permission from more directories. Everyone else should just open(2) and then 1574f97bfe0d9e6f4bdb43fff91f341f4722af16301Elliott Hughes * use the fd, but the loadLibrary API is broken by its need to ask ClassLoaders where to 1584f97bfe0d9e6f4bdb43fff91f341f4722af16301Elliott Hughes * find a .so rather than just calling dlopen(3). 1596d17baa25d349e2659eb16fe5eef3088d48e5e22Elliott Hughes */ 1606d17baa25d349e2659eb16fe5eef3088d48e5e22Elliott Hughes public static boolean canOpenReadOnly(String path) { 1616d17baa25d349e2659eb16fe5eef3088d48e5e22Elliott Hughes try { 1626d17baa25d349e2659eb16fe5eef3088d48e5e22Elliott Hughes // Use open(2) rather than stat(2) so we require fewer permissions. http://b/6485312. 1636d17baa25d349e2659eb16fe5eef3088d48e5e22Elliott Hughes FileDescriptor fd = Libcore.os.open(path, O_RDONLY, 0); 1646d17baa25d349e2659eb16fe5eef3088d48e5e22Elliott Hughes Libcore.os.close(fd); 1656d17baa25d349e2659eb16fe5eef3088d48e5e22Elliott Hughes return true; 1666d17baa25d349e2659eb16fe5eef3088d48e5e22Elliott Hughes } catch (ErrnoException errnoException) { 1676d17baa25d349e2659eb16fe5eef3088d48e5e22Elliott Hughes return false; 1686d17baa25d349e2659eb16fe5eef3088d48e5e22Elliott Hughes } 1696d17baa25d349e2659eb16fe5eef3088d48e5e22Elliott Hughes } 1706d17baa25d349e2659eb16fe5eef3088d48e5e22Elliott Hughes 1719726be51ed6f9695357bc8f11a547d9beaa79fceBrian Carlstrom public static void throwInterruptedIoException() throws InterruptedIOException { 1729726be51ed6f9695357bc8f11a547d9beaa79fceBrian Carlstrom // This is typically thrown in response to an 1739726be51ed6f9695357bc8f11a547d9beaa79fceBrian Carlstrom // InterruptedException which does not leave the thread in an 1749726be51ed6f9695357bc8f11a547d9beaa79fceBrian Carlstrom // interrupted state, so explicitly interrupt here. 1759726be51ed6f9695357bc8f11a547d9beaa79fceBrian Carlstrom Thread.currentThread().interrupt(); 1769726be51ed6f9695357bc8f11a547d9beaa79fceBrian Carlstrom // TODO: set InterruptedIOException.bytesTransferred 1779726be51ed6f9695357bc8f11a547d9beaa79fceBrian Carlstrom throw new InterruptedIOException(); 1789726be51ed6f9695357bc8f11a547d9beaa79fceBrian Carlstrom } 179c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath 180c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath /** 181c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath * A convenience class for reading the contents of a file into a {@code String} 182c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath * or a {@code byte[]}. This class attempts to minimize the number of allocations 183c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath * and copies required to read this data. 184c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath * 185c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath * For the case where we know the "true" length of a file (most ordinary files) 186c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath * we allocate exactly one byte[] and copy data into that. Calls to 187c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath * {@link #toByteArray} will then return the internal array and <b>not</b> a copy. 188c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath * 189c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath * <b>Note that an absolute path must be supplied. Expect your reads to fail 190c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath * if one isn't.</b> 191c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath */ 192c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath private static class FileReader { 193c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath private FileDescriptor fd; 194c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath private boolean unknownLength; 195c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath 196c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath private byte[] bytes; 197c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath private int count; 198c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath 199c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath public FileReader(String absolutePath) throws IOException { 200c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath // We use IoBridge.open because callers might differentiate 201c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath // between a FileNotFoundException and a general IOException. 202c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath // 203c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath // NOTE: This costs us an additional call to fstat(2) to test whether 204c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath // "absolutePath" is a directory or not. We can eliminate it 205c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath // at the cost of copying some code from IoBridge.open. 206c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath try { 207c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath fd = IoBridge.open(absolutePath, O_RDONLY); 208c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath } catch (FileNotFoundException fnfe) { 209c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath throw fnfe; 210c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath } 211c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath 212c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath int capacity; 213c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath try { 214c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath final StructStat stat = Libcore.os.fstat(fd); 215c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath // Like RAF & other APIs, we assume that the file size fits 216c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath // into a 32 bit integer. 217c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath capacity = (int) stat.st_size; 218c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath if (capacity == 0) { 219c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath unknownLength = true; 220c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath capacity = 8192; 221c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath } 222c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath } catch (ErrnoException exception) { 223c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath closeQuietly(fd); 224c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath throw exception.rethrowAsIOException(); 225c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath } 226c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath 227c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath bytes = new byte[capacity]; 228c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath } 229c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath 230c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath public FileReader readFully() throws IOException { 231c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath int read; 232c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath int capacity = bytes.length; 233c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath try { 234c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath while ((read = Libcore.os.read(fd, bytes, count, capacity - count)) != 0) { 235c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath count += read; 236c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath if (count == capacity) { 237c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath if (unknownLength) { 238c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath // If we don't know the length of this file, we need to continue 239c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath // reading until we reach EOF. Double the capacity in preparation. 240c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath final int newCapacity = capacity * 2; 241c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath byte[] newBytes = new byte[newCapacity]; 242c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath System.arraycopy(bytes, 0, newBytes, 0, capacity); 243c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath bytes = newBytes; 244c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath capacity = newCapacity; 245c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath } else { 246c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath // We know the length of this file and we've read the right number 247c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath // of bytes from it, return. 248c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath break; 249c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath } 250c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath } 251c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath } 252c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath 253c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath return this; 254c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath } catch (ErrnoException e) { 255c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath throw e.rethrowAsIOException(); 256c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath } finally { 257c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath closeQuietly(fd); 258c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath } 259c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath } 260c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath 261c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath @FindBugsSuppressWarnings("EI_EXPOSE_REP") 262c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath public byte[] toByteArray() { 263c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath if (count == bytes.length) { 264c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath return bytes; 265c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath } 266c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath byte[] result = new byte[count]; 267c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath System.arraycopy(bytes, 0, result, 0, count); 268c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath return result; 269c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath } 270c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath 271c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath public String toString(Charset cs) { 272c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath return new String(bytes, 0, count, cs); 273c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath } 274c7b35cdea3d660c8d4b77e11fa0ef19f6ca17db9Narayan Kamath } 27599a89dd6f0a0e1396aa9b3feebf15ea31f703d3aElliott Hughes} 276