/* * SPDX-License-Identifier: Apache-2.0 * * The OpenSearch Contributors require contributions made to * this file be licensed under the Apache-2.0 license or a * compatible open source license. */ /* * Licensed to Elasticsearch under one or more contributor * license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright * ownership. Elasticsearch licenses this file to you under * the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /* * Modifications Copyright OpenSearch Contributors. See * GitHub history for details. */ package org.opensearch.common.io; import org.opensearch.core.common.bytes.BytesReference; import org.opensearch.core.common.io.stream.BytesStream; import org.opensearch.common.io.stream.BytesStreamOutput; import org.opensearch.core.common.io.stream.StreamOutput; import java.io.BufferedReader; import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.Reader; import java.io.StringWriter; import java.io.Writer; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.function.Consumer; /** * Simple utility methods for file and stream copying. * All copy methods use a block size of 4096 bytes, * and close all affected streams when done. *
* Mainly for use within the framework,
* but also useful for application code.
*
* @opensearch.internal
*/
public abstract class Streams {
public static final int BUFFER_SIZE = 1024 * 8;
/**
* OutputStream that just throws all the bytes away
*/
public static final OutputStream NULL_OUTPUT_STREAM = new OutputStream() {
@Override
public void write(int b) {
// no-op
}
@Override
public void write(byte[] b, int off, int len) {
// no-op
}
};
/**
* Copy the contents of the given byte array to the given OutputStream.
* Closes the stream when done.
*
* @param in the byte array to copy from
* @param out the OutputStream to copy to
* @throws IOException in case of I/O errors
*/
public static void copy(byte[] in, OutputStream out) throws IOException {
Objects.requireNonNull(in, "No input byte array specified");
Objects.requireNonNull(out, "No OutputStream specified");
try (OutputStream out2 = out) {
out2.write(in);
}
}
// ---------------------------------------------------------------------
// Copy methods for java.io.Reader / java.io.Writer
// ---------------------------------------------------------------------
/**
* Copy the contents of the given Reader to the given Writer.
* Closes both when done.
*
* @param in the Reader to copy from
* @param out the Writer to copy to
* @return the number of characters copied
* @throws IOException in case of I/O errors
*/
public static int copy(Reader in, Writer out) throws IOException {
Objects.requireNonNull(in, "No Reader specified");
Objects.requireNonNull(out, "No Writer specified");
// Leverage try-with-resources to close in and out so that exceptions in close() are either propagated or added as suppressed
// exceptions to the main exception
try (Reader in2 = in; Writer out2 = out) {
return doCopy(in2, out2);
}
}
private static int doCopy(Reader in, Writer out) throws IOException {
int byteCount = 0;
char[] buffer = new char[BUFFER_SIZE];
int bytesRead;
while ((bytesRead = in.read(buffer)) != -1) {
out.write(buffer, 0, bytesRead);
byteCount += bytesRead;
}
out.flush();
return byteCount;
}
/**
* Copy the contents of the given String to the given output Writer.
* Closes the write when done.
*
* @param in the String to copy from
* @param out the Writer to copy to
* @throws IOException in case of I/O errors
*/
public static void copy(String in, Writer out) throws IOException {
Objects.requireNonNull(in, "No input String specified");
Objects.requireNonNull(out, "No Writer specified");
try (Writer out2 = out) {
out2.write(in);
}
}
/**
* Copy the contents of the given Reader into a String.
* Closes the reader when done.
*
* @param in the reader to copy from
* @return the String that has been copied to
* @throws IOException in case of I/O errors
*/
public static String copyToString(Reader in) throws IOException {
StringWriter out = new StringWriter();
copy(in, out);
return out.toString();
}
@Deprecated
public static int readFully(InputStream reader, byte[] dest) throws IOException {
return reader.readNBytes(dest, 0, dest.length);
}
/**
* Fully consumes the input stream, throwing the bytes away. Returns the number of bytes consumed.
*/
public static long consumeFully(InputStream inputStream) throws IOException {
return org.opensearch.common.util.io.Streams.copy(inputStream, NULL_OUTPUT_STREAM);
}
public static List