Guava Library Learning: Learning Guava Files Series (ii)

Source: Internet
Author: User
Tags string back

Original address: Guava Library Learning: Learning Guava Files Series (ii)

Previous, Guava Library learning: Learning Guava Files Series (a), we simply learned to use files for file reading and writing, such as common operations, this article we continue to guava files series of learning.

Inputsupplier and Outputsupplier

The guava provides Inputsupplier and Outputsupplier interfaces for handling inputstreams/readers or outputstreams/writers. We'll see in the next article what guava provides for us, and guava typically use these interfaces when you open, refresh, and close resources.

Sources and Sinks

    Guava I/O corresponds to the read and write of the file sources and sinks concepts, sources and sinks are not those streams, readers or writers objects, but provide the same effect. sources and Sinks  objects can be used in the following two ways:

    • We can retrieve the underlying stream through the provider. Each time the provider returns a stream, it is a completely new instance, independent of any other instances that might have been returned. Retrieves the is responsible for closing the stream.

    • Provides some basic and convenient ways to perform the basic operations we expect, such as reading a stream or writing a stream. When through sources and Sinks perform read and write, the open and close stream operations are processed by us.

There are two types of sources: Bytesource and Charssource. Similarly, there are two types of sinks: Bytesink and Charsink. The respective sources and sinks classes provide similar functionality, and the differences in their methods depend only on whether we are using characters or raw bytes. The files class provides several ways to manipulate the file through the Bytesink and Charsink classes. We can create Bytesource, Bytesink, Charsource, Charsink instances by using the static factory method provided by the files class. In our example, we will focus on Bytesource and Bytesink objects, Charsource and Charsink objects are similar, just using characters.


The Bytesource class represents a readable byte. Typically, the byte source we expect is a file, but it can also read bytes from a byte array.

We can create bytesource for a file object by using the static method provided by files:

