Chain flow
When using streams, they are usually linked together.
Let’s look at the advantages of using linked streams:
- A stream instance leverages another stream instance.
- This creates higher-level functionality. We can have one stream accessing the data, and then another stream retrieving the results of the data and handling more complex functions.
- This simplifies reusability because you can organize flows in a way that allows each flow to perform specific work. That way, they don’t need to know each other’s inner workings.
We use constructors to perform links. We construct a higher-level instance of the flow and pass an instance of the lower-level flow. The InputStreamReader class is a good example of a chained stream. This class takes advantage of the link InputStream_ by providing reader behavior on. It converts binary responses into character behavior.
Let’s see how it works.
`void doChain(InputStream in) throws IOException{` `int length; ` `char[] buffer = new char[128]; ` `try(InputStreamReader rdr = new InputStreamReader(in)) {` `while((length = rdr.read(buffer)) >= 0) {` `//do something` `}` `}` `}`Copy the code
We don’t need to worry about how InputStream works. It doesn’t matter whether it’s supported by files or networks. The only thing we know is that it’s going to give us binary data, and we’re going to pass it to our InputStreamReader and convert it to binary data and we can use it as character data.
Notice that we also use try-with-resources here. If we close InputStreamReader, its InputStream also closes automatically. You should know that this is a very powerful concept.
Files and buffered streams
We often use streams to access files.
The _java. IO package has several classes to use, such as:
- FileReader
- FileWriter
- FileInputStream
- FileOutputStream
The real truth is that these file streams are now deprecated. Still, they are widely used in code, so they are worth mentioning.
Buffer flow
Buffer streams were introduced to replace the FileStream class in the _java.io_ package. These new Streams are placed under the _java.nio_ package. This is necessary because direct file access can be inefficient and buffered streams can be significantly more efficient in the following ways:
- Buffer the contents of memory
- Read/write in bulk
- Reduce low-level flow interactions
Buffering is available for all four stream types:
- BufferReader
- BufferWriter
- BufferedInputStream
- BufferedOutputStream
They are very simple to use.
`try(BufferedReader br = new BufferedReader(new FileReader("file.txt"))){` `int value; ` `while((value = br.read()) >= 0) {` `char charValue = (char)value; ` `//do something` `}` `}`Copy the code
Benefits of using BufferedStreams:
- It handles newlines for a variety of platforms, such as Windows or Unix
- Use the correct values for the current platform
- The BufferedWriter has one method: newLine() _._ which creates a newLine with the appropriate characters.
- The BufferedReader has a row-based reading method: readLine().
Let’s see how they work.
BufferedWriter:
`void writeData(String[] data) throws IOException {` `try(BufferedWriter bw = new BufferedWriter(new FileWriter("file.txt"))){` `int value; ` `for(String str : data) {` `bw.write(str); ` `bw.newLine(); ` ` `} ` `}Copy the code
BufferedReader:
`void readData(String[] data) throws IOException {` `try(BufferedReader br = new BufferedReader(new FileReader("file.txt"))){` `String inValue; ` `while((inValue = br.readLine()) ! = null) {` `System.out.println(inValue); ` ` `} ` `}Copy the code
The above code will write out the contents of the file line by line.
Access files using the java.nio.file package
In Java 8, the _java.io.FileXXX_ stream is deprecated. There is a new package for handling file streams called the java.nio.file package.
This package has several benefits over java.io:
- Better exception reporting
- With greater scalability, they work better with large files
- More file system features are supported
- Simplify common Tasks
Path and Paths types
Path:
- Used to find file system entries
- It can be a file or a directory
Paths:
- Used to get a Path object through the static Path factory method
- It converts a layered string-based Path or URI to a Path.
Example: Path p = paths.get (” \\documents\ foo.txt “)
The file type
- Static methods for interacting with files
- Create, copy, delete…
- Open file stream
NewBufferedReader newBufferedWriter 3 newInputStream 4 newOutputStreamCopy the code
- Read/write file contents
'1, readAllLines'' 2, writeCopy the code
Reading Lines With BufferedReader
`void readData(String[] data) throws IOException {` `try(BufferedReader br = Files.newBufferedReader(Paths.get("data.txt")){` `String inValue; ` `while((inValue = br.readLine()) ! = null) {` `System.out.println(inValue); ` `} ` `} ` ` `}Copy the code
Read All lines
`void readAllLines(String[] data) throws IOException {` `List<String> lines = Files.readAllLines(Paths.get("data.txt")); ` `for(String line:lines) {` `System.out.println(); ` ` `} ` `}Copy the code
The file system
When we use files in a Java program, these files are contained in the file system. Most commonly, we use the computer’s default file system.
Java also supports dedicated file systems, such as _Zip file _ system.
The Path instance is bound to the file system, and the Path class only applies to the default instance. So we need another solution. Fortunately, in the _java.nio_ package, we had the opportunity to address this problem.
File System Type
FileSystem
- Represents a single file system
- Path instance Factory
FileSystems
- Get objects from the static FileSystem factory method
- Open or create file system newFileSystem
Accessing the file system
The file system identified by the URI
- The details of urIs vary widely between file systems
- Zip file system using theThe jar: file“Scheme _jar: files: /documents/data.zip_
The file system supports custom attributes
- Each file system type is different
- Example: string encoding, whether to create if it does not exist
Create a Zip file system
`public static void main(String[] args) throws FileNotFoundException, IOException {` `try (FileSystem zipFileSystem = openZip(Paths.get("data.zip"))){ //pass the Path where we would like to create our FileSystem` `}catch (Exception e) {` `System.out.println(e.getClass().getSimpleName() + " - " + e.getLocalizedMessage());; ` `}` `}` `private static FileSystem openZip(Path path) throws URISyntaxException, IOException {` `Map<String, String> properties = new HashMap<>(); ` `properties.put("create", "true"); //set the property to allow creating` `URI zipUri = new URI("jar:file", path.toUri().getPath(), null); //make a new URI from the path` `FileSystem zipFileSystem = FileSystems.newFileSystem(zipUri, properties); //create the filesystem` `return zipFileSystem; ` ` `}Copy the code
After the code above, you should see the _data.zip_ file in the directory.
Copy files to the Zip file system
Let’s extend the above example with a file copy operation.
In this example, I create a file called file.txt_ in the project library. We will copy this file to our _data.zip_ file system.
`try (FileSystem zipFileSystem = openZip(Paths.get("data.zip"))){` `copyFileToZip(zipFileSystem); //Here we call the file copy` `}catch (Exception e) {` `System.out.println(e.getClass().getSimpleName() + " - " + e.getLocalizedMessage());; ` `}` `}` `private static FileSystem openZip(Path path) throws URISyntaxException, IOException {` `Map<String, String> properties = new HashMap<>(); ` `properties.put("create", "true"); ` `URI zipUri = new URI("jar:file", path.toUri().getPath(), null); ` `FileSystem zipFileSystem = FileSystems.newFileSystem(zipUri, properties); ` `return zipFileSystem; ` `}` `static void copyFileToZip(FileSystem zipFileSystem) throws IOException{` `Path sourceFile = FileSystems.getDefault().getPath("file.txt"); //Read the file to copy` `Path destFile = zipFileSystem.getPath("/fileCopied.txt"); //get the path of the new file` `Files.copy(sourceFile, destFile); //Copy the file to our zip FileSystem` `}`Copy the code
After running the code, you should see _filecopied.txt_ in the zip file. Its context should be the same as _ in our file.txt. _
summary
In this article, you examine flows in Java 8. Demonstrates how stream linking works and how files are processed through the new _java.nio_ package. I also talked about why you should use more of the latest buffered versions of file streams.