A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://github.com/google/guava/wiki/IOExplained below:

IOExplained · google/guava Wiki · GitHub

ByteStreams and CharStreams

Guava uses the term "stream" to refer to a Closeable stream for I/O data which has positional state in the underlying resource. The term "byte stream" refers to an InputStream or OutputStream, while "char stream" refers to a Reader or Writer (though their supertypes Readable and Appendable are often used as method parameter types). Corresponding utilities are divided into the utility classes ByteStreams and CharStreams.

Most Guava stream-related utilities deal with an entire stream at a time and/or handle buffering themselves for efficiency. Also note that Guava methods that take a stream do not close the stream: closing streams is generally the responsibility of the code that opens the stream.

Some of the methods provided by these classes include:

It's common to create I/O utility methods that help you to avoid dealing with streams at all when doing basic operations. For example, Guava has Files.toByteArray(File) and Files.write(File, byte[]). However, you end up with similar methods scattered all over, each dealing with a different kind of source of data or sink to which data can be written. For example, Guava has Resources.toByteArray(URL) which does the same thing as Files.toByteArray(File), but using a URL as the source of data rather than a file.

To address this, Guava has a set of abstractions over different types of data sources and sinks. A source or sink is a resource of some sort that you know how to open a new stream to, such as a File or URL. Sources are readable, while sinks are writable. Additionally, sources and sinks are broken down according to whether you are dealing with byte or char data.

The advantage of these APIs is that they provide a common set of operations. Once you've wrapped your data source as a ByteSource, for example, you get the same set of methods no matter what that source happens to be.

Creating sources and sinks

Guava provides a number of source and sink implementations:

Bytes Chars Files.asByteSource(File) Files.asCharSource(File, Charset) Files.asByteSink(File, FileWriteMode...) Files.asCharSink(File, Charset, FileWriteMode...) MoreFiles.asByteSource(Path, OpenOption...) MoreFiles.asCharSource(Path, Charset, OpenOption...) MoreFiles.asByteSink(Path, OpenOption...) MoreFiles.asCharSink(Path, Charset, OpenOption...) Resources.asByteSource(URL) Resources.asCharSource(URL, Charset) ByteSource.wrap(byte[]) CharSource.wrap(CharSequence) ByteSource.concat(ByteSource...) CharSource.concat(CharSource...) ByteSource.slice(long, long) N/A CharSource.asByteSource(Charset) ByteSource.asCharSource(Charset) N/A ByteSink.asCharSink(Charset)

In addition, you can extend the source and sink classes yourself to create new implementations.

Note: While it can be tempting to create a source or sink that wraps an open stream (such as an InputStream), this should be avoided. Your source/sink should instead open a new stream each time its openStream() method is called. This allows the source or sink to control the full lifecycle of that stream and allows it to be usable multiple times rather that becoming unusable the first time any method on it is called. Additionally, if you're opening the stream before creating the source or sink you may still have to deal with ensuring that the stream is closed correctly if an exception is thrown elsewhere in your code, which defeats many of the advantages of using a source or sink in the first place.

Once you have a source or sink instance, you have access to a number of operations for reading or writing.

All sources and sinks provide the ability to open a new stream for reading or writing. By default, other operations are all implemented by calling one of these methods to get a stream, doing something, and then ensuring that the stream is closed.

These methods are all named:

// Read the lines of a UTF-8 text file
ImmutableList<String> lines = Files.asCharSource(file, UTF_8)
    .readLines();

// Count distinct word occurrences in a file
Multiset<String> wordOccurrences = HashMultiset.create(
    Splitter.on(CharMatcher.whitespace())
        .trimResults()
        .omitEmptyStrings()
        .split(Files.asCharSource(file, UTF_8).read()));

// SHA-1 a file
HashCode hash = Files.asByteSource(file).hash(Hashing.sha1());

// Copy the data from a URL to a file
Resources.asByteSource(url).copyTo(Files.asByteSink(file));

In addition to methods for creating file sources and sinks, the Files class contains a number of convenience methods that you might be interested in.


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.3