java-IO Programming

IO base

I 流

IO read and write data stream is a sequence pattern:

  • One-way flow
  • A byte as the minimum unit (a byte stream)

If the character is not a single-byte representation ASCLL code, Java also provide some solutions:

  • java also provides a reader, writer represents the character stream
  • The smallest unit of character streaming is char
  • Byte character stream output depends coding

reader, the writer is essentially a codec automatically InputStream / OutputStream: While using the reader reads the data source is a sub-section, but we read all the data types of characters char

Although an InputStream and read data are the same as the source byte sub-section, but we can encode binary byte array into a string and achieve the same effect reader
So how to choose reader and InputStream? It depends on the data source, if the data source is not a text can only use InputStream, if the text is easier to use reader.

Synchronous and asynchronous io io

Synchronization io:

  • When the code waits for the data write io returned after subsequent code continues
  • Simply write code execution efficiency is low cpu

Asynchronous io:

  • Only when a request to read and write io, and then execute the code immediately subsequent
  • Write code complexity, high efficiency cpu

java.io JDK provides a synchronous io, java.nio asynchronous io

File object

java.io.File represents a file system file or directory creation method: can be relative or absolute path

// windows
File f=new File("c:\\win\\note.exe");
// linux
File f=new File("/usr/bin/javac");
复制代码

Get the path / absolute path / paths specifications: getPath () / getAbsolutePath () / getCanonicalPath () determines a file or directory:

  • isFile (): Whether the file
  • isDirectory (): it is a directory

Note that to construct a File object, even if we pass the file or directory does not exist and will not error, because there is no any operation on the disk, only when calling certain methods if the file or directory does not exist until an error.
File operations:

  • canRead (): if allowed to read the file
  • canWrite (): whether to allow writing the file
  • canExecute (): Whether the file is allowed to run
  • length (): Get File Size
  • createNewFile (): Create a new file
  • static createTempFile (): creates a temporary file
  • delete (): delete the file
  • deleteOnExit (): delete the file when the JVM exits

Directory operations:

  • String [] list (): files and subdirectories under the name listed in the directory
  • File [] listFiles (): files and subdirectories under the name listed in the directory
  • File[] listFiles(FileFilter filter)
  • File[] listFiles(FilenameFilter filter)
  • mkdir (): to create the directory
  • mkdirs (): create the directory, and if necessary, the parent directory does not exist create it
  • delete (): delete the directory

Input和Output

InputStream

java.io.InputStream is the superclass of all input streams

  • int Read () Reads the next byte of data from the input stream, the byte int return value in the range 0 to 255. If the end of the stream has been reached because no byte is available, it returns -1. Before the input data is available, detecting the end of the stream or throw an exception, this method has been blocked.
  • Bytes int read (byte []) and filled into several bytes read byte [] array, the read return
  • read () method is blocking (blocking) of

Read the full InputStream all sub-sections

After the code transformation, using the cache to speed read:

package com.feiyangedu.sample;
import java.io.*;
public class Main {
	public static void main(String[] args) throws IOException {
		try (InputStream input = new FileInputStream("readme.txt")) {
			int n;
			byte[] buffer = new byte[1000];
			while ((n = input.read(buffer)) != -1) {
				System.out.println(n);
			}
		}
	}
}
复制代码

One problem with the above code, if io error occurs during reading, InputStream can not be closed properly resources were not released. After transformation, the code is as follows:

Or (wording JDK1.7 later)
The use of buffer reads more sub-sections, increase efficiency:
ByteArrayInputStream can simulate a InputStream in memory:
his role is to be an array into an InputStream, often for testing

OutputStream

OutputStream is the superclass of all output streams:

  • write (int b) Writes a byte
  • Write (byte []) write byte [] array all bytes
  • close (): close the output stream, using the try (resource) can be closed properly ensure OutputStream
  • flush () method of the contents of the output buffer is usually no need to manually invoke the automatic call

package com.feiyangedu.sample;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class Main {
	public static void main(String[] args) throws IOException {
		try (OutputStream output = new FileOutputStream("output.txt")) {
			byte[] b1 = "Hello".getBytes("UTF-8");
			output.write(b1);
			byte[] b2 = "你好".getBytes("UTF-8");
			output.write(b2);
		}
	}
}
复制代码

