1)按照数据单位的不同流可分为:字节流和字符流
2)按照数据流的流向可分为:输入流和输出流
3) 按流的角色的不同分为:节点流,处理流
抽象基类 节点流(字节流/字符流) 缓冲流 (处理流的一种)
InputStream FileInputStream BufferedInputStream
OutputStream FileOutputStream BufferedOutputStream
Reader FileReader BufferedReader
Writer FileWriter BufferedWriter
为了提高数据读写的速度,Java API提供了带缓冲功能的流类,在使用这些流类时,会创建一个内部缓冲区数组。
根据数据操作单位可以把缓冲流分为:
BufferedInputStream 和 BufferedOutputStream
BufferedReader 和 BufferedWriter
缓冲流要“套接”在相应的节点流(FileInputStream ,FileOutputStream)之上也就是说创建一个缓冲自己输入流 new BufferedInputStream(FileInputStream);。同理输出流也是这样。对读写的数据提供了缓冲的功能,提高了读写的效率,同时增加了一些新的方法
对于输出的缓冲流,写出的数据会先在内存中缓存,使用**flush()**将会使内存中的数据立刻写出.
1)提供读入和写出的文件
2)创建相应的节点流(因为缓冲流是建立在节点流之上的)
3)将创建的节点流对象作为形参传递给缓冲流的构造器
4)写具体的操作
5)关闭流 先关闭缓冲输出流,在关闭缓冲输入流 因为缓冲流包含节点流 所以不用关闭节点流 直接关闭缓冲流即可。
package com.ghl.io;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class BufferInputOutPutStreamDemo {
public static void main(String[] args) {
testMyOutput(); //BufferInputStream BufferOutputStream
testBufferedRead();//BufferedReader 和 BufferedWriter
}
// 实现文件复制(BufferInputStream BufferOutputStream)
public static void testMyOutput() {
try {
// 1.需要读和写的文件 文件的复制操作
File file = new File("2.jpg");
File file2 = new File("3.jpg");
// 2.创建相应的节点流(因为缓冲流是建立在节点流之上的)
FileInputStream fis = new FileInputStream(file);
FileOutputStream fos = new FileOutputStream(file2);
// 3.将创建的节点流对象作为形参传递给缓冲流的构造器
BufferedInputStream bis = new BufferedInputStream(fis);
BufferedOutputStream bos = new BufferedOutputStream(fos);
byte[] b = new byte[1024];
int len;
while ((len = bis.read(b)) != -1) {
bos.write(b, 0, len);
bos.flush();//将数据写入到磁盘中
}
bos.close();
bis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//实现文本文件的复制(BufferedReader 和 BufferedWriter)
public static void testBufferedRead() {
try {
// 1.需要读和写的文件 文本文件的复制操作
File file = new File("dbcp.txt");
File file2 = new File("dbcp1.txt");
// 2.创建相应的节点流(因为缓冲流是建立在节点流之上的)
FileReader fr=new FileReader(file);
FileWriter fw=new FileWriter(file2);
// 3.将创建的节点流对象作为形参传递给缓冲流的构造器
BufferedReader br=new BufferedReader(fr);
BufferedWriter bw=new BufferedWriter(fw);
//第一种输出的方法
char[] c = new char[1024];
int len;
while((len=br.read(c))!=-1) {
bw.write(c, 0, len);
bw.flush();//将数据写入到磁盘中
}
//第二种输出的方法 缓冲流提供的操作方法 一次读取一行
String str;
while((str=br.readLine())!=null) {
System.out.println(str);
bw.write(str);
bw.newLine();//相当于换行操作
bw.flush();
}
bw.close();
br.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
1)转换流提供了在字节流和字符流之间的转换
2)Java API提供了两个转换流:InputStreamReader和OutputStreamWriter
3)字节流中的数据都是字符时,转成字符流操作更高效。
用于将字节流中读取到的字节按指定字符集解码成字符。需要和InputStream“套接”。
构造方法
public InputStreamReader(InputStream in)
public InputSreamReader(InputStream in,String charsetName) //charsetName:指定字符集
用于将要写入到字节流中的字符按指定字符集编码成字节。需要和OutputStream“套接”。
构造方法
public OutputStreamWriter(OutputStream out)
public OutputSreamWriter(OutputStream out,String charsetName) //charsetName:指定字符集
package com.ghl.io;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public class InputStreamReaderDemo {
public static void main(String[] args) throws Exception {
testMyInput();
}
/**转换流
* @throws Exception
*/
public static void testMyInput() throws Exception {
FileInputStream fis = new FileInputStream("dbcp.txt");
FileOutputStream fos = new FileOutputStream("dbcp3.txt");
InputStreamReader isr = new InputStreamReader(fis, "GBK");
OutputStreamWriter osw = new OutputStreamWriter(fos, "GBK");
BufferedReader br = new BufferedReader(isr);
BufferedWriter bw = new BufferedWriter(osw);
String str = null;
while ((str = br.readLine()) != null) {
bw.write(str);
bw.newLine();
bw.flush();
}
bw.close();
br.close();
}
}
System.in和System.out分别代表了系统标准的输入和输出设备
默认输入设备是键盘,输出设备是显示器
System.in的类型是InputStream
System.out的类型是PrintStream,其是OutputStream的子类FilterOutputStream 的子类
打印流是输出信息最方便的类。打印流–必须是输出流(两个都是) 顾名思义,打印不就是输出的意思么。
解决的问题:方便的打印各种数据的。
PrintStream(字节打印流)PrintWriter(字符打印流):提供了一系列重载的print和println方法,用于多种数据类型的输出
PrintStream和PrintWriter的输出不会抛出异常
PrintStream和PrintWriter都有自动flush功能
System.out返回的是PrintStream的实例,也就是说System.out.println();之所以可以打印各种类型的数据,就是因为System.out提供了了一系列的重载方法。(具体的可以参考jdk官方文档)
为了方便地操作Java语言的基本数据类型的数据,可以使用数据流。
比如说将一个 long 类型的数据写到文件中,我们肯定不能直接写,可能需要将long类型转成字符串 → 在通过 getbytes() 变成字节写进去,比较费劲,而且在此过程中 long 类型的数需要不断地转换. Java 中的数据流能够很好的解决这个问题(不需要转换,直接写进去)
数据流有两个类:(用于读取和写出基本数据类型的数据)
DataInputStream 和 DataOutputStream分别“套接”在 InputStream 和 OutputStream 节点流上。
DataInputStream中的方法
boolean readBoolean()
byte readByte()
char readChar()
float readFloat()
double readDouble()
short readShort()
long readLong()
int readInt()
String readUTF() //字符串
void readFully(byte[] b) //字节数组
DataOutputStream中的方法
将上述的方法的read改为相应的write即可。
package com.ghl.io;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class DataInputStreamDemo {
public static void main(String[] args) {
DataOutputStream dos = null;
try { //创建连接到指定文件的数据输出流对象
dos = new DataOutputStream(new FileOutputStream(
"D:\\io\\destData.dat"));
dos.writeUTF("ab中国"); //写UTF字符串
dos.writeBoolean(false); //写入布尔值
dos.writeLong(1234567890L); //写入长整数
System.out.println("写文件成功!");
} catch (IOException e) {
e.printStackTrace();
} finally { //关闭流对象
try {
if (dos != null) {
// 关闭过滤流时,会自动关闭它包装的底层节点流
dos.close();
}
} catch (IOException e) {
e.printStackTrace();
} }
}
}
1)用于存储和读取对象的处理流。ObjectInputStream和OjbectOutputSteam
2)它的强大之处就是可以把Java中的对象写入到磁盘中,也能把对象从磁盘中还原回来。
3)如果想通过对象流来实现对对象的存储和读取操作,必须明白对象的序列化和反序列化机制。因为对象流就是通过序列化机制完成对内存中的对象进行操作。
序列化(Serialize):用ObjectOutputStream类将一个Java对象写入IO流中
反序列化(Deserialize):用ObjectInputStream类从IO流中恢复该Java对象
ObjectOutputStream和ObjectInputStream不能序列化static和transient修饰的成员变量。
对象序列化机制:允许把内存中的Java对象转换二进制流,允许把这种二进制流持久地保存在磁盘上或通过网络将这种二进制流传输到另一个网络节点(网络编程)当其它程序获取了这种二进制流,就可以恢复成原来的Java对象。
对象反序列化机制:把二进制流恢复成原来的Java对象。
序列化的好处在于可将任何实现了Serializable****接口的对象转化为字节数据,使其在保存和传输时可被还原
也就是说如果想某个对象支持序列化机制,则必须让其类是可序列化的 也就是implements Serializable接口。
package com.ghl.io;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class ObjectInputOutputStream {
public static void main(String[] args) throws Exception {
TestObjectOutputStream(); // java内存中的对象写本到地磁盘
TestObjectInputStream();
}
//对象的序列化过程,将内存中的对象通过ObjectOutputStream转换成二进制流 并存储在硬盘中
public static void TestObjectOutputStream() throws FileNotFoundException, IOException {
Person p1=new Person("zhangsan",23);
Person p2=new Person("lisi",21);
ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("person.txt"));
oos.writeObject(p1);
oos.flush();
oos.writeObject(p2);
oos.flush();
}
//反序列化 把二进制流恢复成原来的Java对象。
public static void TestObjectInputStream() throws Exception{
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("person.txt"));
Person p1 = (Person) ois.readObject();
System.out.println(p1);//com.ghl.io.Person@3d075dc0
Person p2 = (Person) ois.readObject();
System.out.println(p2);//com.ghl.io.Person@214c265e
}
}
/*
* 1.类必须实现序列化
* 2.类中的属性也要实现序列化接口
*/
class Person implements Serializable{
String name;
Integer age;
public Person(String name,Integer age) {
this.name=name;
this.age=age;
}
}
字节流-缓冲流(重点 开发会用到)
输入流InputStream-FileInputStream-BufferedInputStream
输出流OutputStream-FileOutputStream-BufferedOutputStream
字符流-缓冲流(重点 开发会用到)
输入流Reader-FileReader-BufferedReader
输出流Writer-FileWriter-BufferedWriter
转换流(了解)
InputSteamReader和OutputStreamWriter
对象流ObjectInputStream和ObjectOutputStream(难点+重点 开发会用到)
序列化(重点 开发会用到)
反序列化(重点 开发会用到)