流
流的分类
- 字节流
- 字符流
字节流 | 转换流(桥梁) | 字符流 |
---|---|---|
InputStream | InputStreamReader | Reader |
OutputStream | OutputStreamWriter | Writer |
FileInputStream | BufferedReader | |
FileOutputStream | BufferedWriter | |
BufferedInputStream | FileReader | |
BufferedOutputStream | FileWriter | |
DataInputStream | ||
DataOutputStream | ||
ObjectInputStream | ||
ObjectOutputStream | ||
PrintStream |
字节流
InputStream 是所有字节输入流的父类
OutputStream 是所有字节输出流的父类
FileinputStream 类是inputStream类的子类,用于从文件中获取字节输入流
FileoutputStream类是outputStream类的子类,用于将字节输出到文件中
public static void main(String[] args) {
try{
//1:创建对象并传入读取和写入路径
FileInputStream inputstream = new FileInputStream("E:/1.JPG");
FileOutputStream outputstream = new FileOutputStream("E:/2.JPG");
//2:读取路径内容并写入新的路径,可使用“单字节搬运”和”多字节搬运“
int len = -1;
byte[] by = new byte[1000];
while((len = inputstream.read(by)) != -1){
outputstream.write(by, 0, len);
}
//关闭流
outputstream.flush();
outputstream.close();
inputstream.close();
}catch(IOException io){
io.printStackTrace();
}
}
- bufferedinputStream和BufferedoutputStream分别是inputStream类和outputStream类的子类,他们使用装饰着模式对输入流和输出流进行装饰,使输入流和输出流缓冲功能,从而提高读写速度
public static void main(String[] args) {
try {
BufferedInputStream buff = new BufferedInputStream(new FileInputStream("E:/1.JPG"));
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream("E:/4.JPG"));
// 比原始方法性能更高,但是并不是很明显,因为他们自带缓冲功能。
int len = -1;
byte[] by = new byte[1000];
while ((len = buff.read(by)) != -1) {
out.write(by, 0, len);
}
// 原始方法 效率也比较高
/*
* while((len = buff.read()) != -1){
* out.write(len);
* }
*/
out.flush();
out.close();
buff.close();
} catch (IOException io) {
io.printStackTrace();
}
}
- DataInoutStream和DataOutputStream分别是InputStream和OutputStream类的子类使用装饰着模式对输入流和输出流进行装饰,使输入流和输出流可以将java中的基本数据类型和字符串输出到流中或从流中读取
public static void main(String[] args) {
try {
//写入部分
DataOutputStream out = new DataOutputStream(new FileOutputStream("E:/he.dat"));
out.writeInt(20);
out.writeDouble(2.6);
out.writeUTF("hehe");
out.close();
//输出部分 顺序要和写入顺序保持一致
DataInputStream in = new DataInputStream(new FileInputStream("E:/he.dat"));
int a = in.readInt();
double b = in.readDouble();
String str = in.readUTF();
System.out.println(a);
System.out.println(b);
System.out.println(str);
in.close();
} catch (IOException IO) {
IO.printStackTrace();
}
}
- PrintWriter可以方便的将内容输出到制定的目标中,例如Sytem.out中的out就是PrintStream类的对象,将内容默认输出到标准输出流(屏幕)。
//标准的关闭流的做法
public static void main(String[] args) {
PrintStream pr = null;
try {
pr = new PrintStream("E:/pr.txt");
pr.print("aaa");
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
try {
if (pr != null) {
pr.close();
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
序列化
ObjectInputStream和ObjectOutputStream除了将基本数据类型转换为流的功能外还具备将对象转换为流。
使用ObjectOutputStream将对象写入流的过程称为序列化,使用ObjectInputStream将流转换为对象的过程称为反序列化。
类参与序列化(反序列化)必须要实现java.io.Serializable接口该接口没有任何方法只是将类标记为一个可(反)序列化类。
如果父类是可序列化类,子类也是可序列化类
每个可序列化类都要去实现一个名称为serialVersionUID序列化ID
标记为transient的属性将不参与序列化和反序列化
静态属性也不参与序列化和反序列化
可序列化类的属性也必须是可序列化的
//将对象序列化(反序列化)
try {
ObjectInputStream in = new ObjectInputStream(new FileInputStream("E:/hello.dat"));
Student st = (Student)in.readObject();
System.out.println(st.getName());
System.out.println(st.getAge());
System.out.println(st.getAddre().getCity());
System.out.println(st.getAddre().getAddress());
in.close();
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("E:/hello.dat"));
out.writeObject(stu);
out.close();
} catch (Exception e) {
e.printStackTrace();
}
字符流
java.io.Reader和java.io.Writer分别是字符流的读取和写入的父类
outputStreamWriter是writer的子类,用于将字符流和字节流转换
InputStreamReader是Reader类的子类,用于将字节流和字符流转换
public static void main(String[] args) {
try {
InputStreamReader reader = new InputStreamReader(new FileInputStream("E:/hah"));
//“多字节搬运”本身不具备缓冲功能
StringBuffer sb = new StringBuffer();
int len = -1;
char[] ch = new char[100];
while ((len = reader.read(ch)) != -1) {
// String str = new String(ch, 0 , len);
// sb.append(str);
sb.append(ch, 0, len);
}
System.out.println(sb);
reader.close();
//基本读取“单字节搬运”
while ((len = reader.read()) != -1) {
char ch1 = (char) len;
sb.append(ch1);
}
System.out.println(sb.toString());
//写入方法
OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream("E:/hah"));
out.write("hello\n");
out.write("nihao");
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
- BufferedReader 和 BufferedWriter 是具有缓冲功能的Reader和Writer,同时他们使用了装饰者模式
public static void main(String[] args) {
try {
// 读取方法
BufferedReader reader =
new BufferedReader(new InputStreamReader(new FileInputStream("E:/hello.txt")));
StringBuffer sb = new StringBuffer();
String str = null;
while ((str = reader.readLine()) != null) {
sb.append(str).append("\n");
}
System.out.println(sb);
reader.close();
// 写入方法
BufferedWriter writer =
new BufferedWriter(new OutputStreamWriter(new FileOutputStream("E:/hello.txt")));
writer.write("hello");
writer.write("你好");
writer.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
- FileReader 和FileWriter 在构造方法上比其他的Reader 和Writer较为简单,但是相比bufferReader的读取比较麻烦不能使用BufferReader的readline方法,只能单个字符读取或者使用数组。
public static void main(String[] args) {
try {
//读取方法
FileReader reader = new FileReader("E:/write.txt");
char[] ch = new char[100];
int len = -1;
StringBuilder sb = new StringBuilder();
while ((len = reader.read(ch)) != -1) {
sb.append(ch, 0, len);
}
System.out.println(sb);
//写入方法
FileWriter writer = new FileWriter("E:/write.txt");
writer.write("你好");
writer.write("java");
} catch (Exception ex) {
ex.printStackTrace();
}
}