Java基础总结--IO总结1

1.IO流(数据流)主要应用概述
数据来源:存储在设备里面
* IO流用来处理设备间数据之间的传输
* Java对数据的操作是通过流的方式
* Java用于对流的操作的对象都在IO包
* 流按照流向分为:输出流(写动作)与输入流(读动作)(相对于程序来说)
读写的方式不同造成被封装成不同的对象
* 按照一次操作数据的字节数目:字节流(1B)与字符流(2B)
以前无字符流:ASCII码1B--表达英语的文字数字,随机计算机普及,为了表示更多国家的语言,兼容了许多国家的码表,这样不利于信息沟通,统一出了unicode编码用来表示众多语言的文字和符号,特点是任何字符用2B表示--比较浪费资源(后面会出现不同的编码方式优化这些问题)。一个中文字在不同码表里面编码不一样,所以希望在读取文字信息的时候按照unicode编码方式,对于同一信息,获取相同的结果
所以使用字符流处理文字。
* 字符流来历:字节流读取字节数据后,不直接操作而是先查指定的编码表获取对应的字,在对文字进行操作==字节流+编码表

2.具体的IO对象
共性抽取--获得IO流的根类(抽象类)
字节流:InputStream OutputStream
字符流:Reader Writer
其子类均是以其相应的后缀结尾的,对象名的前缀是功能

3.传送文字信息 内存--硬盘的文件(优先考虑字符流的输出流Writer)
找到可以操作文件的Writer
Writer-->OutputStreamWriter-->FileWriter
* 必须明确存储数据的目的地--文件名
* 文件不存在会自动创建,文件存在且有数据,文件会被覆盖(删除+创建新文件)
* 输入或输出异常--IOException最好要进行处理
具体步骤:
1.FileWriter fw = new FileWriter("demo.txt");
2.调用Writer的写方法void write()-参数可以是字符串,字符数组,int
fw.write("abcd");--此时数据被临时存储缓冲区
3.进行刷新--将缓冲区流存储在目标文件中
fw.flush();
4.关闭Windows资源
fw.close()--一般写在try-catch-finally(一定会执行)
close()由来--Java程序,记事本程序等写入硬盘文件的操作其实都是调用windows底层的输出流,所以在写操作进行完后,必须将此流占有的资源释放
注意:关闭资源的时候会先刷新close(){flush()}
流关闭后不能在写数据,但是刷新后可以继续写
要实现换行,直接那操作系统的换行命令操作
追加数据FileWriter(String filename, boolean append)-追加true
close与flush区别:后者相当于打开文件写保存,后者要关闭文件时候,询问是否要保存,关闭文件。再次打开文件就是新的流。

4.异常处理IOException(只要读写就可能会发生异常)
文件不存在,写失败,关闭底层资源也会抛出异常
利用try(里面放肯发生异常的语句)-catch-finally(close())
注意:声明在try外面,里面进行对象的初始化
关闭资源的时候先判断是否为空指针,在进行关闭动作

5.从文件中读数据,将其打印在控制台 FileReader
read-读单个字符,字符数组等
* 创建都文件的对象,确定要读取的文件名和存在性
FileReader fr = new FileReader(String filename);-找不到文件就发生异常
* 用Reader里面的read()方法读单个字符
fr.read()-int(0-655235 char的一个字符的范围);读取到结尾会返回-1表示结束
read()方法其实是和底层的操作系统关联,读到结尾出,把结束标识传给JVM,然后JVM自定义一个符合传给调用者。
* 通常将都的动作放在循环里面
* 第二种读的方法(效率比较高)
int read(char[] cbuf)--返回读的字符的个数.结尾为-1,将读到的字符存在字符数组里面。注意:空格也算是一个字符。字符数组的长度固定
int num = fr.read(ch);//数据读到字符数组里面
System.out.println(num + " " + new String(ch));3 abc
int num1 = fr.read(ch);//数据读到字符数组里面 2 dec
System.out.println(num1 + " " + new String(ch));//覆盖前两个元素
总结上面:写成循环
从硬盘上取数据必须是一个一个取,字符数组相当是取一个放进去,等达到个数后
再统一进行处理。
关于字符数组长度1024的整数倍
eg:把一个文件复制到另一个文件里面--复制原理先读后写-字符流
1.创建读取文件的字符流对象
2.创建一个目的,用来存储读到的数据
3.频繁的读写操作
4.关闭资源
注意:一次读一写一,累计多个后再写
write(char[] cbuf, int off, int len) --多个读时候写方法的选择