Examples of integrated input stream, the output stream, byte array buffer

InputStream input stream, OutputStream output stream, ByteArrayInputStream input buffer, ByteArrayOutStream coordinated use of the output buffer.

The input stream and output stream can be likened to both ends of the pipe, when the water flow in and out from a string file or the completion point to another, or converting the movement through the outlet (the OutputStream) through the inlet (the InputStream), in the process do not seem to the intervention of the buffer. So what will be used when the buffer it? When you want to have many operations in the middle of the input and output streams, or the input stream "copy" a time to do another operation is necessary to use a buffer. For example, we upload pictures, for greater security, to judge by the first four strings of the file type of file: (a write instance)

// 创建输出流缓冲区
 ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len;
while ((len = file.read(buffer)) > -1 ) {
    baos.write(buffer, 0, len);
}
// 将缓冲区数据写入到数组中
baos.flush();
// 关闭文件
baos.close();

// 创建输出流缓冲区,将输入流缓冲区的数据写入到输入流缓冲区中,这样就实现了一次输入多次输出的效果
InputStream getType = new ByteArrayInputStream(baos.toByteArray()); // 拿去检测文件类型
InputStream fileImg = new ByteArrayInputStream(baos.toByteArray()); // 如果文件类型合法,拿去上传文件

复制代码

to sum up

  • OutputStream is the superclass of all output streams
  • FileOutputStream realized the stream output file
  • ByteArrayOutStream analog output stream of bytes in a memory
  • Use try (resource) can be closed properly to ensure OutputStream

Filter mode

Has FileInputStream (), for example, he reads data from a file, the final data source.

Conventional practice to add functionality in the FileInputStream

If we add to give FileInputStream buffer function: BufferedFileInputStream extends FileInputStreamderive a BufferedFileInputStream if FileInputStream added to calculate a signature feature: DigestFileInputStream extends FileInputStreamderive a DigestFileInputStream ..... If you want to add more functionality you need more subclasses to extend, so do disadvantages caused subclass explosion

The JDK Filter mode

JDK in order to solve the above problem InputStream divided into two categories:

  • Provide direct data InputStream :( real source of the data)
    • FileInputStream
    • ByteArrayInputStream
    • ServletInputStream
    • ...
  • Additional features provide additional InputStream:
    • BufferedInputStream
    • DigestInputStream
    • CipherInputStream
    • ...

how to use

Combination: Copy an object variable to another object, its characteristics and method of holding another object when we use our InputStream according to the actual situation combination use:

The figure above shows the FileInputStream provide data twice after packaging, it has more features, but no matter how many times after the package he can still upcast InputStream then follow.

Filter pattern known as Decorator pattern, combinations of various functions realized by a small number of classes.

InputStream inheritance tree

FilterInputStream effect is used to "package other input streams, and to provide additional functionality for them." It is commonly used and the subclasses BufferedInputStream DataInputStream. One side is implemented to provide data class, the implementation class while providing additional functionality. More functions implemented by combinations of classes sides.

Personal understanding: providing data class can not achieve similar packaging, and can function like the same package.

Examples

package com.feiyangedu.sample;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.GZIPInputStream;

public class Main {

	public static void main(String[] args) throws IOException {
		try (InputStream input = new GZIPInputStream(new BufferedInputStream(new FileInputStream("test.txt.gz")))) {
			ByteArrayOutputStream output = new ByteArrayOutputStream();
			byte[] buffer = new byte[1024];
			int n;
			while ((n = input.read(buffer)) != -1) {
				output.write(buffer, 0, n);
			}
			byte[] data = output.toByteArray();
			String text = new String(data, "UTF-8");
			System.out.println(text);
		}
	}

}
复制代码

The number of bytes to write custom tools read calculated

import java.io.*;
import java.util.zip.GZIPInputStream;

public class Main {

