节制,是比仁慈更高尚的品德。|

subeipo

园龄:1个月粉丝:0关注:0

📂Java
🔖Java
2025-01-20 17:06阅读: 1评论: 0推荐: 0

Java初学者笔记-08、IO流

I:负责把磁盘和网络中的数据读到程序内存中去。
O:负责把程序内存中的数据写到网络或者磁盘中。
按照流的内容,IO流分为字节流字符流
字节流:最小单位是字节。适合操作所有类型的文件。比如音频、视频、图片文本等的复制,转移。
字符流:只适合操作纯文本文件。比如读写txt,java文件等。
结合IO和字节流字符流,可分为下面4种。

  1. 字节输入流 InputStream
  2. 字节输出流 OutputStream
  3. 字符输入流 Reader
  4. 字符输出流 Writer
字节输入流 字节输出流 字符输入流 字符输出流
InputStream OutputStream Reader Writer
FileInputStream FileOutputStream FileReader FileWriter
BufferedInputStream BufferedOutputStream BufferedReader BufferedWriter
InputStreamReader
PrintStream PrintWriter
DataInputStream DataOutputStream

字节流

抽象类 对应的实现类
字节输入流 InputStream 文件字节输入流 FileInputStream
字节输出流 OutputStream 文件字节输出流 FileOutputStream

文件字节输入流 FileInputStream

作用:以内存为基准,可以把磁盘文件中的数据以字节的形式读入到内存中去。

使用构造器创建文件字节输入流

创建字节输入流管道与源文件接通。

public FileInputStream(File file)
public FileInputStream(String pathName) //一般用这个
InputStream is = new FileInputStream("good.txt");

字节输入流管道对象的read()方法

方法 说明
public int read() 每次读取一个字节返回,如果发现没有数据可读会返回-1
public int read(byte[] buffer) 每次用一个字节数组去读取数据,返回字节数组读取了多少个字节,如果发现没有数据可读会返回-1
// 1.创建管道与文件连接
InputStream is = new FileInputStream("111.txt");
// 2.定义一个字节数组用于每次读取字节
byte[] buffer = new byte[1024];
// 3.定义一个变量记住每次读多少字节
int len;
// 4.循环读取并转成字符
while( (len = is.read(buffer)) != -1) {
String str = new String(buffer, 0 ,len);
System.out.print(str);
}
is.close();

文件字节输出流 FileOutputStream

作用:以内存为基准,把内存中的数据以字节的形式写出到文件中去。

使用构造器创建文件字节输出流

构造器 说明
public FileOutputStream(File file) 创建字节输出流管道与源文件对象接通
public FileOutputStream(String filepath) 创建字节输出流管道与源文件路径接通
public FileOutputStream (File *file, boolean append) 创建字节输出流管道与源文件对象接通,可追加数据
public FileOutputStream(String filepath, boolean append) 创建字节输出流管道与源文件路径接通,可追加数据

字节输出流管道对象的write()方法

方法名称 说明
public void write(int a) 写一个字节出去
public void write(byte[] buffer) 写一个字节数组出去
public void write(byte[] buffer, int pos , int len) 写一个字节数组的一部分出去
public void close() throws IOExcention 关闭流
byte[] bytes = "我爱你中国666".getBytes();
os.write(bytes); //我爱你中国666
os.write(bytes,0,3); //我
os.close();

换行符一般使用 "\r\n"
使用完流之后,需要马上关闭,因为这个管道占用的是硬件总线资源。

字节流的应用——文件复制

任何文件的底层都是字节,字节流做复制,是一字不漏的转移完全部字节,复制前后的文件格式一致就没问题!
复制过去必须要带文件名!

InputStream fis = new FileInputStream(srcPath);
OutputStream fos = new FileOutputStream(destPath);
byte[] buffer = new byte[1024];
int len;
while((len = fis.read(buffer)) != -1){
fos.write(buffer,0,len);
}
fis.close();
fos.close();

管道资源的释放方案

