javadoc.src-html.com.google.common.io.CharStreams.html Maven / Gradle / Ivy
The newest version!
001 /*
002 * Copyright (C) 2007 The Guava Authors
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017 package com.google.common.io;
018
019 import com.google.common.annotations.Beta;
020 import com.google.common.base.Preconditions;
021
022 import java.io.Closeable;
023 import java.io.EOFException;
024 import java.io.IOException;
025 import java.io.InputStream;
026 import java.io.InputStreamReader;
027 import java.io.OutputStream;
028 import java.io.OutputStreamWriter;
029 import java.io.Reader;
030 import java.io.StringReader;
031 import java.io.Writer;
032 import java.nio.CharBuffer;
033 import java.nio.charset.Charset;
034 import java.util.ArrayList;
035 import java.util.Arrays;
036 import java.util.List;
037
038 /**
039 * Provides utility methods for working with character streams.
040 *
041 * <p>All method parameters must be non-null unless documented otherwise.
042 *
043 * <p>Some of the methods in this class take arguments with a generic type of
044 * {@code Readable & Closeable}. A {@link java.io.Reader} implements both of
045 * those interfaces. Similarly for {@code Appendable & Closeable} and
046 * {@link java.io.Writer}.
047 *
048 * @author Chris Nokleberg
049 * @author Bin Zhu
050 * @since 1.0
051 */
052 @Beta
053 public final class CharStreams {
054 private static final int BUF_SIZE = 0x800; // 2K chars (4K bytes)
055
056 private CharStreams() {}
057
058 /**
059 * Returns a factory that will supply instances of {@link StringReader} that
060 * read a string value.
061 *
062 * @param value the string to read
063 * @return the factory
064 */
065 public static InputSupplier<StringReader> newReaderSupplier(
066 final String value) {
067 Preconditions.checkNotNull(value);
068 return new InputSupplier<StringReader>() {
069 @Override
070 public StringReader getInput() {
071 return new StringReader(value);
072 }
073 };
074 }
075
076 /**
077 * Returns a factory that will supply instances of {@link InputStreamReader},
078 * using the given {@link InputStream} factory and character set.
079 *
080 * @param in the factory that will be used to open input streams
081 * @param charset the character set used to decode the input stream
082 * @return the factory
083 */
084 public static InputSupplier<InputStreamReader> newReaderSupplier(
085 final InputSupplier<? extends InputStream> in, final Charset charset) {
086 Preconditions.checkNotNull(in);
087 Preconditions.checkNotNull(charset);
088 return new InputSupplier<InputStreamReader>() {
089 @Override
090 public InputStreamReader getInput() throws IOException {
091 return new InputStreamReader(in.getInput(), charset);
092 }
093 };
094 }
095
096 /**
097 * Returns a factory that will supply instances of {@link OutputStreamWriter},
098 * using the given {@link OutputStream} factory and character set.
099 *
100 * @param out the factory that will be used to open output streams
101 * @param charset the character set used to encode the output stream
102 * @return the factory
103 */
104 public static OutputSupplier<OutputStreamWriter> newWriterSupplier(
105 final OutputSupplier<? extends OutputStream> out, final Charset charset) {
106 Preconditions.checkNotNull(out);
107 Preconditions.checkNotNull(charset);
108 return new OutputSupplier<OutputStreamWriter>() {
109 @Override
110 public OutputStreamWriter getOutput() throws IOException {
111 return new OutputStreamWriter(out.getOutput(), charset);
112 }
113 };
114 }
115
116 /**
117 * Writes a character sequence (such as a string) to an appendable
118 * object from the given supplier.
119 *
120 * @param from the character sequence to write
121 * @param to the output supplier
122 * @throws IOException if an I/O error occurs
123 */
124 public static <W extends Appendable & Closeable> void write(CharSequence from,
125 OutputSupplier<W> to) throws IOException {
126 Preconditions.checkNotNull(from);
127 boolean threw = true;
128 W out = to.getOutput();
129 try {
130 out.append(from);
131 threw = false;
132 } finally {
133 Closeables.close(out, threw);
134 }
135 }
136
137 /**
138 * Opens {@link Readable} and {@link Appendable} objects from the
139 * given factories, copies all characters between the two, and closes
140 * them.
141 *
142 * @param from the input factory
143 * @param to the output factory
144 * @return the number of characters copied
145 * @throws IOException if an I/O error occurs
146 */
147 public static <R extends Readable & Closeable,
148 W extends Appendable & Closeable> long copy(InputSupplier<R> from,
149 OutputSupplier<W> to) throws IOException {
150 int successfulOps = 0;
151 R in = from.getInput();
152 try {
153 W out = to.getOutput();
154 try {
155 long count = copy(in, out);
156 successfulOps++;
157 return count;
158 } finally {
159 Closeables.close(out, successfulOps < 1);
160 successfulOps++;
161 }
162 } finally {
163 Closeables.close(in, successfulOps < 2);
164 }
165 }
166
167 /**
168 * Opens a {@link Readable} object from the supplier, copies all characters
169 * to the {@link Appendable} object, and closes the input. Does not close
170 * or flush the output.
171 *
172 * @param from the input factory
173 * @param to the object to write to
174 * @return the number of characters copied
175 * @throws IOException if an I/O error occurs
176 */
177 public static <R extends Readable & Closeable> long copy(
178 InputSupplier<R> from, Appendable to) throws IOException {
179 boolean threw = true;
180 R in = from.getInput();
181 try {
182 long count = copy(in, to);
183 threw = false;
184 return count;
185 } finally {
186 Closeables.close(in, threw);
187 }
188 }
189
190 /**
191 * Copies all characters between the {@link Readable} and {@link Appendable}
192 * objects. Does not close or flush either object.
193 *
194 * @param from the object to read from
195 * @param to the object to write to
196 * @return the number of characters copied
197 * @throws IOException if an I/O error occurs
198 */
199 public static long copy(Readable from, Appendable to) throws IOException {
200 CharBuffer buf = CharBuffer.allocate(BUF_SIZE);
201 long total = 0;
202 while (true) {
203 int r = from.read(buf);
204 if (r == -1) {
205 break;
206 }
207 buf.flip();
208 to.append(buf, 0, r);
209 total += r;
210 }
211 return total;
212 }
213
214 /**
215 * Reads all characters from a {@link Readable} object into a {@link String}.
216 * Does not close the {@code Readable}.
217 *
218 * @param r the object to read from
219 * @return a string containing all the characters
220 * @throws IOException if an I/O error occurs
221 */
222 public static String toString(Readable r) throws IOException {
223 return toStringBuilder(r).toString();
224 }
225
226 /**
227 * Returns the characters from a {@link Readable} & {@link Closeable} object
228 * supplied by a factory as a {@link String}.
229 *
230 * @param supplier the factory to read from
231 * @return a string containing all the characters
232 * @throws IOException if an I/O error occurs
233 */
234 public static <R extends Readable & Closeable> String toString(
235 InputSupplier<R> supplier) throws IOException {
236 return toStringBuilder(supplier).toString();
237 }
238
239 /**
240 * Reads all characters from a {@link Readable} object into a new
241 * {@link StringBuilder} instance. Does not close the {@code Readable}.
242 *
243 * @param r the object to read from
244 * @return a {@link StringBuilder} containing all the characters
245 * @throws IOException if an I/O error occurs
246 */
247 private static StringBuilder toStringBuilder(Readable r) throws IOException {
248 StringBuilder sb = new StringBuilder();
249 copy(r, sb);
250 return sb;
251 }
252
253 /**
254 * Returns the characters from a {@link Readable} & {@link Closeable} object
255 * supplied by a factory as a new {@link StringBuilder} instance.
256 *
257 * @param supplier the factory to read from
258 * @throws IOException if an I/O error occurs
259 */
260 private static <R extends Readable & Closeable> StringBuilder toStringBuilder(
261 InputSupplier<R> supplier) throws IOException {
262 boolean threw = true;
263 R r = supplier.getInput();
264 try {
265 StringBuilder result = toStringBuilder(r);
266 threw = false;
267 return result;
268 } finally {
269 Closeables.close(r, threw);
270 }
271 }
272
273 /**
274 * Reads the first line from a {@link Readable} & {@link Closeable} object
275 * supplied by a factory. The line does not include line-termination
276 * characters, but does include other leading and trailing whitespace.
277 *
278 * @param supplier the factory to read from
279 * @return the first line, or null if the reader is empty
280 * @throws IOException if an I/O error occurs
281 */
282 public static <R extends Readable & Closeable> String readFirstLine(
283 InputSupplier<R> supplier) throws IOException {
284 boolean threw = true;
285 R r = supplier.getInput();
286 try {
287 String line = new LineReader(r).readLine();
288 threw = false;
289 return line;
290 } finally {
291 Closeables.close(r, threw);
292 }
293 }
294
295 /**
296 * Reads all of the lines from a {@link Readable} & {@link Closeable} object
297 * supplied by a factory. The lines do not include line-termination
298 * characters, but do include other leading and trailing whitespace.
299 *
300 * @param supplier the factory to read from
301 * @return a mutable {@link List} containing all the lines
302 * @throws IOException if an I/O error occurs
303 */
304 public static <R extends Readable & Closeable> List<String> readLines(
305 InputSupplier<R> supplier) throws IOException {
306 boolean threw = true;
307 R r = supplier.getInput();
308 try {
309 List<String> result = readLines(r);
310 threw = false;
311 return result;
312 } finally {
313 Closeables.close(r, threw);
314 }
315 }
316
317 /**
318 * Reads all of the lines from a {@link Readable} object. The lines do
319 * not include line-termination characters, but do include other
320 * leading and trailing whitespace.
321 *
322 * <p>Does not close the {@code Readable}. If reading files or resources you
323 * should use the {@link Files#readLines} and {@link Resources#readLines}
324 * methods.
325 *
326 * @param r the object to read from
327 * @return a mutable {@link List} containing all the lines
328 * @throws IOException if an I/O error occurs
329 */
330 public static List<String> readLines(Readable r) throws IOException {
331 List<String> result = new ArrayList<String>();
332 LineReader lineReader = new LineReader(r);
333 String line;
334 while ((line = lineReader.readLine()) != null) {
335 result.add(line);
336 }
337 return result;
338 }
339
340 /**
341 * Streams lines from a {@link Readable} and {@link Closeable} object
342 * supplied by a factory, stopping when our callback returns false, or we
343 * have read all of the lines.
344 *
345 * @param supplier the factory to read from
346 * @param callback the LineProcessor to use to handle the lines
347 * @return the output of processing the lines
348 * @throws IOException if an I/O error occurs
349 */
350 public static <R extends Readable & Closeable, T> T readLines(
351 InputSupplier<R> supplier, LineProcessor<T> callback) throws IOException {
352 boolean threw = true;
353 R r = supplier.getInput();
354 try {
355 LineReader lineReader = new LineReader(r);
356 String line;
357 while ((line = lineReader.readLine()) != null) {
358 if (!callback.processLine(line)) {
359 break;
360 }
361 }
362 threw = false;
363 } finally {
364 Closeables.close(r, threw);
365 }
366 return callback.getResult();
367 }
368
369 /**
370 * Joins multiple {@link Reader} suppliers into a single supplier.
371 * Reader returned from the supplier will contain the concatenated data
372 * from the readers of the underlying suppliers.
373 *
374 * <p>Reading from the joined reader will throw a {@link NullPointerException}
375 * if any of the suppliers are null or return null.
376 *
377 * <p>Only one underlying reader will be open at a time. Closing the
378 * joined reader will close the open underlying reader.
379 *
380 * @param suppliers the suppliers to concatenate
381 * @return a supplier that will return a reader containing the concatenated
382 * data
383 */
384 public static InputSupplier<Reader> join(
385 final Iterable<? extends InputSupplier<? extends Reader>> suppliers) {
386 return new InputSupplier<Reader>() {
387 @Override public Reader getInput() throws IOException {
388 return new MultiReader(suppliers.iterator());
389 }
390 };
391 }
392
393 /** Varargs form of {@link #join(Iterable)}. */
394 public static InputSupplier<Reader> join(
395 InputSupplier<? extends Reader>... suppliers) {
396 return join(Arrays.asList(suppliers));
397 }
398
399 /**
400 * Discards {@code n} characters of data from the reader. This method
401 * will block until the full amount has been skipped. Does not close the
402 * reader.
403 *
404 * @param reader the reader to read from
405 * @param n the number of characters to skip
406 * @throws EOFException if this stream reaches the end before skipping all
407 * the bytes
408 * @throws IOException if an I/O error occurs
409 */
410 public static void skipFully(Reader reader, long n) throws IOException {
411 while (n > 0) {
412 long amt = reader.skip(n);
413 if (amt == 0) {
414 // force a blocking read
415 if (reader.read() == -1) {
416 throw new EOFException();
417 }
418 n--;
419 } else {
420 n -= amt;
421 }
422 }
423 }
424
425 /**
426 * Returns a Writer that sends all output to the given {@link Appendable}
427 * target. Closing the writer will close the target if it is {@link
428 * Closeable}, and flushing the writer will flush the target if it is {@link
429 * java.io.Flushable}.
430 *
431 * @param target the object to which output will be sent
432 * @return a new Writer object, unless target is a Writer, in which case the
433 * target is returned
434 */
435 public static Writer asWriter(Appendable target) {
436 if (target instanceof Writer) {
437 return (Writer) target;
438 }
439 return new AppendableWriter(target);
440 }
441 }
© 2015 - 2025 Weber Informatics LLC | Privacy Policy