目录
a.构造方法
2.1.字符缓冲流
1.字节流
a.构造方法
b.字节流写数据的三种方式
方法名 | 说明 |
---|---|
void write(int b) | 将指定的字节写入此文件输出流 一次写一个字节数据 |
void write(byte[] b) | 将 b.length字节从指定的字节数组写入此文件输出流 一次写一个字节数组数据 |
void write(byte[] b, int off, int len) | 将 len字节从指定的字节数组开始,从偏移量off开始写入此文件输出流 一次写一个字节数组的部分数据 |
1.1.字符流读写数据
a.构造方法
方法名 | 说明 |
---|---|
BufferedOutputStream(OutputStream out) | 创建字节缓冲输出流对象 |
BufferedInputStream(InputStream in) | 创建字节缓冲输入流对象 |
b.字节缓冲流复制视频
-
案例需求
把“E:\itcast\字节流复制图片.avi”复制到模块目录下的“字节流复制图片.avi”
-
实现步骤
-
根据数据源创建字节输入流对象
-
根据目的地创建字节输出流对象
-
读写数据,复制视频
-
释放资源
-
public class CopyAviDemo {
public static void main(String[] args) throws IOException {
//复制视频
// method1();
method2();
}
//字节缓冲流一次读写一个字节数组
public static void method2() throws IOException {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("E:\\itcast\\字节流复制图片.avi"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("myByteStream\\字节流复制图片.avi"));
byte[] bys = new byte[1024];
int len;
while ((len=bis.read(bys))!=-1) {
bos.write(bys,0,len);
}
bos.close();
bis.close();
}
//字节缓冲流一次读写一个字节
public static void method1() throws IOException {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("E:\\itcast\\字节流复制图片.avi"));
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("myByteStream\\字节流复制图片.avi"));
int by;
while ((by=bis.read())!=-1) {
bos.write(by);
}
bos.close();
bis.close();
}
}
2.字符流
a.为什么会出现字符流
- 字符流的介绍
由于字节流操作中文不是特别的方便,所以Java就提供字符流
字符流 = 字节流 + 编码表
- 中文的字节存储方式用字节流复制文本文件时,文本文件也会有中文,但是没有问题,原因是最终底层操作会自动进行字节拼接成中文,如何识别是中文的呢?
汉字在存储的时候,无论选择哪种编码存储,第一个字节都是负数
简单来说:就是处理中文汉字问题:GBK:汉字占两个字节,UTF-8占3个字节,字符一个汉字占一个字符1
b.构造方法
FileReader(File file) | 在给定从中读取数据的 File 的情况下创建一个新 FileReader |
FileReader(String fileName) | 在给定从中读取数据的文件名的情况下创建一个新 FileReader |
c.成员方法
方法名 | 说明 |
---|---|
int read() | 一次读一个字符数据 |
int read(char[] cbuf) | 一次读一个字符数组数据 |
d.字符流用户注册案例
-
案例需求
将键盘录入的用户名和密码保存到本地实现永久化存储
-
实现步骤
-
获取用户输入的用户名和密码
-
将用户输入的用户名和密码写入到本地文件中
-
关流,释放资源
-
-
代码实现
public class CharStreamDemo8 {
public static void main(String[] args) throws IOException {
//需求: 将键盘录入的用户名和密码保存到本地实现永久化存储
//要求:用户名独占一行,密码独占一行
//分析:
//1,实现键盘录入,把用户名和密码录入进来
Scanner sc = new Scanner(System.in);
System.out.println("请录入用户名");
String username = sc.next();
System.out.println("请录入密码");
String password = sc.next();
//2.分别把用户名和密码写到本地文件。
FileWriter fw = new FileWriter("charstream\\a.txt");
//将用户名和密码写到文件中
fw.write(username);
//表示写出一个回车换行符 windows \r\n MacOS \r Linux \n
fw.write("\r\n");
fw.write(password);
//刷新流
fw.flush();
//3.关流,释放资源
fw.close();
}
}
2.1.字符缓冲流
a.构造方法
方法名 | 说明 |
---|---|
BufferedWriter(Writer out) | 创建字符缓冲输出流对象 |
BufferedReader(Reader in) | 创建字符缓冲输入流对象 |
b.字符缓冲流特有功能
BufferedWriter:
方法名 | 说明 |
---|---|
void newLine() | 写一行行分隔符,行分隔符字符串由系统属性定义 |
BufferedReader:
方法名 | 说明 |
---|---|
String readLine() | 读一行文字。 结果包含行的内容的字符串,不包括任何行终止字符如果流的结尾已经到达,则为null |
c.字符缓冲流操作文件中数据排序案例
-
案例需求
使用字符缓冲流读取文件中的数据,排序后再次写到本地文件
-
实现步骤
-
将文件中的数据读取到程序中
-
对读取到的数据进行处理
-
将处理后的数据添加到集合中
-
对集合中的数据进行排序
-
将排序后的集合中的数据写入到文件中
-
public class CharStreamDemo14 {
public static void main(String[] args) throws IOException {
//需求:读取文件中的数据,排序后再次写到本地文件
//分析:
//1.要把文件中的数据读取进来。
BufferedReader br = new BufferedReader(new FileReader("charstream\\sort.txt"));
//输出流一定不能写在这里,因为会清空文件中的内容
//BufferedWriter bw = new BufferedWriter(new FileWriter("charstream\\sort.txt"));
String line = br.readLine();
System.out.println("读取到的数据为" + line);
br.close();
//2.按照空格进行切割
String[] split = line.split(" ");//9 1 2 5 3 10 4 6 7 8
//3.把字符串类型的数组变成int类型
int [] arr = new int[split.length];
//遍历split数组,可以进行类型转换。
for (int i = 0; i < split.length; i++) {
String smallStr = split[i];
//类型转换
int number = Integer.parseInt(smallStr);
//把转换后的结果存入到arr中
arr[i] = number;
}
//4.排序
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
//5.把排序之后结果写回到本地 1 2 3 4...
BufferedWriter bw = new BufferedWriter(new FileWriter("charstream\\sort.txt"));
//写出
for (int i = 0; i < arr.length; i++) {
bw.write(arr[i] + " ");
bw.flush();
}
//释放资源
bw.close();
}
}
3.转换流
InputStreamReader:是从字节流到字符流的桥梁,父类是Reader
(磁盘中字节文件转换为字符读入到内存,个人理解)
OutputStreamWriter:是从字符流到字节流的桥梁,父类是Writer
(内存中的字符文件转换为字节写出到磁盘,个人理解)
a.构造方法
方法名 | 说明 |
---|---|
InputStreamReader(InputStream in) | 使用默认字符编码创建InputStreamReader对象 |
InputStreamReader(InputStream in,String chatset) | 使用指定的字符编码创建InputStreamReader对象 |
OutputStreamWriter(OutputStream out) | 使用默认字符编码创建OutputStreamWriter对象 |
OutputStreamWriter(OutputStream out,String charset) | 使用指定的字符编码创建OutputStreamWriter对象 |
b.代码实例
public class ConversionStreamDemo {
public static void main(String[] args) throws IOException {
//OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("myCharStream\\osw.txt"));
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("myCharStream\\osw.txt"),"GBK");
osw.write("中国");
osw.close();
//InputStreamReader isr = new InputStreamReader(new FileInputStream("myCharStream\\osw.txt"));
InputStreamReader isr = new InputStreamReader(new FileInputStream("myCharStream\\osw.txt"),"GBK");
//一次读取一个字符数据
int ch;
while ((ch=isr.read())!=-1) {
System.out.print((char)ch);
}
isr.close();
}
}
4.对象流
a.对象序列化
就是将对象保存到磁盘中,或者在网络中传输对象
-
构造方法
方法名 说明 ObjectOutputStream(OutputStream out) 创建一个写入指定的OutputStream的ObjectOutputStream -
序列化对象的方法
方法名 说明 void writeObject(Object obj) 将指定的对象写入ObjectOutputStream
注意事项
一个对象要想被序列化,该对象所属的类必须必须实现Serializable 接口
Serializable是一个标记接口,实现该接口,不需要重写任何方法
b.对象反序列化
磁盘-->内存
-
构造方法
方法名 说明 ObjectInputStream(InputStream in) 创建从指定的InputStream读取的ObjectInputStream -
反序列化对象的方法
方法名 说明 Object readObject() 从ObjectInputStream读取一个对象
代码实例
public class ObjectInputStreamDemo {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//ObjectInputStream(InputStream in):创建从指定的InputStream读取的ObjectInputStream
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("myOtherStream\\oos.txt"));
//Object readObject():从ObjectInputStream读取一个对象
Object obj = ois.readObject();
Student s = (Student) obj;
System.out.println(s.getName() + "," + s.getAge());
ois.close();
}
}
5.serialVersionUID&transient
a.serialVersionUID
用对象序列化流序列化了一个对象后,假如我们修改了对象所属的类文件,读取数据会不会出问题呢?
会出问题,会抛出InvalidClassException异常
如果出问题了,如何解决呢?
重新序列化
给对象所属的类加一个serialVersionUID
private static final long serialVersionUID = 42
-
b.transient
-
如果一个对象中的某个成员变量的值不想被序列化,又该如何实现呢?
-
给该成员变量加transient关键字修饰,该关键字标记的成员变量不参与序列化过程
-
-