Java-IO流

目录

 

一、JAVA流式输入/输出原理

二、输入输出流分类

三、节点流和处理流

四、InputStream(输入流)

InputStream的基本方法

以File(文件)这个类型作为讲解节点流的典型代表

五、OutputStream(输出流)

OutputStream的基本方法

六、Reader流

Reader的基本方法

七、Writer流

Writer的基本方法

演示使用FileWriter(字符流)向指定文件中写入数据

八、IO流总结


一、JAVA流式输入/输出原理

在Java程序中,对于数据的输入/输出操作以“流”(Stream)方式进行;J2SDK提供了各种各样的“流”类,用以获取不同种类的数据:程序中通过标准的方法输入或输出数据。
读入写出

二、输入输出流分类

Java.io 包中定义了多个流类型(类或抽象类)来实现输入/输出功能;可以从不同的角度对其进行分类:

  • 按数据流的方向不同可以分为输入流和输出流
  • 按照处理数据单位不同可以分为字节流和字符流
  • 按照功能不同可以分为节点流和处理流

两个概念:

  • 字节流:最原始的一个流,读出来的数据就是010101这种最底层的数据表示形式,一个字节(Byte)是8位(bit)读的时候不是一个位一个位的来读,而是一个字节一个字节来读。
  • 字符流:字符流是一个字符一个字符地往外读取数据。一个字符是2个字节

输入流:InputStream(字节流),Reader(字符流)
输出流:OutPutStream(字节流),Writer(字符流)

区分什么叫输入流?什么叫输出流?
如果站在文件的角度上,这叫输出。
如果站在程序的角度上,这叫输入。
我们以后说输入流和输出流都是站在程序的角度上来说。

三、节点流和处理流

1.节点流类型
节点流就是一根管道直接插到数据源上面,直接读数据源里面的数据,或者是直接往数据源里面写入数据。典型的节点流是文件流:

文件的字节输入流(FileInputStream),文件的字节输出流(FileOutputStream),文件的字符输入流(FileReader),文件的字符输出流(FileWriter)。

2.处理流类型

处理流是包在别的流上面的流,相当于是包到别的管道上面的管道。

四、InputStream(输入流)

继承自InputStream的流都是用于向程序中输入数据,且数据的单位为字节(8bit);下图中深色为节点流,浅色为处理流。

InputStream的基本方法

//读取一个字节并以整数的形式返回(0~255)
//如果返回-1就说明已经到了输入流的末尾
int read() throws IOException
//读取一系列字节并存储到一个数组buffer
//返回实际读取的字节数,如果读取前已到输入流的末尾,则返回-1
int read(byte[] buffer) throws IOException
//读取length个字节
//并存储到一个字节数组buffer,从length位置开始
//返回实际读取的字节数,如果读取前以到输入流的末尾返回-1.
int read(byte[] buffer,int offset,int length) throws IOException
//关闭流释放内存资源
void close() throws IOException
//跳过n个字节不读,返回实际跳过的字节数
long skip(long n) throws IOException

read()方法是一个字节一个字节地往外读,每读取一个字节,就处理一个字节。read(byte[] buffer)方法读取数据时,先把读取到的数据填满这个byte[]类型的数组buffer(buffer是内存里面的一块缓冲区),然
后再处理数组里面的数据。

以File(文件)这个类型作为讲解节点流的典型代表

使用FileInputStream流来读取FileInputStream.java文件的内容

package com.kou.chapter;
import java.io.*;
public class TestFileInputStream {
public static void main(String args[]) {
int b = 0;// 使用变量b来装调用read()方法时返回的整数
FileInputStream in = null;
// 使用FileInputStream流来读取有中文的内容时,读出来的是乱码,因为使用
InputStream流里面的read()方法读取内容时是一个字节一个字节地读取的,而一个汉字是占用两个
字节的,所以读取出来的汉字无法正确显示。
// FileReader in = null;
// 使用FileReader流来读取内容时,中英文都可以正确显示,因为Reader流里面的
read()方法是一个字符一个字符地读取的,这样每次读取出来的都是一个完整的汉字,这样就可以正确
显示了。
try {
in = new FileInputStream("D:\\IDEA\\CODE\\JAVASE\\src\\com\\kou\\Student.java");
// in = new FileReader("D:\\IDEA\\CODE\\JAVASE\\src\\com\\kou\\Student.java");
} catch (FileNotFoundException e) {
System.out.println("系统找不到指定文件!");
System.exit(-1);// 系统非正常退出
}
long num = 0;// 使用变量num来记录读取到的字符数
// 调用read()方法时会抛异常,所以需要捕获异常
try {
while ((b = in.read()) != -1) {
// 调用int read() throws Exception方法时,返回的是一个int类型的整
数
// 循环结束的条件就是返回一个值-1,表示此时已经读取到文件的末尾了。
// System.out.print(b+"\t");//如果没有使用“(char)b”进行转换,那
么直接打印出来的b就是数字,而不是英文和中文了
System.out.print((char) b);
// “char(b)”把使用数字表示的汉字和英文字母转换成字符输入
num++;
}
in.close();// 关闭输入流
System.out.println();
System.out.println("总共读取了" + num + "个字节的文件");
} catch (IOException e1) {
System.out.println("文件读取错误!");
}
}
}

