java IO流(复习,上课笔记)

IO流

流:代表任何有能力产出数据的数据源对象或者是有能力接受数据的接收端对象
流的本质:数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作

凡是与Java外部进行交互的,都叫做IO(Input/Output)

文件

日志文件的记录分为代码after;before;round
万物皆文件:文件是操作一切功能的接口
上课笔记 _文件系统
上课笔记_硬卡
访问任何一个硬件时,都要接口卡,如网卡,显卡,声卡等
接口卡又称为适配器
硬卡中有控制总线,地址总线(端口,地址),数据总线

往端口里写数据,需要将数据变成顺序的数据
一个字节一个字节往端口里放,这样的接口称为流接口
映射:将磁盘里的一段空间映射到内存里,内存直接映射到硬卡里;批量操作,速度快

元数据:描述数据的数据,如文件的的位置,文件的大小,文件的使用权限等等

tmp文件系统

tmp文件夹 ——tmp文件系统
在这个文件夹中的文件到点就收,临时文件目录,相当于回收站
TmpFile.deleteOnExit(); 程序退出,文件夹就会被删除
TmpFile.delete(); 立刻就会被删除

IO流的分类

  1. 按数据流的方向分为 输入流、输出流
    输入流:从别的地方(本地文件,网络上的资源等)获取资源 输入到 我们的程序中
    输出流:从我们的程序中 输出到 别的地方(本地文件), 将一个字符串保存到本地文件中,就需要使用输出流。

  2. 按处理数据单位不同分为 字节流、字符流
    1字符 = 2字节 、 1字节(byte) = 8位(bit) 、 一个汉字占两个字节长度

字节流:每次读取(写出)一个字节,当传输的资源文件有中文时,就会出现乱码(InputStream/outputStream)
字符流:每次读取(写出)两个字节,有中文时,使用该流就可以正确传输显示中文(Reader/Writer)

  1. 按功能不同分为 节点流、处理流
    节点流:以从或向一个特定的地方(节点)读写数据。如FileInputStream 
    处理流:是对一个已存在的流的连接和封装,通过所封装的流的功能调用实现数据读写。如BufferedReader。处理流的构造方法总是要带一个其他的流对象做参数。一个流对象经过其他流的多次包装,

IO流特性

  1. 先进先出,最先写入输出流的数据最先被输入流读取到。

  2. 顺序存取,可以一个接一个地往流中写入一串字节,读出时也将按写入顺序读取一串字节,不能随机访问中间的数据。

  3. 只读或只写,每个流只能是输入流或输出流的一种,不能同时具备两个功能,输入流只能进行读操作,对输出流只能进行写操作。在一个数据传输通道中,如果既要写入数据,又要读取数据,则要分别提供两个流

五类一接口

在整个Java.io包中最重要的就是5个类和一个接口。5个类指的是File、OutputStream、InputStream、Writer、Reader;一个接口指的是Serializable.掌握了这些IO的核心操作那么对于Java中的IO体系也就有了一个初步的认识了。

主要的类如下:

  1. File(文件特征与管理):File类是对文件系统中文件以及文件夹进行封装的对象,可以通过对象的思想来操作文件和文件夹。 File类保存文件或目录的各种元数据信息,包括文件名、文件长度、最后修改时间、是否可读、获取当前文件的路径名,判断指定文件是否存在、获得当前目录中的文件列表,创建、删除文件和目录等方法。

  2. InputStream(二进制格式操作):抽象类,基于字节的输入操作,是所有输入流的父类。定义了所有输入流都具有的共同特征。

  3. OutputStream(二进制格式操作):抽象类。基于字节的输出操作。是所有输出流的父类。定义了所有输出流都具有的共同特征。

  4. Reader(文件格式操作):抽象类,基于字符的输入操作。

  5. Writer(文件格式操作):抽象类,基于字符的输出操作。

  6. RandomAccessFile(随机文件操作):一个独立的类,直接继承至Object.它的功能丰富,可以从文件的任意位置进行存取(输入输出)操作。

字节流操作

一个字节一个字节的读

File f=new File("/data/bb.txt");
OutputStream fos=null;
try{
fos=new.FileOutputStream(f);
String str="测试程序";
fos.write(str.getBytes);
fos.flush();}catch(){}

写文件bbb.txt,写入“测试程序”,一个字节一个字节的写,再写一次会覆盖原文件

在try{}中写入

fos=new FileOutputStream(f,true);

不断执行就会往原文件中不断写入内容“测试程序\n”

读文件

OutputStream fos=null;

换成