如何确保流一定能够被释放?如果发生意外,导致代码没有执行close()方法,怎么办?

方案一:使用finally代码区(不推荐)

finally代码区的特点:无论try中的程序是正常执行了,还是出现了异常,最后都一定会执行finally区,除非JVM终止。

//1.创建一个文件字节输入流管道与源文件连通
InputStream fis = null;
Outputstream fos = null;
try {
fis = new FileInputStream(srcPath);
fos = new FileOutputStream(destPath);
//2.读取一个字节数组,写入一个字节数组
byte[] buffer = new byte[1024];
int len;
while((len = fis.read(buffer))!= -1) {
fos.write(buffer, 0, len);
}
System.out.println("复制成功!");
} catch (Exception e) {
e.printStackTrace();
} finally {
//3.释放资源
try {
if(fos != null) fos.close():
} catch (Exception e) {
e.printStackTrace;
}
try {
if(fis != null) fis.close;
} catch (Exception e) {
e.printStackTrace;
}
}

方案二:使用try-with-resource(推荐)

JDK7开始提供的更简单的资源释放方案。

try (
// 1.在这里定义资源,用完后会自动调用其close方法关闭!
InputStream fis = new FileInputStream(scPath);
OutputStream fos = new FileOutputStream(destPath);
){
// 2.读取一个字节数组,写入一个字节数组
byte[] buffer = new byte[1024];
int len;
while((len = fis.read(buffer))!= -1) {
fos.write(buffer, 0, len);
}
system.out.println("复制成功!");
} catch (Exception e) {
e.printStackTrace);
}
  1. 资源不一定是管道资源,资源一般指的是最终实现了AutoCloseable接口的资源。
  2. 资源使用完毕后,会自动调用其close()方法,完成对资源的释放。

字符流

抽象类 对应的实现类
字符输入流 Reader 文件字符输入流 FileReader
字符输出流 Writer 文件字符输出流 FileWriter

文件字符输入流 FileReader

作用:以内存为基准,可以把文件中的数据以字符的形式读入到内存中去。

使用构造器创建文件字符输入流

创建字符输入流管道与源文件接通。

public FileReader(File file)
public FileReader(String pathName) //一般用这个

字符输入流管道对象的read()方法

方法 说明
public int read() 每次读取一个字符返回,如果发现没有数据可读会返回-1
public int read(byte[] buffer) 每次用一个字符数组去读取数据,返回字符数组读取了多少个字节,如果发现没有数据可读会返回-1

文件字符输入流每次读取多个字符,性能较好,而且读取中文是按照字符读取,不会出现乱码!这是一种读取中文很好的方案。

  1. 创建文件字符输入流管道。
  2. 定义一个字符数组,每次读多个字符。
  3. 定义一个变量记录读取长度。
  4. 循环读取。

文件字符输出流 FileWriter

使用构造器创建文件字符输出流

构造器 说明
public FileWriter(File file) 创建字符输出流管道与源文件对象接通
public Filewriter(String filepath) 创建字符输出流管道与源文件路径接通
public FileWriter (File file, boolean append) 创建字符输出流管道与源文件对象接通,可追加数据
public FileWriter(String filepath, boolean append) 创建字符输出流管道与源文件路径接通,可追加数据

字符输出流管道对象的write()方法

方法名称 说明
void write(int c) 写一个字符
void write(String str) 写一个字符串
void write(String str, int off, int len) 写一个字符串的一部分
void write(char[] cbuf) 写入一个字符数组
void write(char[] cbuf, int off, int len) 写入字符数组的一部分

字符输出流管道对象的刷新与关闭

方法名称 说明
public void flush() throws IOException 刷新流,就是将内存中缓存的数据立即写到文件中去生效!
public void close() throws IOException 关闭流的操作,包含了刷新

为什么要刷新?
在管道里有内存缓冲区,不是每个字符都要和磁盘进行耦合,而是在内存缓冲区先集中一波,只做一次IO统一刷新到磁盘中。
刷新就是通知内存赶紧将缓冲区的数据全部写出去。
关闭包含了刷新!

