JAVA IO流学习小结

File简介

要io首先得有文件,所以先介绍java中的文件类File。

File是java.io包下的类,File类的对象抽象代表当前操作系统的文件或者文件夹。

创建File对象时,文件路径中的分隔符使用斜线“/”或双反斜线“\\”或者使用“File.separator”作为分隔符。

//File.separator使用如下
File f = new File("D:" + File.separator + "dir1" + File.separator + "file1");

File类中常用方法小结:

boolean exist();//判断文件是否存在
boolean isFile();//判断是否文件
boolean isDirectoy();//判断文件夹
String File.getName();//获取文件
long File.lastModified();//最后修改时间
String getPath();//获取创建时的路径

由于通过File无法读写文件,所以需要IO流

IO流

字节流与字符流

IO流可根据传输的数据形式(大概算“数据形式”吧,不纠结专有名词)可分为字节流和字符流。

字节流中数据以字节为单位传输,字符流则以字符为单位。

字符集、编码、解码

字符集

数据在计算机中都是二进制码01,以字节为单位就是8bit一个单位,而字符是按特定规则编码而成的,不同的编码方式对应着不同的字符集,或者说不同的字符集有不同的编码方式。下面简单介绍ASCII码、GBK和UTF-8编码:

1. ASCII,全名美国信息交换标准代码,使用8bit编码一个字符,一共字母一个字节,总共可表示128个字符

2. GBK,用于编码汉字,兼容ASCII,包含两万多个汉字字符,汉字第一个字节第一位为1

3. Unicode32字符集,32bit存储,4个字节一个字符,太大不常用

4. UTF-8字符集,优化Unicode,采取可变长编码方案,分为4个长度区:1、2、3、4个字节

英文、数字只占用1个字节,汉字字符占用3个字节。区分规则:

一个字节首位为0,两个字节首位为110 第二个字节首位为10,三个字节首位1110,第二个字节首位10……

字符的编码和解码

//字符的编码和解码
Byte[] getBytes();//使用平台默认的字符集将String编码为一系列字节,存进新数组中
Byte[] getBytes(String cahrset);//指定字符集
//解码:
String(bytes[] bytes);//默认字符集解码
String(bytes[], String charset);//指定字符集解码
//例:
String s = new String(byte1, "GBK");

IO流体系

IO流分为输入流+输出流

或按数据最小单位分为字节流+字符流

字节流适合所有类型的文件,字符流只适合操作文本文件

叶节点就是抽象类的实现类

FileInputStream文件字节输入流

使用这些类时可使用多态方法,例如

InputStream stream = new FileInputStream("……");

Int Stream.read()读取文件的一个字节数据,会自增,一直循环可遍历输出,结束返回-1

在流使用结束后,要结束流释放资源,stream.close()

Int read(byte[] buffer) 可读取多个字节到buffer中,读满buffer或读完文件

在连续读取时,若最后读取到的不足以填满buffer,buffer中仍会满,读取的只会覆盖前面的数据,后面的仍会保留。所以在输出时,需要使用String(buffer, offset: 0, len: len)来实现"读多少出多少",0表示从buffer的头开始读,len表示获取出来的长度

由于按字节读取,分批读取可能会出现编码乱码问题,比如截断汉字编码,一次性读取完则不会出现截断问题

还可以使用byte[] readALLBytes()方法来读取,会返回所有的字节到一个数组中一起返回解码,若文件太大存不下就不会分配。

FileOutputStream文件字节输出流

输出时会自动创建输出的文件

1.创建一个字节输出流管道与目标文件接通

OutputStream os = new FileOutputStream("……");

在FileOutputStream后加true参数,表示追加输出,不会覆盖原数据

2.开始写字节出去

os.write()类比上述read()方法,每次写出一个字节,若直接输出会截断长字节编码导致输出乱码

综合使用上述俩流时,通过buffer数组来中继,读出到buffer中,再写出到目标文件中

释放资源

若操作流时出现问题导致程序中止,而没有执行末尾的close方法,则资源将被锁死。

Try-catch-finally

Try {

Sout();

}catch(Exception e){

e.printStackTrace();

}finally{

Sout();

}

加finally的区别在于,无论是否异常都会执行finally中的程序,而不会直接停止,除非JVM终止。

注意不要在finally中返回数据,主要用于释放资源

