    001/*
    002 * Licensed to the Apache Software Foundation (ASF) under one
    003 * or more contributor license agreements.  See the NOTICE file
    004 * distributed with this work for additional information
    005 * regarding copyright ownership.  The ASF licenses this file
    006 * to you under the Apache License, Version 2.0 (the
    007 * "License"); you may not use this file except in compliance
    008 * with the License.  You may obtain a copy of the License at
    009 *
    010 * http://www.apache.org/licenses/LICENSE-2.0
    011 *
    012 * Unless required by applicable law or agreed to in writing,
    013 * software distributed under the License is distributed on an
    014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    015 * KIND, either express or implied.  See the License for the
    016 * specific language governing permissions and limitations
    017 * under the License.
    018 */
    019package org.apache.commons.compress.utils;
    020
    021import java.io.ByteArrayOutputStream;
    022import java.io.Closeable;
    023import java.io.EOFException;
    024import java.io.File;
    025import java.io.IOException;
    026import java.io.InputStream;
    027import java.io.OutputStream;
    028import java.nio.ByteBuffer;
    029import java.nio.channels.ReadableByteChannel;
    030import java.nio.file.Files;
    031import java.nio.file.LinkOption;
    032
    033import org.apache.commons.io.FileUtils;
    034
    035/**
    036 * Utility functions.
    037 *
    038 * @Immutable (has mutable data but it is write-only).
    039 */
    040public final class IOUtils {
    041
    042    /**
    043     * Empty array of type {@link LinkOption}.
    044     *
    045     * @since 1.21
    046     */
    047    public static final LinkOption[] EMPTY_LINK_OPTIONS = {};
    048
    049    /**
    050     * Closes the given Closeable and swallows any IOException that may occur.
    051     *
    052     * @param c Closeable to close, can be null
    053     * @since 1.7
    054     * @deprecated Use {@link org.apache.commons.io.IOUtils#closeQuietly(Closeable)}.
    055     */
    056    @Deprecated
    057    public static void closeQuietly(final Closeable c) {
    058        org.apache.commons.io.IOUtils.closeQuietly(c);
    059    }
    060
    061    /**
    062     * Copies the source file to the given output stream.
    063     *
    064     * @param sourceFile   The file to read.
    065     * @param outputStream The output stream to write.
    066     * @throws IOException if an I/O error occurs when reading or writing.
    067     * @since 1.21
    068     * @deprecated Use {@link FileUtils#copyFile(File, OutputStream)}.
    069     */
    070    @Deprecated
    071    public static void copy(final File sourceFile, final OutputStream outputStream) throws IOException {
    072        FileUtils.copyFile(sourceFile, outputStream);
    073    }
    074
    075    /**
    076     * Copies the content of a InputStream into an OutputStream. Uses a default buffer size of 8024 bytes.
    077     *
    078     * @param input  the InputStream to copy
    079     * @param output the target, may be null to simulate output to dev/null on Linux and NUL on Windows
    080     * @return the number of bytes copied
    081     * @throws IOException if an error occurs
    082     * @deprecated Use {@link org.apache.commons.io.IOUtils#copy(InputStream, OutputStream)}.
    083     */
    084    @Deprecated
    085    public static long copy(final InputStream input, final OutputStream output) throws IOException {
    086        return org.apache.commons.io.IOUtils.copy(input, output);
    087    }
    088
    089    /**
    090     * Copies the content of a InputStream into an OutputStream
    091     *
    092     * @param input      the InputStream to copy
    093     * @param output     the target, may be null to simulate output to dev/null on Linux and NUL on Windows
    094     * @param bufferSize the buffer size to use, must be bigger than 0
    095     * @return the number of bytes copied
    096     * @throws IOException              if an error occurs
    097     * @throws IllegalArgumentException if bufferSize is smaller than or equal to 0
    098     * @deprecated Use {@link org.apache.commons.io.IOUtils#copy(InputStream, OutputStream, int)}.
    099     */
    100    @Deprecated
    101    public static long copy(final InputStream input, final OutputStream output, final int bufferSize) throws IOException {
    102        return org.apache.commons.io.IOUtils.copy(input, output, bufferSize);
    103    }
    104
    105    /**
    106     * Copies part of the content of a InputStream into an OutputStream. Uses a default buffer size of 8024 bytes.
    107     *
    108     * @param input  the InputStream to copy
    109     * @param output the target Stream
    110     * @param len    maximum amount of bytes to copy
    111     * @return the number of bytes copied
    112     * @throws IOException if an error occurs
    113     * @since 1.21
    114     * @deprecated Use {@link org.apache.commons.io.IOUtils#copyLarge(InputStream, OutputStream, long, long)}.
    115     */
    116    @Deprecated
    117    public static long copyRange(final InputStream input, final long len, final OutputStream output) throws IOException {
    118        return org.apache.commons.io.IOUtils.copyLarge(input, output, 0, len);
    119    }
    120
    121    /**
    122     * Copies part of the content of a InputStream into an OutputStream
    123     *
    124     * @param input      the InputStream to copy
    125     * @param length        maximum amount of bytes to copy
    126     * @param output     the target, may be null to simulate output to dev/null on Linux and NUL on Windows
    127     * @param bufferSize the buffer size to use, must be bigger than 0
    128     * @return the number of bytes copied
    129     * @throws IOException              if an error occurs
    130     * @throws IllegalArgumentException if bufferSize is smaller than or equal to 0
    131     * @since 1.21
    132     * @deprecated No longer used.
    133     */
    134    @Deprecated
    135    public static long copyRange(final InputStream input, final long length, final OutputStream output, final int bufferSize) throws IOException {
    136        if (bufferSize < 1) {
    137            throw new IllegalArgumentException("bufferSize must be bigger than 0");
    138        }
    139        final byte[] buffer = new byte[(int) Math.min(bufferSize, Math.max(0, length))];
    140        int n = 0;
    141        long count = 0;
    142        while (count < length && -1 != (n = input.read(buffer, 0, (int) Math.min(length - count, buffer.length)))) {
    143            if (output != null) {
    144                output.write(buffer, 0, n);
    145            }
    146            count += n;
    147        }
    148        return count;
    149    }
    150
    151    /**
    152     * Reads as much from the file as possible to fill the given array.
    153     * <p>
    154     * This method may invoke read repeatedly to fill the array and only read less bytes than the length of the array if the end of the stream has been reached.
    155     * </p>
    156     *
    157     * @param file  file to read
    158     * @param array buffer to fill
    159     * @return the number of bytes actually read
    160     * @throws IOException on error
    161     * @since 1.20
    162     * @deprecated Use {@link Files#readAllBytes(java.nio.file.Path)}.
    163     */
    164    @Deprecated
    165    public static int read(final File file, final byte[] array) throws IOException {
    166        try (InputStream inputStream = Files.newInputStream(file.toPath())) {
    167            return readFully(inputStream, array, 0, array.length);
    168        }
    169    }
    170
    171    /**
    172     * Reads as much from input as possible to fill the given array.
    173     * <p>
    174     * This method may invoke read repeatedly to fill the array and only read less bytes than the length of the array if the end of the stream has been reached.
    175     * </p>
    176     *
    177     * @param input stream to read from
    178     * @param array buffer to fill
    179     * @return the number of bytes actually read
    180     * @throws IOException on error
    181     */
    182    public static int readFully(final InputStream input, final byte[] array) throws IOException {
    183        return readFully(input, array, 0, array.length);
    184    }
    185
    186    /**
    187     * Reads as much from input as possible to fill the given array with the given amount of bytes.
    188     * <p>
    189     * This method may invoke read repeatedly to read the bytes and only read less bytes than the requested length if the end of the stream has been reached.
    190     * </p>
    191     *
    192     * @param input  stream to read from
    193     * @param array  buffer to fill
    194     * @param offset offset into the buffer to start filling at
    195     * @param length    of bytes to read
    196     * @return the number of bytes actually read
    197     * @throws IOException if an I/O error has occurred
    198     */
    199    public static int readFully(final InputStream input, final byte[] array, final int offset, final int length) throws IOException {
    200        if (length < 0 || offset < 0 || length + offset > array.length || length + offset < 0) {
    201            throw new IndexOutOfBoundsException();
    202        }
    203        return org.apache.commons.io.IOUtils.read(input, array, offset, length);
    204    }
    205
    206    /**
    207     * Reads {@code b.remaining()} bytes from the given channel starting at the current channel's position.
    208     * <p>
    209     * This method reads repeatedly from the channel until the requested number of bytes are read. This method blocks until the requested number of bytes are
    210     * read, the end of the channel is detected, or an exception is thrown.
    211     * </p>
    212     *
    213     * @param channel    the channel to read from
    214     * @param byteBuffer the buffer into which the data is read.
    215     * @throws IOException  if an I/O error occurs.
    216     * @throws EOFException if the channel reaches the end before reading all the bytes.
    217     */
    218    public static void readFully(final ReadableByteChannel channel, final ByteBuffer byteBuffer) throws IOException {
    219        final int expectedLength = byteBuffer.remaining();
    220        final int read = org.apache.commons.io.IOUtils.read(channel, byteBuffer);
    221        if (read < expectedLength) {
    222            throw new EOFException();
    223        }
    224    }
    225
    226    /**
    227     * Gets part of the contents of an {@code InputStream} as a {@code byte[]}.
    228     *
    229     * @param input the {@code InputStream} to read from
    230     * @param length   maximum amount of bytes to copy
    231     * @return the requested byte array
    232     * @throws NullPointerException if the input is null
    233     * @throws IOException          if an I/O error occurs
    234     * @since 1.21
    235     */
    236    public static byte[] readRange(final InputStream input, final int length) throws IOException {
    237        final ByteArrayOutputStream output = new ByteArrayOutputStream();
    238        org.apache.commons.io.IOUtils.copyLarge(input, output, 0, length);
    239        return output.toByteArray();
    240    }
    241
    242    /**
    243     * Gets part of the contents of an {@code ReadableByteChannel} as a {@code byte[]}.
    244     *
    245     * @param input the {@code ReadableByteChannel} to read from
    246     * @param length   maximum amount of bytes to copy
    247     * @return the requested byte array
    248     * @throws NullPointerException if the input is null
    249     * @throws IOException          if an I/O error occurs
    250     * @since 1.21
    251     */
    252    public static byte[] readRange(final ReadableByteChannel input, final int length) throws IOException {
    253        final ByteArrayOutputStream output = new ByteArrayOutputStream();
    254        final ByteBuffer b = ByteBuffer.allocate(Math.min(length, org.apache.commons.io.IOUtils.DEFAULT_BUFFER_SIZE));
    255        int read = 0;
    256        while (read < length) {
    257            // Make sure we never read more than len bytes
    258            b.limit(Math.min(length - read, b.capacity()));
    259            final int readCount = input.read(b);
    260            if (readCount <= 0) {
    261                break;
    262            }
    263            output.write(b.array(), 0, readCount);
    264            b.rewind();
    265            read += readCount;
    266        }
    267        return output.toByteArray();
    268    }
    269
    270    /**
    271     * Skips bytes from an input byte stream.
    272     * <p>
    273     * This method will only skip less than the requested number of bytes if the end of the input stream has been reached.
    274     * </p>
    275     *
    276     * @param input     stream to skip bytes in
    277     * @param toSkip the number of bytes to skip
    278     * @return the number of bytes actually skipped
    279     * @throws IOException on error
    280     */
    281    public static long skip(final InputStream input, final long toSkip) throws IOException {
    282        return org.apache.commons.io.IOUtils.skip(input, toSkip, org.apache.commons.io.IOUtils::byteArray);
    283    }
    284
    285    /**
    286     * Gets the contents of an {@code InputStream} as a {@code byte[]}.
    287     * <p>
    288     * This method buffers the input internally, so there is no need to use a {@code BufferedInputStream}.
    289     * </p>
    290     *
    291     * @param input the {@code InputStream} to read from
    292     * @return the requested byte array
    293     * @throws NullPointerException if the input is null
    294     * @throws IOException          if an I/O error occurs
    295     * @since 1.5
    296     * @deprecated Use {@link org.apache.commons.io.IOUtils#toByteArray(InputStream)}.
    297     */
    298    @Deprecated
    299    public static byte[] toByteArray(final InputStream input) throws IOException {
    300        return org.apache.commons.io.IOUtils.toByteArray(input);
    301    }
    302
    303    /** Private constructor to prevent instantiation of this utility class. */
    304    private IOUtils() {
    305    }
    306
    307}