缓冲流-提高性能 Buffered

作用:可以提高字节输入流读取数据的性能
原理:缓冲字节输入流自带了8KB缓冲池;缓冲字节输出流也自带了8KB缓冲池。
public BufferedInputStream (InputStream is)把低级的字节输入流包装成一个高级的缓冲字节输入流,从而提高读数据的性能。
public BufferedoutputStream (OutputStream os)把低级的字节输出流包装成一个高级的缓冲字节输出流,从而提高写数据的性能。
public BufferedReader (Reader r)把低级的字符输入流包装成字符缓冲输入流管道,从而提高字符输入流谈字符数据的性能。public String readLine()读取一行数据返回,如果没有数据可读了,返回null。
public BufferedWriter (Writer r)把低级的字符输出流包装成一个高级的缓冲字符输出流管道,从而提高字符输出流写数据的性能。public void newline()换行。

字符输入转换流 InputStreamReader

作用:解决不同编码时,字符流读取文本内容乱码的问题。
解决思路:先获取文件的原始字节流,再将其按真实的字符集编码转成字符输入流,这样字符输入流中的字符就不乱码了。

构造器 说明
public InputStreamReader (InputStream is) 把原始的字节输入流,按照代码默认编码转成字符输入流(与直接用FileReader的效果一样)
public InputStreamReader (InputStream is , String charset) 把原始的字节输入流,按照指定字符集编码转成字符输入流(重点)
// 1.提取文件的原始字节流
InputStream is = new FileInputStream("111.txt");
// 2.使用指定字符集把原始字节流转换为字符输入转换流
Reader isr = new InputStreamReader(is, "GBK");
// 3.创建缓冲字符输入流包装低级的字符输入流
BufferedReader br = new BufferedReader(isr);

打印流 PrintStream | PrintWriter(实用)

非常实用,如果要输出使用这个就行。

构造器 说明
public PrintStream(OutputStream/File/String) 打印流直接通向字节输出流/文件/文件路径
public PrintStream (String fileName, Chgrset charset) 可以指定写出去的字符编码
public PrintStream(OutputStream out, boolean autoFlush) 可以指定卖现自动刷新
publis Printstream(Outputstream out, boolean autoFlush,String encoding) 可以指定实现自动刷新,并可指定字符的编码
打印流提供的方法 说明
public void printin(xxx xx) 打印任意类型的数据出去
public void write(int/byte[]/byte[]一部分) 可以支持写字节数据出去

打印流本身不支持追加,如果要追加需要包装低级管道。

try (
PrintStream ps = new PrintStream(new FileOutputStream("111.txt"), true);//追加
){
ps.print(97);
ps.println('a');
}catch (Exception e){
e.printStackTrace();
}

特殊数据流 DataInputStream | DataOutputStream (实用)

两者成对出现。通信经常需要这个,项目经常用到。
作用:允许把数据和其类型一并写出去。

构造器 说明
public DataInputStream(InputStream out) 创建特殊数据输入流包装基础的字节输入流
public DataOutputStream(OutputStream out) 创建特殊数据输出流包装基础的字节输出流
方法 说明
public final void writeByte(int v) throws IOException 将byte类型的数据写入基础的字节输出流
public final void writeInt(int v) throws IOException 将int类型的数据写入基础的字节输出流
public final void writeDouble(Double v) throws IOException 将double类型的数据写入基础的字节输出流
public final void writeUTF(String str) throws IOException 将字符串数据以UTF-8编码成字节写入基础的字节输出流
public void write(int/byte[]/byte[]的一部分) 支持写字节数据出去

本文作者:subeipo

本文链接:https://www.cnblogs.com/subeipo/p/18681979/java-chu-xue-zhe-bi-ji08io-liu

版权声明:本作品采用署名—非商业性使用—相同方式共享 4.0 协议许可协议进行许可。

posted @   subeipo  阅读(1)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起