InputStream fis=new FileInputStream(f);

然后创建一个byte数组

byte[] bbuf=new byte[100];//100个字节的文件
int hasRead=0;
While((hasRead=fis.read(bbuf))>0)//大于零,就是读到内容
{
System.out.print(new String(bbuf,0,hasRead,"utf-8"));
}
fis.close;
fis.avaiable();

能得到文件大小

byte[] bbuf=new byte[fis.avaiable()];

能读出文件大小的字节
如果文件很大会导致宕机

输入字节流InputStream

1. ByteArrayInputStream:字节数组输入流,该类的功能就是从字节数组(byte[])中进行以字节为单位的读取,也就是将资源文件都以字节的形式存入到该类中的字节数组中去,我们拿也是从这个字节数组中拿
2. PipedInputStream:管道字节输入流,它和PipedOutputStream一起使用,能实现多线程间的管道通信
3. FilterInputStream :装饰者模式中处于装饰者,具体的装饰者都要继承它,所以在该类的子类下都是用来装饰别的流的,也就是处理类
4. BufferedInputStream:缓冲流,对处理流进行装饰,增强,内部会有一个缓存区,用来存放字节,每次都是将缓存区存满然后发送,而不是一个字节或两个字节这样发送。效率更高
5. DataInputStream:数据输入流,它是用来装饰其它输入流,它“允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型”
6. FileInputSream:文件输入流。它通常用于对文件进行读取操作
7. File:对指定目录的文件进行操作,具体可以查看讲解File的博文。注意,该类虽然是在IO包下,但是并不继承自四大基础类。
8. ObjectInputStream:对象输入流,用来提供对“基本数据或对象”的持久存储。通俗点讲,也就是能直接传输对象(反序列化中使用)

输出字节流OutputStream

1. OutputStream 是所有的输出字节流的父类,它是一个抽象类。
2. ByteArrayOutputStream、FileOutputStream 是两种基本的介质流,它们分别向Byte 数组、和本地文件中写入数据。PipedOutputStream 是向与其它线程共用的管道中写入数据
3. ObjectOutputStream 和所有FilterOutputStream 的子类都是装饰流(序列化中使用)。

字符流操作

一个字符一个字符的读

