• 10. IO框架


    它的挑战是来自于要覆盖所有的可能性,不仅存在各种I/O源端还有想要和它通信的接收端(文件/控制台/网络链接),而且还需要以不同的方式与它们进行通信(顺序/随机存取/缓存/字符/行/字等等)

    一.IO简介:

    数据流是一组有序,有起点和终点的字节的数据序列,包括输入流和输出流;

    流序列中的数据既可以是未经加工的原始二进制数据,也可以是经过编码处理后符合某种格式规定的特定数据,因此Java中的流分为两种:

    1.字节流

    最小的数据单元是字节;

    2.字符流

    最小的数据单元是字符;java中字符是Unicode编码,一个字符两个字节;

    3.Java.Io包的5类1接口

    File、OutputStream、InputStream、Writer、Reader、Serializable接口;

    Java I/O主要包括如下3层次:

    二.字节流的学习

    内存的角度来定义是 读入

    装饰者模式来实现IO操作:

    1. public static File file;
    2. public static void main(String[] args) {
    3. file=new File("D:/Workspace/CDemo/app/src/testtxt/ioStreamTest.txt");
    4. outputSteamTest();
    5. inputSteamTest();
    6. }
    7. public static void outputSteamTest(){
    8. DataOutputStream out;
    9. try {
    10. //装饰者模式
    11. out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file)));
    12. out.writeByte(80);
    13. out.writeShort(5);
    14. out.writeInt(0);
    15. out.writeLong(1000L);
    16. out.writeFloat(0.02f);
    17. out.writeDouble(0.45d);
    18. out.writeBoolean(true);
    19. out.writeChar('n');
    20. out.close();
    21. } catch (Exception e) {
    22. e.printStackTrace();
    23. }
    24. }
    25. public static void inputSteamTest(){
    26. DataInputStream in;
    27. try {
    28. in = new DataInputStream(new BufferedInputStream(new FileInputStream(file)));
    29. //读取时要与写的顺序一一对应
    30. byte mByte = in.readByte();
    31. short aShort = in.readShort();
    32. int anInt = in.readInt();
    33. long aLong = in.readLong();
    34. float aFloat = in.readFloat();
    35. double aDouble = in.readDouble();
    36. boolean bool = in.readBoolean();
    37. char aChar = in.readChar();
    38. System.out.println("bool :" +bool +" ,\nmByte :" +mByte +" ,\naShort :" +aShort
    39. +" ,\nanInt :" +anInt +" ,\naLong :" +aLong +" ,\naChar :" +aChar
    40. +" ,\naDouble :" +aDouble +" ,\naFloat :" +aFloat);
    41. in.close();
    42. } catch (Exception e) {
    43. e.printStackTrace();
    44. }
    45. }
    46. 运行结果
    47. bool :true ,
    48. mByte :80 ,
    49. aShort :5 ,
    50. anInt :0 ,
    51. aLong :1000 ,
    52. aChar :n ,
    53. aDouble :0.45 ,
    54. aFloat :0.02

    为向文件中写入数据,首先需创建一个FileOutputStream,然后为提升访问效率,可将它发送给具备缓存功能的ButteredOutput-Stream,而为了实现与机器类型无关的java基本类型数据的输出,可将缓存的流传递给DataOutputStream,从上面的关系,我们可看到,其根本目的都是为outputSteam添加额外的功能。

    OutputStream -> FileOutputStream/FilterOutputStream ->DataOutputStream->bufffferedOutputStream

    FilterOutputStream

    应先掌握FilterOutputStream,以及FileOutputStream,这两个类是基类,从继承关系不难发现它们都是对abstract类OutputStream的拓展,是它的子类,然而伴随对stream流的功能的拓展,所以就出现了DataOutputstream,(将java中的基础数据类型写入数据字节输出流中,保存在存储介质中、然后可用DataOutputStream从存储介质中读取到程序中还原成java基础类型),DataOutputstream,FilterOutputStream三个类的关系的这种设计使用了装饰器模式;

    BufferedOutputStream

    为了提升Stream的执行效率,出现了bufferedOutputStream,它在本地添加了一个缓存数组,在使用它之前,每次从磁盘读入数据时,都是需要访问多少byte数据就向磁盘中读多少个byte的数据,而出现bufferedOutputSteam之后,策略就改了,会先读取整个缓存空间相应大小的数据,这样就从磁盘读取了一块比较大的数据,然后缓存起来,从而减少了对磁盘的访问的次数,提升了性能。

    三.字符流的学习

    Writer -> FilterWriter -> BufferedWriter ->OutputStreamWriter ->FileWriter ->其他 字符有一个readline();

    1个字符 = 两个字节, "中文" 1个字符 = 1个字节 "英文" 编码格式 UTF-8 或 GBK格式

    1. public static void writerAndStream(){ //写出
    2. try {
    3. BufferedWriter bfw=new BufferedWriter(
    4. // new FileWriter(file));//使用它替代下面代码
    5. new OutputStreamWriter(new FileOutputStream(file),"GBK"));
    6. bfw.write("我爱你中国");
    7. bfw.flush();
    8. bfw.close();
    9. } catch (Exception e) {
    10. e.printStackTrace();
    11. }
    12. }
    13. public static void readerAndStream(){//读入
    14. try {
    15. BufferedReader bfr = new BufferedReader(
    16. // new FileReader(file)); //使用它替代下面代码
    17. new InputStreamReader(new FileInputStream(file),"GBK"));
    18. String result = bfr.readLine();
    19. bfr.close();
    20. System.out.println("readerAndStream--result"+result);
    21. } catch (Exception e) {
    22. e.printStackTrace();
    23. }
    24. }
    25. //输出数据
    26. readerAndStream--result我爱你中国

    面试题:

    1.如果只用FileOutputStream fos=new FileOutputStream("D:/text.txt");不是也能输出到"d"/text.txt"吗,

    为啥要用其 他两个呢能起到什么作用?

    FileOutputStream: 字节流,它是一个字节一个字节的向外发送数据;

    OutputStreamWriter:字符流,它是一个字符一个字符的向外送数据; 区别为用字符流可以使中文不乱码;

    2.为何使用Buffer缓冲区?

    使用Buffer缓冲区可以减少硬盘读取次数, 保护了硬盘;

    四.RandomAccessFile

    1. 为什么有RandomAccessFile

    多线程中分段下载

    1. 即可读也可写

    RandomAccessFile不属于InputStream 和 OutputStream类系 它是一个独立的类,这里包含读写两种操作;

    构造方法 RandomAccessFile raf = new RandomAccessFile(File file,String mode);

    其中参数mode的值可选 "r": 可读, "w": 可写, "rw": 可读可写;

    1. 重要的成员方法

    seek(int index); 可将指针移动到某个位置开始读写;

    setLength(long len);给写入文件预留空间;

    五.FileChannel

    FileChannel配合者ByteBuffer,将读写的数据缓存到内存中,然后以批量/缓存的方式read/weite,省去非批量操作时的重复中间操作,操纵大文件时可显著提高效率;

    六.Files的常用方法有哪些

    1. Files.exists():检测文件路径是否存在。

    2. Files.createFile():创建文件。

    3. Files.createDirectory():创建文件夹。

    4. Files.delete():删除一个文件或目录。

    5. Files.copy():复制文件。

    6. Files.move():移动文件。

    7. Files.size():查看文件个数。

    8. Files.read():读取文件。

    9. Files.write():写入文件

  • 相关阅读:
    出差学知识No1:制作一个shell脚本在正式命令执行前运行
    Baichuan2开源大模型正式发布,王小川:性能超过LLaMA2
    智慧城市的定义是什么?
    Patroni 源码修改七:Patroni对Opengauss的控制
    钉钉智慧校园小程序如何开发,你知道么!
    【Rust指南】组织管理|路径表示|访问权限
    OTP语音芯片SOP8的前世今生_如九齐_硕呈_钰绅等以及国产方案KT148A
    计算机毕业设计 SSM+Vue社区疫情防控管理系统 小区疫情防疫管理系统 物业管理系统Java Vue MySQL数据库 远程调试 代码讲解
    Rt-Thread 移植2--线程定义与切换(KF32)
    00 数据库基础概念
  • 原文地址:https://blog.csdn.net/x910131/article/details/126023462