java处理流 和节点流(在字节流和字符流中,又分为处理流和节点流)
Java中的I/O流分为两类:字节流和字符流。字节流主要用于读写二进制数据,而字符流则主要用于读写文本数据。在字节流和字符流中,又分为处理流和节点流。
节点流是直接连接到数据源或数据目的地的流,也就是说它们是直接操作文件的流,例如FileInputStream和FileOutputStream。节点流可以直接读写文件,但是不能对数据进行处理。
处理流是对节点流的包装,它们可以对数据进行处理,例如缓冲、压缩、加密等。处理流必须依附于一个节点流,它们通过对数据的处理来增强节点流的功能。例如BufferedInputStream和BufferedOutputStream就是处理流,它们可以提高节点流的读写效率。
处理流和节点流可以组合使用,例如使用FileInputStream读取文件时,可以使用BufferedInputStream进行缓冲,提高读取效率。而使用BufferedOutputStream写入文件时,则可以使用FileOutputStream作为节点流。
---转
基本介绍
1)节点流可以从一个特定的数据源读写数据,如:FileReader、FileWriter;
2)处理流(包装流)是“连接”在已存在的流(节点流或处理流)之上,为程序提供更为强大的读写能力,如:BufferedReader、BufferedWriter;
类属 | 分类 | 字节输入流 | 字节输出流 | 字符输入流 | 字符输出流 |
抽象基类 | InputStream | OutputStream | Reader | Writer | |
节点流 | 访问文件 | FileInuputStream | FileOutputStream | FileReader | FileWriter |
访问数组 | ByteArrayInuputStream | ByteArrayOutputStream | CharArrayReader | CharArrayWriter | |
访问管道 | PipedInputStream | PipedOutputStream | PipedReader | PipedWriter | |
访问字符串 | StringReader | StringWriter | |||
处理流 | 缓冲流 | BufferedInputStream | BufferedOutputStream | BufferedReader | BufferedWriter |
转换流 | InputStreamReader | OutputStreamWriter | |||
对象流 | ObjectInputStream | ObjectOutputStream | |||
抽象基类 | FilterInputStream | FilterOutputStream | FilterReader | FilterWriter | |
打印流 | PrintStream | PrintWriter | |||
推回输入流 | PushbackInputStream | PushbackReader | |||
特殊流 | DataInputStream | DataOutputStream |
节点流和处理流的区别和联系
1)节点流是底层流/低级流,直接跟数据源相接;
2)处理流包装节点流,即可以消除不同节点流的实现差异,也可以提供更方便的方法来完成输入输出;
3)处理流(包装流)对节点流进行包装,使用了修饰器设计模式,不会直接与数据源相连;
处理流的功能主要体现在以下两个方面:
1)性能的提高:主要以增加缓冲的方式来提高输入输出的效率;
2)操作的便捷:处理流可能提供了一系列的便捷方法,来一次输入输出大批量的数据,使用更加灵活方便。
字符处理流BufferedReader和BufferedWriter
★BufferedReader和BufferedWriter属于字符流,按照字符来读取数据;
★关闭时,只需要关闭外层流即可,包装流会自动关闭被包装的节点流。
BufferedReader测试代码
package com.pero.demo;
import org.junit.jupiter.api.Test;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class BufferedReader_ {
public static void main(String[] args) {
}
@Test
public void test() throws IOException {
String path = "d:\\:demo\\test\\Story.txt";
String line;
BufferedReader bufferedReader = new BufferedReader(new FileReader(path));
while ((line = bufferedReader.readLine()) != null){
System.out.println(line);
}
bufferedReader.close();
}
}
bufferedReader.close()源码
public void close() throws IOException {
synchronized (lock) {
if (in == null)
return;
try {
in.close();
} finally {
in = null;
cb = null;
}
}
}
BufferedWriter测试代码
package com.pero.demo;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
public class BufferedWriter_ {
public static void main(String[] args) throws IOException {
String path = "d:\\demo\\test\\Story.txt";
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(path,true));
String str = "床前明月光,疑是地上霜";
bufferedWriter.write('a');
bufferedWriter.write(str+'\n');
bufferedWriter.write(str.toCharArray(),0,5);
bufferedWriter.close();
}
}
使用BufferedReader和BufferedWriter进行文本拷贝
package com.pero.demo;
import org.junit.jupiter.api.Test;
import java.io.*;
public class BufferedCopy_ {
public static void main(String[] args) throws IOException {
String readerPath = "d:\\demo\\test\\Story.txt";
String writerPath = "d:\\demo\\test\\Book.txt";
char[] chars = new char[1024];
int length = 0;
BufferedReader bufferedReader = new BufferedReader(new FileReader(readerPath));
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(writerPath));
while((length = bufferedReader.read(chars)) != -1) {
bufferedWriter.write(chars,0,length);
}
bufferedReader.close();
bufferedWriter.close();
}
@Test
public void test(){
String readerPath = "d:\\demo\\test\\Story.txt";
String writerPath = "d:\\demo\\test\\Book.txt";
BufferedReader bufferedReader = null;
BufferedWriter bufferedWriter = null;
String line = null;
try {
bufferedReader = new BufferedReader(new FileReader(readerPath));
bufferedWriter = new BufferedWriter(new FileWriter(writerPath));
while ((line = bufferedReader.readLine()) != null){
bufferedWriter.write(line);
bufferedWriter.newLine();
}
} catch (IOException e) {
throw new RuntimeException(e);
}finally {
if (bufferedReader != null){
try {
bufferedReader.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
if (bufferedWriter != null){
try {
bufferedWriter.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
}
BufferedInputStream和BufferedOutputStream字节处理流
BufferedInputStream是字节输入缓冲流,在创建BufferedInputStream时,会创建一个内部缓冲区数组;BufferedOutputStream是字节输出缓冲流,实现缓冲的输出流,可以将多个字节写入底层输出流中,而不必对每次字节写入调用底层系统。
字节处理流拷贝文件
package com.pero.demo;
import org.junit.jupiter.api.Test;
import java.io.*;
public class BufferedCopy02_ {
public static void main(String[] args) throws IOException {
String inputPath = "C:\\Users\\Pero\\Desktop\\4.jpeg";
String outputPath = "d:\\demo\\test\\boom.jpeg";
int length = 0;
byte[] bytes = new byte[1024];
BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(inputPath));
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(outputPath));
while((length = bufferedInputStream.read(bytes)) != -1){
bufferedOutputStream.write(bytes,0,length);
}
System.out.println("文件拷贝完毕");
if (bufferedInputStream != null){
bufferedInputStream.close();
}
if (bufferedOutputStream != null){
bufferedOutputStream.close();
}
}
@Test
public void test(){
String inputPath = "C:\\Users\\Pero\\Desktop\\4.jpeg";
String outputPath = "d:\\demo\\test\\boom.jpeg";
BufferedInputStream bufferedInputStream = null;
BufferedOutputStream bufferedOutputStream = null;
int length = 0;
byte[] bytes = new byte[1024];
try {
bufferedInputStream = new BufferedInputStream(new FileInputStream(inputPath));
bufferedOutputStream = new BufferedOutputStream(new FileOutputStream(outputPath));
while((length = bufferedInputStream.read(bytes)) != -1){
bufferedOutputStream.write(bytes,0,length);
}
System.out.println("文件拷贝完毕");
} catch (IOException e) {
throw new RuntimeException(e);
}finally {
if (bufferedInputStream != null){
try {
bufferedInputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
if (bufferedOutputStream != null){
try {
bufferedOutputStream.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
}
对象流ObjectInputStream和ObjectOutputStream
将基本数据类型或者对象进行序列化和反序列化操作。
★序列化和反序列化
1)序列化是指保存数据时,保存数据的值和数据类型;
2)反序列化是指在恢复数据时,恢复数据的值和数据类型;
3)需要让某个对象支持序列化机制,则必须让其类是可序列化的,也就是让该类必须实现如下两个接口之一:
☆Serializable接口(标记接口)
☆Externalizable接口
ObjectOutputStream测试代码
package com.pero.demo;
import java.io.*;
public class ObjectOutputStream_ {
public static void main(String[] args) throws IOException {
String path = "d:\\demo\\test.dat";
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream(path));
objectOutputStream.write(100);
objectOutputStream.writeBoolean(true);
objectOutputStream.writeChar('a');
objectOutputStream.writeByte(11010);
objectOutputStream.writeObject(new Dog("tom",16));
objectOutputStream.close();
}
}
class Dog implements Serializable {
private String name;
private int age;
public Dog(String name, int age) {
this.name = name;
this.age = age;
}
}
ObjectInputStream测试代码
package com.pero.demo;
import java.io.*;
public class ObjectInputStream_ {
public static void main(String[] args) throws IOException {
String path = "d:\\demo\\test.dat";
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream(path));
System.out.println(objectInputStream.readInt());
System.out.println(objectInputStream.readBoolean());
System.out.println(objectInputStream.readChar());
System.out.println(objectInputStream.readByte());
System.out.println(objectInputStream.readUTF());
System.out.println(objectInputStream.readDouble());
try {
Object dog = objectInputStream.readObject();
System.out.println(dog.getClass());
System.out.println(dog);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
objectInputStream.close();
}
}
注意事项和细节
1)读写顺序一致;
2)实现序列化或反序列化对象,必须实现serializable或者Externalizable接口;
3)序列化的类中建议添加SeriaVersionUID,为了提高版本的兼容性;
4)序列化对象时,默认将所有属性都进行序列化,但除了static或transient修饰的成员;
5)序列化对象时,要求属性类型也要实现序列化接口;
6)序列化具备可继承性,某类实现了序列化,那么它的子类也默认实现了序列化。
标准输入输出流
编译类型 | 运行类型 | 默认设备 | |
System.in标准输入 | InputStream | BufferedInputStream | 键盘 |
System.out标准输出 | PrintStream | PrintStream | 显示器 |
package com.pero.demo;
public class InputAndOutput {
public static void main(String[] args) {
System.out.println(System.in.getClass());
System.out.println(System.out.getClass());
}
}
转换流InputStreamReader和OutputStreamWriter
1)InputStreamReader:Reader的子类,可以将InputStream(字节流)包装成(转换)Reader(字符流);
2)OutputStreamWriter:Writer的子类,可以将OutputStream(字节流)包装成Writer(字符流);
3)当处理纯文本数据时,如果使用字符流效率更高,并且可以有效解决中文问题,所以建议将字节流转换成字符流;
4)可以在使用时指定编码格式(UTF-8,gnk等等)。
InputStreamReader测试代码
package com.pero.demo;
import java.io.*;
public class Transformation_ {
public static void main(String[] args) throws IOException {
String path = "d:\\demo\\test\\next.txt";
InputStreamReader inputStreamReader = null;
char[] chars = new char[1024];
int length = 0;
inputStreamReader = new InputStreamReader(new FileInputStream(path),"utf8");
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String s = bufferedReader.readLine();
System.out.println(s);
bufferedReader.close();
}
}
OutputStreamWriter测试代码
package com.pero.demo;
import java.io.*;
public class OutputStreamWriter_ {
public static void main(String[] args) throws IOException {
String filePath = "d:\\demo\\test\\writer.txt";
String charSet = "utf-8" ;
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(
new FileOutputStream(filePath,true),charSet);
outputStreamWriter.write("hello,world");
outputStreamWriter.close();
System.out.println("文件按照"+charSet+"保存文件成功");
}
}
打印流PrintStream(字节打印流)和PrintWriter(字符打印流)
PrintStream测试代码
package com.pero.demo;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintStream;
public class PrintStream_ {
public static void main(String[] args) throws FileNotFoundException {
PrintStream out = System.out;
out.print("hello,world");
try {
out.write("完成打印".getBytes());
} catch (IOException e) {
throw new RuntimeException(e);
}
out.close();
System.setOut(new PrintStream("d:\\demo\\test.txt"));
System.out.println("打印完成");
}
}
PrintWriter测试代码
package com.pero.demo;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
public class PrintWriter_ {
public static void main(String[] args) throws IOException {
PrintWriter printWriter = new PrintWriter(
new FileWriter("d:\\demo\\test\\look.txt"));
printWriter.print("打印成功");
printWriter.close();
}
}
Properties类
properties是Hashtable的子类,读取和写入properties配置文件。
(BufferedReader+FileReader读取properties配置文件)
package com.pero.properties_;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class Properties01 {
public static void main(String[] args) throws IOException {
String read = null;
BufferedReader bufferedReader = new BufferedReader(
new FileReader("src\\mysql.properties"));
while ((read = bufferedReader.readLine()) != null) {
String[] split = read.split("=");
if ("ip".equals(split[0])) {
System.out.println(split[1]);
}
}
bufferedReader.close();
}
}
1)properties类是专门用于读写配置文件的集合类:
配置文件的格式:
键=值
键=值
2)键值对不需要有空格,值不需要引号引起来。默认类型是String。
3)Properties的常见方法:
①load()方法:加载配置文件的键值对到Properties对象;
②list()方法:将数据显示到指定设备;
③getProperty(key)方法:根据键获取值;
④setProperty(key,value)方法:设置键值对到Properties对象;
⑤store()方法:将Properties中的键值对存储到配置文件,在idea中,保存信息到配置文件,如果含有中文会存储为unicode码。
package com.pero.properties_;
import org.junit.jupiter.api.Test;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;
public class Properties02 {
public static void main(String[] args) throws IOException {
Properties properties = new Properties();
properties.load(new FileReader("src\\mysql.properties"));
String ip = properties.getProperty("ip");
System.out.println(ip);
properties.list(System.out);
}
@Test
public void test() throws IOException {
Properties properties = new Properties();
properties.setProperty("ip","192.168.1.1");
properties.setProperty("user","杰克");
properties.setProperty("pwd","987654");
properties.setProperty("pwd","654456");
properties.store(
new FileWriter("src\\mysql2.properties"),
null);
System.out.println("成功保存配置文件");
}
}
课后习题
package com.pero;
import org.junit.jupiter.api.Test;
import java.io.*;
public class Homework01 {
public static void main(String[] args) {
}
@Test
public void test() throws IOException {
String filePath = "d:\\mytemp";
File file = new File(filePath);
if(!file.exists()){
if (file.mkdirs()){
System.out.println("文件夹创建成功");
}else {
System.out.println("文件夹创建失败");
}
}else {
System.out.println("文件夹存在");
}
File fileHello = new File("d:\\mytemp\\hello.txt");
if (!fileHello.exists()){
if (fileHello.createNewFile()){
FileWriter fileWriter = new FileWriter(fileHello);
fileWriter.write("hello,world");
fileWriter.close();
System.out.println("文件创建成功");
}else {
System.out.println("文件创建失败");
}
}else {
System.out.println("文件已经存在,不再重复创建");
FileWriter fileWriter = new FileWriter(fileHello,true);
fileWriter.write("hello,world");
fileWriter.close();
}
}
}
package com.pero;
import org.junit.jupiter.api.Test;
import java.io.*;
public class Homework02 {
public static void main(String[] args) throws IOException {
String versePath = "d:\\books\\book\\verse.txt";
String line = null;
int temp = 1;
BufferedReader bufferedReader = new BufferedReader(new FileReader(versePath));
PrintStream out = System.out;
while ((line = bufferedReader.readLine()) != null) {
if (temp % 2 != 0) {
out.print(temp + line + "," + '\n');
} else {
out.print(temp + line + "。" + '\n');
}
temp++;
}
temp = 1;
bufferedReader.close();
out.close();
}
@Test
public void test() throws IOException {
String bookPath = "d:\\books\\book";
File file = new File(bookPath);
if (!file.exists()) {
if (file.mkdirs()) {
System.out.println("文件夹创建成功");
} else {
System.out.println("文件夹创建失败");
}
} else {
System.out.println("文件夹存在");
}
File fileVerse = new File(bookPath + "\\verse.txt");
if (!fileVerse.exists()) {
if (fileVerse.createNewFile()) {
System.out.println("诗词文本文件创建成功");
BufferedWriter bufferedWriter =
new BufferedWriter(
new FileWriter(bookPath + "\\verse.txt"));
bufferedWriter.write("锄禾日当午" + '\n' +
"汗滴禾下土" + '\n' +
"谁知盘中餐" + '\n' +
"粒粒皆辛苦");
System.out.println("诗词写入成功");
if (bufferedWriter != null) {
bufferedWriter.close();
}
} else {
System.out.println("诗词文本文件创建失败");
}
} else {
System.out.println("诗词文本文件已存在");
}
}
}
package com.pero;
import org.junit.jupiter.api.Test;
import java.io.*;
import java.util.Properties;
public class Homework03 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
Properties properties = new Properties();
FileReader fileReader = new FileReader("src\\dog.properties");
properties.load(fileReader);
String name = properties.getProperty("name");
int age = Integer.parseInt(properties.getProperty("age"));
String color = properties.getProperty("color");
Dog dog = new Dog(name, age, color);
System.out.println(dog);
String dogPath = "d:\\demo\\dog.dat";
ObjectOutputStream objectOutputStream =
new ObjectOutputStream(new FileOutputStream(dogPath));
objectOutputStream.writeObject(dog);
objectOutputStream.close();
System.out.println("dog对象序列化成功");
ObjectInputStream objectInputStream =
new ObjectInputStream(new FileInputStream(dogPath));
Dog dogSee = (Dog)objectInputStream.readObject();
System.out.println(dogSee);
objectInputStream.close();
}
@Test
public void test() throws IOException {
String dogSqlPath = "src\\dog.properties";
Properties properties = new Properties();
properties.setProperty("name","tom");
properties.setProperty("age","5");
properties.setProperty("color","red");
properties.store(new FileWriter(dogSqlPath),null);
System.out.println("dogSql文件保存成功");
}
}
class Dog implements Serializable{
private String name;
private int age;
private String color;
public Dog(String name, int age, String color) {
this.name = name;
this.age = age;
this.color = color;
}
@Override
public String toString() {
return "Dog{" +
"name='" + name + '\'' +
", age=" + age +
", color='" + color + '\'' +
'}';
}
}