	public static void main(String[] args) throws IOException {
		try (InputStream input = new CountInputStream(new GZIPInputStream(new BufferedInputStream(new FileInputStream("test.txt.gz"))))) {
			ByteArrayOutputStream output = new ByteArrayOutputStream();
			byte[] buffer = new byte[1024];
			int n;
			while ((n = input.read(buffer)) != -1) {
				output.write(buffer, 0, n);
			}
			byte[] data = output.toByteArray();
			String text = new String(data, "UTF-8");
            // 打印内容
			//System.out.println(text);
			//由于我们要使用count方法,因此要将InputStream类型向下转型为CountInputStream,因为我们明确的知道继承关系这里可以不判断是否可以安全的向下转型
			System.out.println(InputStream.class.isAssignableFrom(CountInputStream.class));
			System.out.println(((CountInputStream) input).count);
		}
	}
}
class CountInputStream extends FilterInputStream {
	int count=0;
	public CountInputStream(InputStream in) {
		super(in);
	}

	@Override
	public int read(byte[] b, int off, int len) throws IOException {
		//通过调用父类的read方法获取包装的inputStream的字节长度
		int n = super.read(b, off, len);
		count +=n;
		return n;
	}
}

复制代码

Export

true
11356
复制代码

About bytes (important)

InputStream the read () and read (byte [] b)

Found that the process of learning the representative value of the byte value returned (0-255), using read (byte [] b) Return the byte read length, and if the value of the byte used read () is stored in the byte[] bb variable types Why would such a result?
First look JDK explanation: InputStream the read () method reads the next byte of data from the input stream, the byte int return value in the range 0 to 255.
So the question is what byte values range from 0 to 255?
Simple Explanation: 00000000a byte consists of 8-bit binary value, which changes each 8-bit binary number, a total of 2 ^ 8 = 256 kinds of numbers, 0 ~ so () Returns the value of each is from 0 to 255, the Read InputStream 255, the int type 10 hexadecimal values can be converted into a binary number eight character types: char, char because of java unicode will be used, it can be directly assigned to the int type to see him unicode encoded in turn is a type int (char) int can be directly converted to char character

ab中国cdefj
复制代码
import java.io.*;
import java.util.zip.GZIPInputStream;

public class Main {

	public static void main(String[] args) throws IOException {
		InputStream in = null;
		File f = new File("test.txt");
		in = new FileInputStream(f);
		int i = 0;
		while ((i = in.read()) != -1) {
			//String str = new String((char)i);
			System.out.println((char)i);
		}
	}
}
复制代码

Export

a
b
ä
¸
­
å
›
½
c
d
e
f
j
复制代码

The above program demonstrates read()an int and returns a single byte read by (char)icasts and then outputs a single character, since in Chinese accounted portion 3 so Chinese characters garbled

The following code shows byte [] data read

import java.io.*;
import java.util.zip.GZIPInputStream;

public class Main {

	public static void main(String[] args) throws IOException {
		InputStream in = null;
		File f = new File("test.txt");
       //当一次读取3个字节的时候如果凑巧全是中文,或者从第四个字节开始是中文,就不会出现乱码,如果不是就会出现乱码
		byte[] b = new byte[3];

		in = new FileInputStream(f);
		int i = 0;
		while ((i = in.read(b)) != -1) {
        //String函数可以接收一个char数组或者byte数组然后转换成字符串
			String str = new String(b);
			System.out.println(str);
		}
	}
}
复制代码

Here are two demo data: not garbled, because the first three words is a Chinese holiday, each three bytes just read a Chinese character

abc中国cdefj
复制代码

display effect

abc
中
国
cde
fje
复制代码

If there is no previous c

ab中国cdefj
复制代码

Will be garbled output

ab�
���
��c
def
jef
复制代码

Operation Zip

ZipInputStream inherited from FlaterInputStream realized ZipConstants interface, although ZipInputStream is FlaterInputStream subclass but some ZipInputStream method is unique, not upward transition in the use of these methods, the use of ZipInputStream when created directly without the need for a transformation of his example upward,

Zip ZipInputStream stream can be read. JarInputStream provides additional capability to read the contents of the jar package. ZipOutputStream can write Zip stream. With FileInputStream and FileOutputStream can read and write Zip files.

package com.feiyangedu.sample;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

public class Main {

	public static void main(String[] args) throws IOException {
		try (ZipInputStream zip = new ZipInputStream(new BufferedInputStream(new FileInputStream("test.jar")))) {
			ZipEntry entry = null;
			while ((entry = zip.getNextEntry()) != null) {
				if (entry.isDirectory()) {
					System.out.println("D " + entry.getName());
				} else {
					System.out.println("F " + entry.getName() + " " + entry.getSize());
					printFileContent(zip);
				}
			}
		}
	}