五、OutputStream(输出流)

继承自OutputStream的流是用于程序中输出数据,且数据的单位为字节(8bit):下图中深色的为节点流,浅色为处理流。

OutputStream的基本方法

//向输出流中写入一个字节数据,该字节数据为参数b的低8位
void write(int b) throws IOException
//将一个字节类型的数组中的数据写入输出流
void write(byte[] b) throws IOException
//将一个字节类型的数组中的从指定位置(off)开始的len个字节写入到输出流
void write(byte[] b,int off,int len) throws IOException
//关闭流释放内存资源
void close() throws IOException
//将输出流中缓冲的数据全部写出到目的地
void flush() throws IOException

六、Reader流

Reader : 和InputStream一模一样,唯一的区别就在于读的数据单位不同继承自Reader的流都是用于向程序中输入数据,且数据的单位为字符(16bit)

16位:一个字符也就是两个字节,使用Reader流读取数据时都是两个字节两个字节往外读的,为什么还要有这两种两个字节的读取方式呢? 因为有些字符是占2个字节的,如我们的中文字符在Java里面就是占两个字节的。如果采用一个字节一个字节往外读的方式,那么读出来的就是半个汉字,这样子Java就没有办法正确的显示中文字符的,所以有必要存在这种流,一个字符一个字符地往外读。

Reader的基本方法

//读取一个字节并以整数的形式返回(0~255)
//如果返回-1就说明已经到了输入流的末尾
int read() throws IOException
//读取一系列字节并存储到一个数组buffer
//返回实际读取的字节数,如果读取前已到输入流的末尾,则返回-1
int read(byte[] buffer) throws IOException
//读取length个字节
//并存储到一个字节数组buffer,从length位置开始
//返回实际读取的字节数,如果读取前以到输入流的末尾返回-1.
int read(byte[] buffer,int offset,int length) throws IOException
//关闭流释放内存资源
void close() throws IOException
//跳过n个字节不读,返回实际跳过的字节数
long skip(long n) throws IOException

七、Writer流

继承自Writer的流都是用于程序中输出数据,且数据的单位为字符(16bit)

Writer的基本方法

//向输出流中写入一个字节数据,该字节数据为参数b的低16位
void write(int b) throws IOException
//将一个字节类型的数组中的数据写入输出流
void write(byte[] b) throws IOException
//将一个字节类型的数组中的从指定位置(off)开始的len个字节写入到输出流
void write(byte[] b,int off,int len) throws IOException
//关闭流释放内存资源
void close() throws IOException
//将输出流中缓冲的数据全部写出到目的地
void flush() throws IOException

 

演示使用FileWriter(字符流)向指定文件中写入数据

package com.kou.chapter;
/*使用FileWriter(字符流)向指定文件中写入数据写入数据时以1个字符为单位进行写入*/
import java.io.*;
public class TestFileWriter{
public static void main(String args[]){
/*使用FileWriter输出流从程序把数据写入到Uicode.dat文件中
使用FileWriter流向文件写入数据时是一个字符一个字符写入的*/
FileWriter fw = null;
try{
fw = new FileWriter("D:\\IDEA\\CODE\\JAVASE\\src\\com\\kou\\chapter\\StudentNew.java");
//字符的本质是一个无符号的16位整数
//字符在计算机内部占用2个字节
//这里使用for循环把0~60000里面的所有整数都输出
//这里相当于是把全世界各个国家的文字都0~60000内的整数的形式来表示
for(int c=0;c<=60000;c++){
fw.write(c);
//使用write(int c)把0~60000内的整数写入到指定文件内
//调用write()方法时,我认为在执行的过程中应该使用了“(char)c”进行强制
转换,即把整数转换成字符来显示
//因为打开写入数据的文件可以看到,里面显示的数据并不是0~60000内的整
数,而是不同国家的文字的表示方式
}
/*使用FileReader(字符流)读取指定文件里面的内容
读取内容时是以一个字符为单位进行读取的*/
int b = 0;
long num = 0;
FileReader fr = null;
fr = new FileReader("D:\\IDEA\\CODE\\JAVASE\\src\\com\\kou\\chapter\\StudentNew.java");
while((b = fr.read())!= -1){
System.out.print((char)b + "\t");
num++;
}
System.out.println();
System.out.println("总共读取了"+num+"个字符");
}catch(Exception e){
e.printStackTrace();
}
}
}

FileReader和FileWriter这两个流都是字符流,都是以一个字符为单位进行输入和输出的。

所以读取和写入占用2个字节的字符时都可以正常地显示出来,所谓的节点流指定就是直接把输入流或输出插入到数据源上,直接往数据源里面写入数据或读取数据。

八、IO流总结

 

部分图片来源:百度图片

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

寇大大

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值