easier:

Try-with-resource:在try后加个(),在其中写资源分配的语句,结束后会自动释放

包装流

缓冲流

对原始流进行包装,提高原始流读写数据的性能

原来:不使用缓冲流,字节流每次读个字节进入内存的buffer然后写出,总共需要32次io

现在:加入8k缓冲流,2次读入,2次写出,一共4次io,内存中数据流动极快忽略时间,故大大提高速度

相当于默认使用buffer[8192]?

但是缓冲流仍然可以使用默认的read和write方法来一个一个字节读写?

使用原始流使用buffer,buffer与缓冲池同大时,效率相近,黑马说可以近似相同

缓冲池并非越大越快,缓冲池大虽然可以减少io次数,但是会增加单次io耗时。

BufferedInputStream(is, 32 * 1024)就是把字节输入流is包装成缓冲流,缓冲池大小32KB

缓冲流复制文件速度对比

缓冲流+一次读写一个数组 >= 原始流+一次读写一个数组 > 缓冲流+一次读写一个字节 >= 原始流+一次一个字节

对于缓冲池和byte[] buffer的大小,适中为好,太小会导致内外存io次数太多,太大会导致单此io时间过长,当使用buffer时,缓冲流和原始流复制文件速度相近。

字符输入转换流

解决不同编码时,字符流读取文本内容乱码的问题。

先获取文件的原始字节流,再将其按真实的字符集编码转换成字符输入流

用于文本复制时自然不会乱码,毕竟没有解码,但是在程序中读取并操作时,就会乱码

读入的时候,将原始流通过

InputStreamReader类包装,可指定也可自定义字符集编码,然后就可通过特定字符类型读入

写出同理。

打印流PrintStream

打印流能实现打印啥出去就是啥出去

可支持自动刷新和自定义打印字符集

应用:改变打印流方向

数据流

用于io数据及其类型

DataOutputStream dos = new DataOutputStrram(new FileOutputStream("……"));

Dos.writeInt

Dos.writeUTF("……")

DataInputStream ios = new InputStream(new FileInputStream("……"));

Ins.readInt()

Ins.readDouble()

序列化流

用ObjectInputStream类包装一个原始流,然后writeObject(Object obj)

如果要序列化某个类,该类要实现Serializable接口

学习黑马java基础篇io流小结,不甚全面,对于性能的探究并不深入,针对一40000KB大小文件,缓冲池与buffer在256KB时速度整体最快,增加到512KB、1MB时速度开始减慢

仍有疑惑,当buffer为50000KB时,速度反而极慢,此时只有读文件到buffer,写到目标这两次IO,单次IO会这么慢吗?

256KB时有320次左右IO,却最快。

以后再究,第一次blog,希望能坚持下去,也算挖个坑吧

  • 25
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
很抱歉,作为文本AI助手,我无法绘制思维导图。但是,我可以为您提供一个简要的java IO流知识点总结。 Java IO流Java中用于处理输入和输出的机制。它提供了一种有效的方式来读取和写入数据,以及与文件、网络和其他设备进行交互。 Java IO流包括字节流和字符流两种类型。字节流以字节为单位进行操作,适用于处理二进制数据。而字符流以字符为单位进行操作,适用于处理文本数据。 常用的字节流包括InputStream和OutputStream类,用于读取和写入字节数据。常用的字符流包括Reader和Writer类,用于读取和写入字符数据。可以通过使用字节流和字符流的组合来实现不同类型数据的读写操作。 在Java IO流中,还有一些特殊的流,如缓冲流、转换流、对象流等。缓冲流提供了缓冲区来提高IO性能。转换流用于处理字符编码和解码。对象流用于对Java对象进行读写操作。 此外,Java IO流还包括一些常用的类和方法,如File类用于处理文件和目录,RandomAccessFile类用于对文件进行随机访问,FileInputStream和FileOutputStream类用于读写文件等。 通过组合和使用不同类型的流和类,您可以实现各种复杂的IO操作,如读写文件、网络通信、序列化对象等。 希望这个简要总结对您有所帮助。如果您有任何更具体的问题,请随时提问。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [万字长文+思维导图帮你梳理 Java IO 流,还学不会你来打我(值得收藏)](https://blog.csdn.net/a1405/article/details/116766237)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值