	static void printFileContent(ZipInputStream zip) throws IOException {
		ByteArrayOutputStream output = new ByteArrayOutputStream();
		byte[] buffer = new byte[1024];
		int n;
		while ((n = zip.read(buffer)) != -1) {
			output.write(buffer, 0, n);
		}
		byte[] data = output.toByteArray();
		System.out.println("  size: " + data.length);
	}

}

复制代码

classpath resources (linux and win the path of a difference)

In classpath may comprise any type of file. Avoid inconsistent file paths under different environmental problems reading the file from the classpath. Read classpath resources:

try(InputStream input = getClass().getResourceAsStream("/default.properties")) {
    if (input != null) {
        // Read from classpath
    }
}
复制代码
  • To avoid the file path-dependent resources are stored in the classpath
  • the getResourceAsStream object class () can read the resource from the classpath
  • You need to check whether the returned InputStream is null
package com.feiyangedu.sample;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Properties;

public class Main {

	public static void main(String[] args) throws IOException {
		// 从classpath读取配置文件:
		try (InputStream input = Main.class.getResourceAsStream("/conf.properties")) {
			if (input != null) {
				System.out.println("Read /conf.properties...");
				Properties props = new Properties();
				props.load(input);
				System.out.println("name=" + props.getProperty("name"));
			}
		}
		// 从classpath读取txt文件:
		String data = "/com/feiyangedu/sample/data.txt";
		try (InputStream input = Main.class.getResourceAsStream(data)) {
			if (input != null) {
				System.out.println("Read " + data + "...");
				BufferedReader reader = new BufferedReader(new InputStreamReader(input, "UTF-8"));
				System.out.println(reader.readLine());
			} else {
				System.out.println("Resource not found: " + data);
			}
		}
	}

}
复制代码

conf.properties

name=Java IO
url=www.feiyangedu.com
复制代码

Serialization

Refers to the sequence of the Java object becomes a binary content (byte []) to achieve Java object serialization must implement the Serializable interface (air interface) refers to the deserialization a binary content (byte []) into Java objects using ObjectOutputStream ObjectInputStream and implement serialization and de-serialization readObject () may throw an exception:

  • ClassNotFoundException: find no corresponding Class
  • InvalidClassException: Class does not match
  • Deserialize constructed by the JVM Java objects directly, do not call the constructor
  • SerialVersionUID version number may be provided as a (non-essential)

Reader与InputStream

Reader and InputStream difference:

Reader in characters minimum unit to achieve a character stream input:

  • int Read () reads a character and returns the next character int value (0-65535)
  • int read (char []) reads several characters and filled into char [] array used Reader categories:
  • FileReader: read from file
  • CharArrayReader: [] array from the read char

Read files intact examples

The use of buffer to read the file
FileReader can be obtained from a file Reader: But be careful here use the system default encoding
CharArrayReader can simulate a Reader in memory:

Reader's relationship with InputStream

Reader InputStream is based on the configuration of any InputStream can be specified by the encoding and converted into Reader InputStreamReader:

Reader reader = new InputStreamReader(input, "UTF-8")
复制代码

Internal holds a FileReader FileInputStream

import java.io.*;

public class Main {

	public static void main(String[] args) throws IOException {
		try (Reader reader = new InputStreamReader(new FileInputStream("readme.txt"),"UTF-8")) {
			int n;
			while ((n = reader.read()) != -1) {
				System.out.println((char) n);
			}
		}
	}

}
复制代码

Writer与OutputStream

The difference between Writer and OutputStream

Writer in characters minimum unit to achieve a character stream output:

  • write (int c) writing the next character (0-65535)
  • Write (char []) write char [] array all characters
  • write (char [] c, int off, int len) specified range of characters written
  • write (String s) written character string representation

Writer commonly used categories:

  • FileWriter: write to file
  • CharArrayWriter: write char [] array

Write characters to the Writer:

FileWriter can be obtained from a file Writer:
CharArrayWriter can simulate a memory Writer:

Writer and OutputStream of relationship

Writer OutputStream is based on the configuration of any OutputStream can be specified by the encoding and converted into Writer OutputStreamWriter:

Writer writer = new OutputStreamWriter(output, "UTF-8")
复制代码

Guess you like

Origin juejin.im/post/5dae654e51882568691fb924