硬盘
字符流
给硬盘上.txt文件写入数据 文件 字符输出流—FileWriter
从硬盘上.txt文件读取数据 文件 字符输出流—FileReader
package cn.tedu.io.file;
import java.io.FileReader;
import java.io.IOException;
public class FileReaderDemo1 {
public static void main(String[] args) throws IOException {
//创建文件字符输入流对象
//底层没有自带的缓冲区
FileReader reader=new FileReader("D:\\a.txt");
//返回单个字符的编码值
/*System.out.println(reader.read());
System.out.println(reader.read());
System.out.println(reader.read());
//读取完毕的标值---返回-1
System.out.println(reader.read());*/
//通过循环实现
int i=-1;
//把方法返回值(读取到的字符编码之)赋值给新变量,再让新变量和-1进行比较
while ((i=reader.read())!=-1){
//输出新变量的值(方法读到的字符编码值)
System.out.println(i);
}
//关流
reader.close();
}
}
字节流(常见)
给硬盘上.txt文件写入数据 文件 字节输出流—FileOutputStream
package cn.tedu.io.file;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileOutputStreamDemo {
public static void main(String[] args) throws IOException {
//创建文件字节输出流对象
//底层没有自带的缓冲区
//如果不指定append那么默认false就是每次新建空文件覆盖之前的内容
//如果指定append为true那么每次就是追加数据
FileOutputStream fos=new FileOutputStream
("D:\\3.txt",true);
//调用方法写出数据
fos.write("你好".getBytes());
//关流
fos.close();
}
}
从硬盘上.txt文件读取数据 文件字节输入流FileInputStream
package cn.tedu.io.file;
import java.io.FileInputStream;
import java.io.IOException;
public class FileInputStreamDemo {
public static void main(String[] args) throws IOException {
//创建文件字节输入流
FileInputStream fis=new FileInputStream("D:\\1.txt");
//返回一个字节对应的编码值
/* System.out.println(fis.read());
System.out.println(fis.read());
System.out.println(fis.read());
System.out.println(fis.read());
System.out.println(fis.read());
System.out.println(fis.read());*/
//自建缓冲区
byte[] bs=new byte[10];
int len=-1;
//返回读取到的字节数,遇到-1读取完毕[0
while ((len=fis.read(bs))!=-1){
System.out.println(new String(bs,0,len));
}
//关流
fis.close();
}
}
缓冲流(给别的流提供缓冲区)
BufferedReader-----给字符输入流提供缓冲区
readLine()—读取一行
package cn.tedu.io.buffer;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class BufferedReaderDemo {
public static void main(String[] args) throws IOException {
//创建缓冲流对象
//BufferedReader和FileReader都是Reader的子类---同类
//同类对象给本类对象增强(完善)功能---装饰者设计模式
BufferedReader br=new BufferedReader(
new FileReader("D:\\b.txt"));
//读取数据
//读取一行数据
/*System.out.println(br.readLine());
System.out.println(br.readLine());
System.out.println(br.readLine());
//当读取完毕时返回null
System.out.println(br.readLine());*/
//用循环实现
String str="";
while ((str=br.readLine())!=null){
System.out.println(str);
}
//关流
br.close();
}
}
BufferedWrite—提供一个更大的缓冲区
newLine()—换行
package cn.tedu.io.buffer;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
public class BufferedWriterDemo {
public static void main(String[] args) throws IOException {
//创建缓冲流对象
BufferedWriter bw=new BufferedWriter
(new FileWriter("D:\\b.txt"));
//写出数据
bw.write("avs");
//换行
//Windows---/r/n
//Linux---/n
bw.newLine();
bw.write("3216");
//关流
bw.close();
}
}
模式:遇到统一问题时给出统一的解决方式
设计模式:在软件开发中,遇到统一问题给出统一的解决方案
装饰者设计模式:同类对象给本类对象增强(完善)功能
转换流
OutputStreamWriter—把字符流转成字节流
package cn.tedu.io.transform;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
public class OutputStreamWriterDemo {
public static void main(String[] args) throws IOException {
//创建转换流对象
//转换流的对象由文件字节输出流对象构建
//底层真正来进行传输是文件字节输出流对象
//接收准备数据时用的是字符流,底层真正往外写出数据用的是字节流
//转换流---字符流转成字节流
OutputStreamWriter osw=new OutputStreamWriter
(new FileOutputStream("D:\\123.txt"));
//写出数据
//往外写出数据需要先准备数据
//事先需要准备数据都是字符形式的数据---需要提供字符流来操作数据
osw.write("你好");
//关流
osw.close();
}
}
InputStreamReader—把字节流转成字符流
package cn.tedu.io.transform;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
public class InputStreamReaderDemo {
public static void main(String[] args) throws IOException {
//创建转换对象
//转换流对象由文件字节输入流对象来构建
//底层真正来读取数据的是文件字节输入流
//先根据文件字节输入流来读取数据
//再根据字符流来提供展示数据
//转换流---字节流转成字符流
InputStreamReader isr=new InputStreamReader
(new FileInputStream("D:\\b.txt"));
//读取数据
char[]cs=new char[10];//自建缓冲区
int len=-1;
//展示数据---字符形式数据
//展示的数据由提供字符流来获取
while ((len=isr.read(cs))!=-1){
//
System.out.println(new String(cs,0,len));
}
//关流
isr.close();
}
}
系统流
out、err、in(都是字节流)
系统流都是静态的流对象,使用完毕之后不能关流
package cn.tedu.io.system;
import java.util.Scanner;
public class SystemDemo {
public static void main(String[] args) {
/* //输出正确结果 黑色
//out-----字节输出流对象
System.out.println(1);
//输出错我结果 红色
//err-----字节输出流对象
System.err.println(1);
//in------字节输入流对象
new Scanner(System.in);*/
//
Scanner sc1=new Scanner(System.in);
int num1=sc1.nextInt();
System.out.println(num1);
//关流
//in是静态流对象 如果关闭了其他地方都不能使用
sc1.close();
Scanner sc2=new Scanner(System.in);
int num2=sc2.nextInt();
System.out.println(num2);
}
}
打印流
print方法以及println方法都是定义在打印流里
package cn.tedu.io.print;
import java.io.IOException;
import java.io.PrintStream;
public class PrintDemo {
public static void main(String[] args) throws IOException {
//创建打印流对象
PrintStream ps=new PrintStream("D:\\5.txt");
//写出数据
ps.print(22);
ps.println("abc");
ps.write("466".getBytes());
//关流
ps.close();
}
}
序列化与反序列化
序列化:把对象以及相关信息转成字节数组 存储到硬盘(持久化)
package cn.tedu.io.serial;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class ObjectOutputStreamDemo {
public static void main(String[] args) throws IOException {
//创建对象
//如果路径信息没有盘符---当前工程
ObjectOutputStream oos=new ObjectOutputStream
(new FileOutputStream("p.data"));
//提供对象
Person p=new Person();
p.setName("豆豆");
p.setAge(10);
//把对象转成字节数组进行序列化
oos.writeObject(p);
//关流
oos.close();
}
}
反序列化:把字节数组转成相应的对象
package cn.tedu.io.serial;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
public class ObjectInputStreamDemo {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//创建对象
ObjectInputStream ois=new ObjectInputStream
(new FileInputStream("p.data"));
//读取字节数组转成对应对象---反序列化
Person p=(Person)ois.readObject();
//关流
ois.close();
//展示信息
System.out.println(p.getName()+","+p.getAge());
}
}
注意:
1.类实现Serializable产生对象才能做序列化
2.如果属性被static/transient修饰不能被序列化过去
3.serialVersionUID(序列化版本号)
在序列化之前会根据类里的属性和方法来计算出一个版本号,随着对象一起序列化过去。在反序列化之前会再次根据类里属性和方法来计算出一个版本号,根据前后两个版本号进行对比,如果对比结果一致可以进行正常的反序列化,如果对比结果不一致则进行反序列化失败。(指定版本号private static final long seriaVersionUID=1534321534L;)
4.集合对象和映射对象都不能直接进行序列化,只能依次遍历元素一一进行序列化。
package cn.tedu.io.serial;
import java.io.Serializable;
//类实现Serializable接口产生对象才能做序列化
public class Person implements Serializable {
private static final long serialVersionUID = 1494936044942872395L;
//提供版本号---java就不再计算版本号
//private static final long seriaVersionUID=1534321534L;
//属性
private String name;
private int age;
//属性会被序列化
//private char gender;
//强制属性不被序列化过去
//transient double weight;
//静态属性不会被序列化
//private static String classroom;
//
//private static
//方法不会被序列化
//public void m(){}
//提供get/set方法
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;
}
}