FileReader fr=new FileReader("/opt/test/nobur.out");
BufferedReader br=new BufferedReader(fr);
new String();
String str=" ";
While((str=br.readline())!null
{System.out.println(str);
}

FileReader的底层还是FileInputStream()
BufferedReader的缓存,先把数据读到缓存流里,再从缓存流往外读

字符输入流Reader

1. Reader 是所有的输入字符流的父类,它是一个抽象类。
2. CharReader、StringReader 是两种基本的介质流,它们分别将Char 数组、String中读取数据。PipedReader 是从与其它线程共用的管道中读取数据
3. BufferedReader 很明显就是一个装饰器,它和其子类负责装饰其它Reader 对象。
4. FilterReader 是所有自定义具体装饰流的父类,其子类PushbackReader 对Reader 对象进行装饰,会增加一个行号。
5. InputStreamReader 是一个连接字节流和字符流的桥梁,它将字节流转变为字符流。FileReader 可以说是一个达到此功能、常用的工具类,在其源代码中明显使用了将FileInputStream 转变为Reader 的方法。我们可以从这个类中得到一定的技巧。Reader 中各个类的用途和使用方法基本和InputStream 中的类使用一致。

字符输出流Writer

1. Writer 是所有的输出字符流的父类,它是一个抽象类。
2. CharArrayWriter、StringWriter 是两种基本的介质流,它们分别向Char 数组、String 中写入数据。PipedWriter 是向与其它线程共用的管道中写入数据,
3. BufferedWriter 是一个装饰器为Writer 提供缓冲功能。
4. PrintWriter 和PrintStream 极其类似,功能和使用也非常相似。
5. OutputStreamWriter 是OutputStream 到Writer 转换的桥梁,它的子类FileWriter 其实就是一个实现此功能的具体类(具体可以研究一SourceCode)。功能和使用和OutputStream 极其类似

字节流和字符流使用情况

字符流和字节流的使用范围:字节流一般用来处理图像,视频,以及PPT,Word类型的文件。字符流一般用于处理纯文本类型的文件,如TXT文件等,字节流可以用来处理纯文本文件,但是字符流不能用于处理图像视频等非文本类型的文件

字符流与字节流转换

1. 转换流的作用,文本文件在硬盘中以字节流的形式存储时,通过InputStreamReader读取后转化为字符流给程序处理,程序处理的字符流通过OutputStreamWriter转换为字节流保存。
2. 转换流的特点:
其是字符流和字节流之间的桥梁
可对读取到的字节数据经过指定编码转换成字符
可对读取到的字符数据经过指定编码转换成字节
3. 何时使用转换流
当字节和字符之间有转换动作时;
流操作的数据需要编码或解码时。
4. 具体的对象体现:
InputStreamReader:字节到字符的桥梁
OutputStreamWriter:字符到字节的桥梁
这两个流对象是字符体系中的成员,它们有转换作用,本身又是字符流,所以在构造的时候需要传入字节流对象进来。

OutputStreamWriter(OutStreamout):将字节流以字符流输出。
InputStreamReader(InputStream in):将字节流以字符流输入。

字节流和字符流的区别

节流没有缓冲区,是直接输出的,而字符流是输出到缓冲区的。因此在输出时,字节流不调用colse()方法时,信息已经输出了,而字符流只有在调用close()方法关闭缓冲区时,信息才输出。要想字符流在未关闭时输出信息,则需要手动调用flush()方法。
· 读写单位不同:字节流以字节(8bit)为单位,字符流以字符为单位,根据码表映射字符,一次可能读多个字节。
· 处理对象不同:字节流能处理所有类型的数据(如图片、avi等),而字符流只能处理字符类型的数据

设备流,转换流,包装流

  1. 设备流
    file 文件设备
    socket 网设备
    array 内存设备(拿内存做设备使用)
    tty 封装

  2. 包装流
    把字节流重新封装一遍变成字符流

InputStreamReader reader=new InputStreamReader(System.in);

输入字符流

PrintStream ps=new PrintStream(System.out);

输出字符流

字符流必须有缓存区

  1. 转换流
    将输入转换为文件,从文件中往外读

随机文件

RandomAccessFile raf=new RandomAccessFile("out.txt","rw");

随机读随机写

序列化与反序列化

堆中的数据时不连续的,将数据放入内核态中的硬盘中,需要顺序化,此过程便是序列化,反之从硬盘读出数据,变成java对象使用,便是反序列化

序列化

将保存在内存中的对象数据转化为二进制数据流进行传输,任何对象都可以序列化

序列化数据类型数据:基础数据类型与String

表示层协议(数据展示协议)
xml,json,csv,yaml,properties
protobbuf与thrift为非字符串,效率低,调错能力差

java中transient关键字 描述属性:序列化时不考虑,反序列化时清零

使类继承Externarizable接口,重写WriteExternal和ReadExternal方法,可以自定义序列化

  1. properties
    底层时hashmap(cnf,ini)
class card{int cid;}
class str{int id;
Strint name;
card[] cards;}
card c1=new card(1);
card c2=new card(1);
stu s1=new stu(1,"xxx",[c1,c2]);

//生成propertirs文件
Mysqe my=new Mysqe("opt/xxx.propeties");my.writeobj(s));

//用properties文件进行序列化
card=a.b
card.a.cid=1
card.b.cid=2
stu=s1
stu.s1.id=1
stu.s1.name="xxx"
stu.s1.cards=a b

Mysqe my=new sqe("opt/xxx.properties");
Stu s=my.readobj();
System.out.println(s.id,s.name,s.card[0].cid);
  1. csv
    二维格式(二维表)
    序列化后是两个文件
    能自动填充到Excel表格中

card.csv

cid
1
2

stu.csv

id,name,caeds
1,xxx,cid=1;cid=2
2,yyy,cid=3
  1. xml
    HTML是特殊的xml
    树形结构
<a xxx=1>sss</a>

开标签与闭标签
xxx为属性
sss为内容

<stus>
<stu id=1 name="xxx">
<cards>
<card cid=1/>
<card cid=2/>
</cards>
<stu/>
<stu>
<stu id=2 name="yyy">
<cards>
<card cid=3/>
</cards>
</stu>
</stus>

一句一句解释(弹栈)叫say解释

深度优先遍历:一次一个完整的对象
广度优先遍历:拿到所有对象的首层属性

  1. json
    特殊的jsp

kv对[{k;v}]

[{id:1,name:"xxx",card:[{cid:1},{cid:2}]],{~}}]
  1. yaml
stus:s1
 id: 1//必须有空格,不空格会报错
   name: "xxx"
      cards:
       -c1
         cid=1
       -c2
        cid=2
        
        s2
  id:2
   name:"xxx"
    card:
     -c3
      cid=3

缩进要一样,以示属性相同或上下级关系

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值