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