All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.commons.io.input.TeeReader Maven / Gradle / Ivy

There is a newer version: 2024.11.18751.20241128T090041Z-241100
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF 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.
 */
package org.apache.commons.io.input;

import static org.apache.commons.io.IOUtils.EOF;

import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
import java.nio.CharBuffer;

/**
 * Reader proxy that transparently writes a copy of all characters read from the proxied reader to a given Reader. Using
 * {@link #skip(long)} or {@link #mark(int)}/{@link #reset()} on the reader will result on some characters from the
 * reader being skipped or duplicated in the writer.
 * 

* The proxied reader is closed when the {@link #close()} method is called on this proxy. You may configure whether the * reader closes the writer. *

* * @since 2.7 */ public class TeeReader extends ProxyReader { /** * The writer that will receive a copy of all characters read from the proxied reader. */ private final Writer branch; /** * Flag for closing the associated writer when this reader is closed. */ private final boolean closeBranch; /** * Constructs a TeeReader that proxies the given {@link Reader} and copies all read characters to the given * {@link Writer}. The given writer will not be closed when this reader gets closed. * * @param input reader to be proxied * @param branch writer that will receive a copy of all characters read */ public TeeReader(final Reader input, final Writer branch) { this(input, branch, false); } /** * Constructs a TeeReader that proxies the given {@link Reader} and copies all read characters to the given * {@link Writer}. The given writer will be closed when this reader gets closed if the closeBranch parameter is * {@code true}. * * @param input reader to be proxied * @param branch writer that will receive a copy of all characters read * @param closeBranch flag for closing also the writer when this reader is closed */ public TeeReader(final Reader input, final Writer branch, final boolean closeBranch) { super(input); this.branch = branch; this.closeBranch = closeBranch; } /** * Closes the proxied reader and, if so configured, the associated writer. An exception thrown from the reader will * not prevent closing of the writer. * * @throws IOException if either the reader or writer could not be closed */ @Override public void close() throws IOException { try { super.close(); } finally { if (closeBranch) { branch.close(); } } } /** * Reads a single character from the proxied reader and writes it to the associated writer. * * @return next character from the reader, or -1 if the reader has ended * @throws IOException if the reader could not be read (or written) */ @Override public int read() throws IOException { final int ch = super.read(); if (ch != EOF) { branch.write(ch); } return ch; } /** * Reads characters from the proxied reader and writes the read characters to the associated writer. * * @param chr character buffer * @return number of characters read, or -1 if the reader has ended * @throws IOException if the reader could not be read (or written) */ @Override public int read(final char[] chr) throws IOException { final int n = super.read(chr); if (n != EOF) { branch.write(chr, 0, n); } return n; } /** * Reads characters from the proxied reader and writes the read characters to the associated writer. * * @param chr character buffer * @param st start offset within the buffer * @param end maximum number of characters to read * @return number of characters read, or -1 if the reader has ended * @throws IOException if the reader could not be read (or written) */ @Override public int read(final char[] chr, final int st, final int end) throws IOException { final int n = super.read(chr, st, end); if (n != EOF) { branch.write(chr, st, n); } return n; } /** * Reads characters from the proxied reader and writes the read characters to the associated writer. * * @param target character buffer * @return number of characters read, or -1 if the reader has ended * @throws IOException if the reader could not be read (or written) */ @Override public int read(final CharBuffer target) throws IOException { final int originalPosition = target.position(); final int n = super.read(target); if (n != EOF) { // Appending can only be done after resetting the CharBuffer to the // right position and limit. final int newPosition = target.position(); final int newLimit = target.limit(); try { target.position(originalPosition).limit(newPosition); branch.append(target); } finally { // Reset the CharBuffer as if the appending never happened. target.position(newPosition).limit(newLimit); } } return n; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy