学习博客:IO流之处理流
作者:互联网
处理流/包装流”连接“在已存在的流(节点流和处理流)之上,拥有更强大的读写功能、更灵活(BufferedReader、BufferedWriter)
消除不同节点流之间的实现差异,提供更方便的方法完成输入输出
使用修饰器设计模式,不会直接与数据源相接
提高性能:以增加缓冲的方式提高输入输出的效率
方便操作:一次大批量输入输出数据
1.BufferReader
import java.io.BufferedReader;
import java.io.FileReader;
public class BufferReader_ {
public static void main(String[] args) throws Exception{
//路径
String filePath = "D:\\test1.txt";
//创建对象
BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath));
//读取
String line;
while((line = bufferedReader.readLine()) != null){ //按行读取,返回null则读取完毕
System.out.println(line);
}
//关闭外层即可,底层会自动关闭节点流
bufferedReader.close();
}
}
2.BufferWriter
import java.io.BufferedWriter;
import java.io.FileWriter;
public class BufferWriter_ {
public static void main(String[] args) throws Exception{
//路径
String filePath = "D:\\qqq.txt";
//创建BufferedWriter
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filePath));
bufferedWriter.write("hi,java");
bufferedWriter.newLine();
bufferedWriter.write("hi,php");
bufferedWriter.newLine();
bufferedWriter.write("hi,python");
bufferedWriter.newLine();
bufferedWriter.close();
}
}
应用
import java.io.*;
//BufferedReader和BufferedWriter是安装字符操作 避免操作二进制文件,会造成文件损坏
public class BufferedCopy_ {
public static void main(String[] args){
String srcFilePath = "D:\\qqq.txt";
String destFilePath = "D:\\1\\qqq.txt";
BufferedReader br = null;
BufferedWriter bw = null;
String line;
try {
br = new BufferedReader(new FileReader(srcFilePath));
bw = new BufferedWriter(new FileWriter(destFilePath));
while((line = br.readLine()) != null){
bw.write(line); //读一行写一行
bw.newLine(); //插入换行
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(br != null){
br.close();
}
if(bw != null){
bw.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
2.BufferedInputStream\BufferedOutputStream
缓冲字节输入流 BufferedInputStream,在创建BufferedInputStream时,会创建一个内部缓冲区数组
缓冲字节输出流 BufferedOutputStream,实现缓冲的输出流,可以将多个字节写入底层输出流中,不必对每次字节写入调用底层系统
字节流可以操作二进制文件,字符流不能操作二进制文件
应用
import java.io.*;
//二进制文件拷贝
public class BufferedCopy__ {
public static void main(String[] args) {
//路径
String srcFilePath = "D:\\IMG_7489.JPG";
String destFilePath = "D:\\1\\h.JPG";
//创建BufferedInputStream对象和BufferedOutputStream对象
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
bis = new BufferedInputStream(new FileInputStream(srcFilePath));
bos = new BufferedOutputStream(new FileOutputStream(destFilePath));
//循环读取文件,写入destFilePath
byte[] buff = new byte[1024];
int readLen = 0;
while((readLen = bis.read(buff)) != -1){
bos.write(buff, 0, readLen);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(bis != null){
bis.close();
}
if(bos != null){
bos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println("拷贝成功");
}
}
3.序列化与反序列化
1.仅将程序(内存)中的数据写入至文件(磁盘),保存的是值
2.将程序(内存)中的保存值和数据类型写入至文件(磁盘),称作序列化
3.将保存在文件的数据(值和数据类型)恢复至程序,称作反序列化
4.若某个对象支持序列化机制,其类必须是可序列化的,需要是实现两个接口之一(Serializable(标记接口,没有方法)、Externalizable(需要是实现方法))
3.1 对象字节输出流 ObjectOutputStream(序列化)
创建一个Person类
import java.io.Serializable;
public class Person implements Serializable {
private String name;
private int age;
//序列化对象时,默认将其所有属性都序列化,除static和transient修饰的成员
private transient String nation;
private static String city;
//序列化对象时,其属性的类型也需要实现序列化接口
private Hobby hobby = new Hobby();
//serialVersionUID序列化版本号,可提高兼容性
private static final long serialVersionUID = 1L;
public Person(String name, int age, String nation, String city) {
this.name = name;
this.age = age;
this.nation = nation;
this.city = city;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getNation() {
return nation;
}
public void setNation(String nation) {
this.nation = nation;
}
public static String getCity() {
return city;
}
public static void setCity(String city) {
Person.city = city;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", nation='" + nation + '\'' +
'}' + city + hobby;
}
}
实现序列化
import com.yl.IO.Person;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
public class ObjectOutputStream_ {
public static void main(String[] args) throws Exception {
String filePath = "D:\\data.dat";
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath));
//序列化数据
oos.writeInt(10); //int -> Integer (实现了Serializable)
oos.writeBoolean(true); //boolean -> Boolean (实现了Serializable)
oos.writeChar('q'); //char -> Charactor (实现了Serializable)
oos.writeDouble(3.14159); //double -> Double (实现了Serializable)
oos.writeUTF("杨杨杨"); //String
//保存一个Person对象
oos.writeObject(new Person("架构师", 28, "china", "beijing"));
oos.close(); //关闭流
System.out.println("序列化成功");
}
}
3.2 对象字节输入流 ObjectInputStream(反序列化)
import com.yl.IO.Person;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
public class ObjectInputStream_ {
public static void main(String[] args) throws IOException, ClassNotFoundException {
String filePath = "D:\\data.dat";
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filePath));
//读取(反序列化)的顺序需要和保存数据(序列化)的顺序一致
System.out.println(ois.readInt());
System.out.println(ois.readBoolean());
System.out.println(ois.readChar());
System.out.println(ois.readDouble());
System.out.println(ois.readUTF());
Object person = ois.readObject();
System.out.println("运行类型:" + person.getClass());
System.out.println("对象信息:" + person); //底层 Object -> Person
//若调用Person类中的方法,则需要向下转型,Person类必须在可以引用到的位置
Person person2 = (Person)person;
System.out.println(person2.getName());
ois.close(); //关闭流
}
}
小结
1.读写顺序一致
2.要求实现序列化\反序列化对象,需要实现Serializablea
3.序列化的类中添加序列化版本号 private static final long serialVersionUID = 1L 可以提高版本兼容性
4.序列化对象时,默认将其所有属性都序列化,除static和transient修饰的成员
5.序列化对象时,要求其属性的类型也要是实现序列化接口
6.序列化具备可继承性,若某类已实现序列化,则其所有子类也默认实现了序列化
4.标准输入输出流
System.in 标准输入 InputStream 键盘
System.out 标准输出 PrintStream 显示器
public class InputAndOutput {
public static void main(String[] args) {
//System类的 public final static InputStream in = null;
//System.in 编译类型 InputStream
//System.in 运行类型 BufferedInputStream
//标准输入 键盘
System.out.println(System.in.getClass());
//System.out public final static PrintStream out = null;
//编译类型 PrintStream
//运行类型 PrintStream
//标准输出 显示器
System.out.println(System.out.getClass());
}
}
应用
1.System.out.println() 使用out对象将数据输出到显示器
2.Scanner scanner = new Scanner(System.in) 从标准输入键盘接受数据
5.转换流
InputStreamReader是Reader的子类,可将InputStream(字节流)包装成Reader(字符流)
OutputStreamWriter是Writer的子类,可将OutputStream(字节流)包装成Writer(字符流)
处理纯文本数据时,若使用字符流效率更高,且可解决中文乱码问题,则将字节流转换成字符流
指定编码格式,UTF-8,GBK,GB2312,ISO-8859-1
文件乱码可由转换流解决
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class CodeQ {
public static void main(String[] args) throws IOException {
//路径
String filePath = "D:\\run.txt";
//创建字符输入流 BufferedReader
BufferedReader br = new BufferedReader(new FileReader(filePath));
//默认 utf-8 若改成其他编码会出现乱码,以ANSI为例
String s = br.readLine();
System.out.println(s);
br.close();
}
}
5.1 InputStreamReader
import java.io.*;
public class InputStreamReader_ {
public static void main(String[] args) throws IOException {
//路径
String filePath = "D:\\run.txt";
//FileInputStream 转换成 InputStreamReader
//InputStreamReader isr = new InputStreamReader(new FileInputStream(filePath),"GBK");
//将InputStreamReader 传入 BufferedReader
//BufferedReader br = new BufferedReader(isr);
BufferedReader br = new BufferedReader(new InputStreamReader(
new FileInputStream(filePath),"GBK"));
String s = br.readLine();
System.out.println(s);
br.close();
}
}
5.2 OutputStreamWriter
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
public class OutputStreamWriter_ {
public static void main(String[] args) throws IOException {
//路径
String filePath = "D:\\yl.txt";
String charset = "GBK";
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(filePath), charset);
osw.write("哈喽,Java");
osw.close();
System.out.println("以" + charset + "方式保存文件成功");
}
}
6.打印流
只有输出流,没有输入流
6.1 字节打印流 PrintStream
import java.io.IOException;
import java.io.PrintStream;
public class PrintStream_ {
public static void main(String[] args) throws IOException {
PrintStream out = System.out;
out.println("hi,java");
/* //print的底层方法是write
public void print(String s) {
if (s == null) {
s = "null";
}
write(s);
}*/
out.write("hi,杨杨杨".getBytes());
out.close();
//修改打印流输出的位置\设备
System.setOut(new PrintStream("D:\\rain.txt"));
/* public static void setOut(PrintStream out) {
checkIO();
setOut0(out); //native方法,修改了out
}*/
System.out.println("hi,杨杨杨");
}
}
6.2 字符打印流 PrintWriter
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(System.out);
//重定向
PrintWriter printWriter = new PrintWriter(new FileWriter("D:\\yly.txt"));
printWriter.print("hi,跑步");
printWriter.close();
}
}
7.Properties
专门读写配置文件的集合类
格式:键=值
键值对不需要空格,值不需要引号,默认类型:String
新建mysql.properties
ip=192.168.1.1
user=admin
pwd=mima123
使用Properties类读取文件
import java.io.FileReader;
import java.io.IOException;
import java.util.Properties;
public class Properties1 {
public static void main(String[] args) throws IOException {
//使用Properties类读取mysql.properties文件
//创建Properties对象
Properties properties = new Properties();
//加载指定配置文件
properties.load(new FileReader("src\\mysql.properties"));
//显示K-V至控制台
properties.list(System.out);
//根据键获取对应的值
String user = properties.getProperty("user");
String pwd = properties.getProperty("pwd");
System.out.println("用户名:" + user);
System.out.println("密码:" + pwd);
}
}
使用Properties类修改文件
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;
public class Properties2 {
public static void main(String[] args) throws IOException {
//使用Properties类创建、配置文件,修改配置文件内容
Properties properties = new Properties();
//若文件没有key,为创建
//有key,为修改
/*
Properties父类是Hashtable,底层是Hashtable
public synchronized V put(K key, V value) {
// Make sure the value is not null
if (value == null) {
throw new NullPointerException(); //值为空则抛出空指针异常
}
// Makes sure the key is not already in the hashtable.
Hashtable.Entry<?,?> tab[] = table;
int hash = key.hashCode(); //计算哈希值,相同则判定为替换
int index = (hash & 0x7FFFFFFF) % tab.length;
@SuppressWarnings("unchecked")
Hashtable.Entry<K,V> entry = (Hashtable.Entry<K,V>)tab[index];
for(; entry != null ; entry = entry.next) {
if ((entry.hash == hash) && entry.key.equals(key)) {
V old = entry.value;
entry.value = value; //如果key存在则替换
return old;
}
}
addEntry(hash, key, value, index); //如果是新key则addEntry
return null;
}*/
properties.setProperty("charset","utf-8");
properties.setProperty("user","超级admin"); //保存中文 -> 保存它的unicode值
properties.setProperty("pwd","123mima");
//将键值对存入文件
properties.store(new FileOutputStream("src\\mysql2.properties"),null);
System.out.println("创建配置文件成功");
}
}
标签:String,流之,System,博客,IO,new,序列化,public,out 来源: https://blog.csdn.net/Aurinko324/article/details/123609361