6.字符流的缓冲区--用数组来缓冲流中的数据
出现的原因:提高对数据读写的效率--Java将其封装为两个对象
对应的类:BufferedReader(字符,字符数组行)/BufferedWriter(字符,字符数组)

缓冲区的使用:要结合对应的流进行使用,在流的基础上对流功能的增强
缓冲区:对要操作的数据进行临时存储,磁头切换次数少,效率高
代码优化:设计优化(代码重构),性能优化(增加功能-缓冲区)eg:超市拿框
缓冲区必须结合流来进行操作才会起到作用--提高效率
具体写数据流程--使用缓冲流
//创建写成流
FileWriter fw = new FileWriter("demo3.txt");
//创建写成字符缓冲流对象和字符写出流进行关联
BufferedWriter bw = new BufferedWriter(fw);
//使用缓冲流的写方法-连续写操作
bw.write("ggsghjdjcjmdkkdkd");
//刷新数据到目标文件
bw.flush();
//关闭资源--其实底层关的是fw,缓冲仅仅是提高效率
bw.close();
[字符写入流不断的写数据不处理,放在写缓冲流中在特定的时间统一操作]
换行LINE_SEPARATOR 定义该常量,传递给System.getProperties();-优先选择
也可以使用方法换行bw.newLine();
字符缓冲读取流--readLine()-String表示读一行(行是根据回车符判断)
可以利用循环返回值为null时候,控制循环
[读字符流不断的读出数据不处理,放在缓冲流中在特定的时间统一操作]
BufferedReader重写了父类的方法,读的时候父类从源读数据,缓冲区方法从缓冲区进行读取数据--就是不需要直接读取内存,而是直接操作缓冲区,为了让用户读文本更便捷-读一行--将read方法的字符进行判断,越到换行,就停止不包含换行符

6.模拟readLine()功能的实现
* 先实现read()-在缓冲区读
创建数组,调用FileReader的read(char[]ch),定义两个变量分别表示数组中剩余的字符count,和数组的角标pose.
* 当缓冲区为0时候,开始往缓冲区方数据count = r.read(buff);pose = 0
* count < 0的时候直接返回-1
* 其他情况直接取字符 int ch = buff[pose++],count--;
实现readLine()方法
* 创建新的缓冲区StringBuilder
* 循环加入元素调用myRead()
* 循环中分别判断\r使用continue;和\n 返回字符串。
* 其他情况读到尾巴返回null
* 注意enter键对应的是 \r+\n 读到\n后在会换行

7.装饰设计模式--对某种功能的增强
缓冲区主要作用:将读取源数据进行存储,提供对该缓冲区操作的方法,把读内存改为读缓冲区。缓冲区的出现对字符流的操作进行功能的提升--装饰着模式
装饰者模式:对已有的东西进行增强,主体还是原来的东西
装饰者与继承的区别:
*相同点:装饰和继承都能实现对功能的扩展
*对于继承来说:首先有一个继承体系,下面有各种子类对象,为了更好的操作并提 高效率必须在产生新的子类提供功能的扩展,这样就会导致继承体系的臃肿,不灵 活,关系一旦产生,关系很难去除。
* 装饰着模式:产生新类对旧的类功能的扩展,在结合已经存在的子类对某个功能的 扩展的实现,使得类之间的关系没有特别紧密。比较灵活
* 使用装饰者模式的要求
装饰者与被装饰者具有同一个父类或同一个父接口(具有相同的方法功能的增强)
eg:BufferedReader& FileReader--Reader

8.LineNumberReader(BufferedReader子类也是装饰者)--获取设置当前行号
setLineNumber(int lineNumber)
getLineNumber()
BufferedReader的增强版本

9.字节流-操作字节、字符以及其他的媒体文件
操作思想和字符流完全一致
* InputStram/OutputStream--字节流用的缓冲区是字节数组byte[]b
写不进缓冲直接去目的地,不用刷新,直接关闭资源。写的是原码
avaliable()-int 可操作的字节数目;
* 字节流的应用--复制mp3
1.自定义缓冲区FileInputStram 2.使用封装的BufferedInputStram(写要刷新)
注意:不能用字符流读图片,因为字符流会把所以字节拿到后在去查码表解析,但是对于文字有固定的码表对应,对于图片无固定的码表,所以可能存在找不到对于信息的情况,所以复制图片不能代表原来的图片

上一篇:git提交代码到github


下一篇:被linux线程基础折磨的点滴——还是没得到完美的答案,但至少得到了所需