@Testpublic void Createbytesourcefromfiletest () throws Exception {file F1 = new File ("D:\\test2.txt");    Bytesource Bytesource = Files.asbytesource (F1);    byte[] readbytes = (); Assertthat (Readbytes,is (Files.tobytearray (F1));}

In this example, we create bytesource for the file object by using the Files.asbytesource method. Next, we show how to read the contents of the Bytesource into a byte array by calling the Read method . Finally, we assert that a byte array called the Read method returns the same byte array as the Files.tobytearray method.


The Bytesink class represents a writable byte. We can write bytes to one file or to another byte array. To create a bytesink for a file object, we can do this:

@Testpublic void Testcreatefilebytesink () throws Exception {file Dest = new File ("D:\\test.txt");    Dest.deleteonexit ();    Bytesink Bytesink = Files.asbytesink (dest);    File File = new file ("D:\\test2.txt");    Bytesink.write (Files.tobytearray (file)); Assertthat (Files.tobytearray (dest), is (Files.tobytearray (file)));

Above we create a file object and then call the static method Files.asbytesink with the created file instance as a parameter. Then we call the Write method to write the bytes to their final destination. Finally, we assert that the file contains the expected content. There is also a method on the Bytesink class where we can write OutputStream objects.

Copy from Bytesource to Bytesink

Now we will show an example of copying the underlying bytes from the Bytesource instance to the Bytesink instance through the Bytesource and Bytesink classes. While this may seem obvious, there are some very important concepts. First, we deal with Bytesource and Bytesink instances at an abstraction level, we really don't need to know the original source, and secondly, the entire open and closed resource operation will be handled by us:

 @Testpublic  void copytobytesinktest ()  throws exception {    file dest = new file ("D:\\ Test.txt ");     dest.deleteonexit ();    file source =  New file ("D:\\test2.txt");    bytesource bytesource =  Files.asbytesource (source);     bytesink bytesink = files.asbytesink (dest);     bytesource.copyto (Bytesink);     assertthat (Files.toByteArray (dest) ,  is (Files.tobytearray (source)));} 

Here we create a bytesource and Bytesink instance with similar static methods in the Files class. We then call the Bytesource.copyto method to the write byte in the Bytesink object. We then assert that the content of the new file is the same as the content of the source file. Similarly, the Bytesink class also has a CopyTo () method that replicates bytes to outputstream.

Bytestreams and Charstreams

Bytestreams is a practical program class for handling InputStream and OutputStream instances, and Charstreams is a program class for working with reader and writer instances. Bytestreams and Charstreams provide a series of methods to manipulate files directly, similar to those provided by the files class. Some methods provide the ability to copy the entire contents of a stream or reader into another outputsupplier, OutputStream, or writer instance. There are a lot of detailed methods here, so let's learn some interesting ways.

Limit the size of the InputStream

    Bytesteams.limit method receives a InputStream parameter and a long value as the length, returning a The InputStream is decorated. Consider the following example:

@Testpublic void Limitbytestreamtest () throws Exception {file Binaryfile = new File ("D:\\test2.txt");    Bufferedinputstream InputStream = new Bufferedinputstream (new FileInputStream (Binaryfile));    InputStream Limitedinputstream = Bytestreams.limit (InputStream, 10);    Assertthat (Limitedinputstream.available (), is (10)); Assertthat (Inputstream.available (), is (218882));}

In the example above, we created a inputstream for the test file Text2.txt, and then we created a inputstream with a limit of 10 bytes through the Bytestreams.limit method, We then assert that verifying that our newly created finite inputstream correctly reads the number of bytes is 10, and we also assert whether the original stream is larger in size.

Connection Charstreams

    The Charstreams.join method connects multiple Inputsupplier instances and joins them so that they are logically represented as a inputsupplier instance and write their contents to a Outputsupplier instance:

@Testpublic  void jointest ()  throws exception {    file f1  = new file ("D:\\test.txt");     file f2 = new file ("D:\ \test1.txt ");     file f3 = new file (" D:\\test2.txt ");     file joinedoutput = new file ("D:\\test3.txt");     Joinedoutput.deleteonexit ();    list<inputsupplier<inputstreamreader>>  Inputsuppliers = getinputsuppliers (F1,&NBSP;F2,&NBSP;F3);    inputsupplier< Reader> joinedsupplier = charstreams.join (inputsuppliers);     outputsupplier<outputstreamwriter> outputsupplier =             files.newwritersupplier (joinedoutput, charsets.utf_8);     String expectedOutputString = joinfiles (F1,&NBSP;F2,&NBSP;F3);     charstreams.copy (joinedSupplier,  Outputsupplier);     string joinedoutputstring = joinfiles (joinedOutput);     assertthat (Joinedoutputstring, is (expectedoutputstring));} Private string joinfiles (file... files)  throws IOException {     stringbuilder builder = new stringbuilder ();    for  (File  file : files)  {        builder.append ( Files.tostring (file, charsets.utf_8));    }    return  Builder.tostring ();} Private list<inputsupplier<inputstreamreader>> getinputsuppliers (File... files)  {    List<InputSupplier<InputStreamReader>> list =           &nBsp; lists.newarraylist ();    for  (file file : files)  {         list.add (Files.newreadersupplier (file, Charsets.UTF_8));     }    return list;}

This is a big example, let's simply comb through the steps:

    1. We have created four file objects, including three source files and one output files that need to be connected

    2. In our tests we provided a method getinputsuppliers (), using the Files.newreadersupplier static factory method to create Inputsupplier objects for each source file

    3. After that we create inputsupplier to connect the Inputsupplier collection to a logical Inputsupplier

    4. Using the 4 file objects created in our first step, call the Files.newwritersupplier factory method to create a outputsupplier

    5. Using another private method Joinfiles, each file invokes the Files.tostring method to construct the value we want to test

    6. Call the Charstreams.copy method to write the contents of the supplied Inputsuppliers () to Outputsupplier

    7. We verify that the target file contains the same content as the three original files


The closer class in

    Guava is used to ensure that all registered Closeable objects are properly closed when the Closer.close method is invoked. The closer class is similar to the try-with-resources syntax behavior in Java 7, but can be used in a Java 6 environment. Using the closer class is very simple, as follows:

@Testpublic  void testcloser ()  throws ioexception {    closer  closer = closer.create ();    try {         file destination = new file ("D:\\test.txt");         destination.deleteonexit ();         Bufferedreader reader = new bufferedreader (New filereader ("D:\\test2.txt"));         bufferedwriter writer = new bufferedwriter (New  filewriter (destination));         closer.register (reader);         closer.register (writer);         String line;        while  (line =  Reader.readline ())  != null) &NBSP;{&NBSP;&NBsp;          writer.write (line);         }    } catch  (throwable t)  {         throw closer.rethrow (t);    } finally {         closer.close ();     }}

In the example above, we simply set up a copy of the text file. First, we create a closer instance, then create BufferedReader and BufferedWriter, and then register the objects with the closer instance that was created. We need to note that all of the methods mentioned here use Inputsupplier and outputsupplier to manage the shutdown of the underlying I/O resources through the closer class, and guava recommend that, in the case of raw I/O flow, readers, writers operations, It is best to use sources and Sinks.


When working with binary data, we sometimes need to convert the bytes representing the data into printable ASCII characters. Of course, we also need to be able to convert the encoded byte form into the original decoding. Baseencoding is an abstract class that contains many static factory methods that can create instances for different encoding methods. In the simplest form, we can use the Baseencoding class in the following ways :

 @Testpublic  void encodedecodetest ()   Throws exception {    file file = new file ("D:\\test2.txt");     byte[] bytes = files.tobytearray (file);     Baseencoding baseencoding = baseencoding.base64 ();     string encoded  = baseencoding.encode (bytes);     assertthat (Pattern.matches ("[A-Za-z0-9+/=]+"),  encoded), is (true)),     assertthat (Baseencoding.decode (encoded), is (bytes));} 

