Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”
This article has participated in the “Digitalstar Project” and won a creative gift package to challenge the creative incentive money.
IO stream
When working with streams, let’s see what it means to work with IO streams, one stream instance leveraging another stream instance.
Transmission of I/O streams
This will create higher-level functionality, where we can have one stream accessing the data, and then another stream retrieving the results of the data and handling more complex functionality.
Transparency between IO streams
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.
Transitivity between IO streams
-
The link is performed using the constructor, which constructs a higher-level instance of the flow, and then passes an instance of the lower-level flow.
-
The InputStreamReader class is a good example of an IO stream that takes advantage of receiving an InputStream by providing read behavior on it, which converts binary responses into character array 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
The working nature of IO streams
Don’t worry about how InputStream works. It doesn’t matter whether it’s supported by files or networks. All we know is that it’s going to give us binary data, pass it to us 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, so you should know that this is a very powerful concept.
File operation IO stream
Streams are often used 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, but are nonetheless widely used in code, so it’s worth mentioning.
Buffer type IO stream
Buffered streams were introduced to replace the File operation IO Stream classes 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
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 Buffered IO stream:
Various platforms, such as Windows or Unix, handle newlines, using the correct value for the current platform
-
BufferedWriter has one method: newLine(), which creates a newLine with the appropriate characters.
-
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
Java8 proprietary package
In Java 8, the use of java.io.FileXXX streams 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
- Obtain the Path object using the static Path factory method
- String-based hierarchical paths or URIs are converted to paths.
- Example: Path p = paths.get (” \documents\foo.txt “)
The file type
-
Static methods for interacting with files
-
Create, copy, delete, etc
Open file stream
- newBufferedReader
- newBufferedWriter
- newInputStream
- newOutputStream
Read/write file contents
- readAllLines
- write
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
Default 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.
Zip file system
Java also supports dedicated file systems, such as Zip file systems, to which Path instances are bound, and the Path class only applies to default instances. 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 FileSystem, Path instance factory
-
FileSystems: used for FileSystem the static FileSystem factory method is used to obtain objects and open or create FileSystem newFileSystem
Accessing the file system
File systems identified by URI: Zip File systems use jar: file
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
//make a new URI from the path
URI zipUri = new URI("jar:file", path.toUri().getPath(), null);
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.
A file named file.txt is created in the project library. This file will be copied 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