Here we use binary files and will byteencoded as aBASE64 encoded string. We assert that this is a string consisting entirely of ASCII characters. We then convert the encoded string back into bytes and assert that it equals our original byte. But the Baseencoding class gives us more flexibility than simply encoding and decoding byte arrays. We can decorate Outputsuplier, Bytesink, and writer instances so that the bytes are encoded sing Woo the same as they were written. Conversely, we can also decode Intputstream, Bytesource, and reader instances into strings. Take a look at the following example:

@Testpublic  void encodebytesinktest ()  throws exception {    file  file = new file ("D:\\test2.txt");     file encodedfile =  new file ("D:\\test3.txt");     encodedfile.deleteonexit ();     charsink charsink = files.ascharsink (encodedfile, charsets.utf_8);     baseencoding baseencoding = baseencoding.base64 ();    bytesink  Bytesink = baseencoding.encodingsink (charsink);     bytesource bytesource  = files.asbytesource (file);     bytesource.copyto (Bytesink);     string encodedbytes = baseencoding.encode ( ());     Assertthat (Encodedbytes, is (files.tostring (Encodedfile, charsets.utf_8));}

In the example above, we created a file object, one that provides the binaries, and the other is the original copy we are going to copy. Next, a Charsink instance is created from the file object. After that, the baseencoding instance is created to encode and decode the Base64 algorithm. We use baseencoding instances to decorate the charsink that were constructed before bytesink, so the bytes are automatically encoded sing Woo they are written. We then created the Bytesource instance for our target file and copied the bytes to our bytesink. We then assert that the byte encoding of our original file is consistent with the string converted to the destination file.


We learned how guava is turning on or off our I/O resources by using Inputsupplier and Outputsupplier. Also see how to use the Bytesource, Bytesink, Charsource, and Charsink classes. Finally, we learned to use the Baseencoding class to convert binary data into text. In the next series, we will do things by hashing classes and bloomfilter data structures, and optional classes that avoid null pointers.

Guava Library Learning: Learning Guava Files Series (ii)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.