JAVA高级部分IO流

1、什么是流

   在计算机系统中,将不同的输入输出源统一抽象为流,流是一种实现数据交换技术的核心,比较常见的流的使用在于:文件操作,网络数据传输等;流由两大核心部分构成:1.Input(输入),2.Output(输出)。

   java-io将流分为几种类别:

  1. 按流向分为:输入和输出

  2. 按类型分为:字节和字符

  3. 按功能分为:节点流和处理流

 

字节流

​ 所谓字节流,其实就是将数据以字节为单位进行读写相关操作,字节流一般用于对于一些二进制文件(图片,音频,视频等)进行读写操作,java中的字节流都是来自以下两个抽象类:

  1. InputStream(字节输入流)

  2. OutputStream(字节输出流)

InputStream类

inputStream类是所有字节输入流的父类,是一个抽象类,常用方法包含以下:

  1. available():获取当前流中的可读字节数

  2. close():关闭此流

  3. read():从流中读取一个字节,返回读取到的字节

  4. read(byte[] b):将流中读取到的字节存入到指定的字节数组中,返回真实读取的长度,读取不到返回-1

  5. read(byte[] b,int offset,int len):将流中读取奥的字节存入到指定的字节数组中(跳过offset个字节存储,存储长度为len),读取不到返回-1

InputStream类的常见子类有FileInputStream,ByteArrayInputStream,ObjectInputStream,FilterInputStream等,以FileInputStream类为例:

public class ReadFileDemo {
​
    public static void main(String[] args) throws IOException {     
        //创建File对象
        File f = new File("C:\\Users\\mrchai\\Desktop\\a.txt");
        //基于File对象创建文件字节输入流
        FileInputStream fis = new FileInputStream(f);
        //获取当前输入流的可读字节数
        int len = fis.available();
        //获取文件对象的可读字节数
        byte[] b = new byte[len];
        fis.read(b);        
        System.out.println(new String(b)); 
    }
}

​ 通过以上代码看出可以根据流中有效字节长度创建字节数组,在下一次读取时,直接将所有读取的内容存储到数组中,但是如果流中数据过大,将会需要消耗大量空间存储,考虑到空间的限制,一般不会一次性读完,而是采用循环的方式每次读取固定长度的数据并缓存到字节数组中,以减少内存空间的消耗,以上程序修改后,如下:

public class ReadFileDemo2 {
​
    public static void main(String[] args) throws IOException {
        //创建File对象
        File f = new File("C:\\Users\\mrchai\\Desktop\\a.txt");
        //基于File对象创建文件字节输入流
        FileInputStream fis = new FileInputStream(f);
    
        //声明一个指定长度的字节缓冲区(太大会消耗大量运行时内存)
        byte[] b = new byte[1024];
        //声明临时变量用于存储每次读取的字节的真实长度
        int len = 0;
        //循环读取
        while((len = fis.read(b)) != -1){
            String s = new String(b,0,len);
            System.out.println(s);
        }
        fis.close();
    }
​
}
​

OutputStream类

OutputStream类是所有字节输出流的父类,是一个抽象类,常用方法如下:

  1. write(byte[] b):将字节数组中的内容写入输出源(文件,网络,内存)

  2. write(byte[] b,int offset,int len):将字节数组中的内容从offset开始写入len长到输出源

  3. write(int b):将一个字节写入输出源

  4. flush():将流中的数据强制刷新到输出源

  5. close():关闭此流

OutputStream类的常见子类有FileOutputStream,ByteArrayOutputStream,ObjectOutputStream,FilterOutputStream等,以FileOutputStream类为例:

public class WriteFileDemo {
    public static void main(String[] args) throws IOException {
        //准备目标文件对象
        File file = new File("C:\\Users\\mrchai\\Desktop\\a.txt");
        //创建一个基于目标文件的字节输出流
        FileOutputStream fos = new FileOutputStream(file,true);
        
        String msg = "床前明月光,疑似地上霜!";
        //将需要通过输出流输出的内容转换为字节数组并输出
        fos.write(msg.getBytes()); 
        //关闭资源
        fos.close();
    }
}
​

字符流

​ 字符流,顾名思义,是以字符的形式对输入输出源操作,通常情况下一个字符表示两个字节,但是在一些unicode编码,如UTF-8则使用3个字节表示,但是由于字符流的特殊性,一般用字符流主要操作一些文本输入输出源(文本文档,记事本文件等字符数据);java中所有的字符流都从以下两个抽象类继承:

  1. Reader 字符输入流

  2. Writer 字符输出流

Reader

字符输入流,是所有字符输入流的父类,是一个抽象类,内部的常见方法如下:

  1. read():读取并返回一个字符

  2. read(char[] c):将从流中读取的字符存储到字符数组

  3. read(char[] c,int offset,int len):将从流中读取的字符存入字符数组(跳过offset个字节,写入len长)

  4. ready():返回此流是否准备好被读取的状态

  5. close():关闭此流

Reader类的常见子类包含:InputStreamReader,BufferedReader,FilterReader,PipedReader等,常见的间接子类有FileReader,使用如下:

public class ReaderDemo1 {
​
    public static void main(String[] args) throws IOException {
        
        File f = new File("C:\\Users\\mrchai\\Desktop\\3周疑问.txt");
        //根据给定的文件对象构建一个文件字符输入流对象
        FileReader fr = new FileReader(f);
        
//      System.out.println(fr.ready());
//      int i = fr.read();
//      System.out.println((char)i);
        
        char[] c = new char[512];
        int len = 0;
        while((len = fr.read(c)) != -1){
            String s = new String(c,0,len);
            System.out.println(s);
        }
        
    }
​
}
​

Writer

字符输出流,是所有字符输出流的父类,是一个抽象类,内部的常见方法如下:

  1. append(char c):向流中追加一个字符

  2. append(CharSequence c):向流中追加一个字符序列(字符串)

  3. witer(String s):写入一个字符串到目标输出源

  4. witer(char[] c):写入字符数组到目标输出源

Writer类的常见子类包含:OutStreamReader,BufferedWriter,FilterWriter,PipedWriter等,常见的间接子类有FileWriter,使用如下:

public class WriteDemo {
​
    public static void main(String[] args) throws IOException {
        
        File f = new File("C:\\Users\\mrchai\\Desktop\\test.txt");
        //获取文件的字符输出流,使用追加模式
        FileWriter fw = new FileWriter(f,true); 
        fw.write("飞流直下三千尺,疑是银河落九天");
        
        //使用字符流执行写入操作时,由于内置的字符缓冲区可能不能及时将内容输出
        //因此,需要手动调用flush强制将内容通过输出流输出或者执行close
//      fw.flush();
        fw.close();
    }
}
​

 

转换流、缓冲流打印流

​ 由于以上所提到的流,按照功能来说都属于节点流(直接跟输入输出源打交道),而在实际开发中有些需求可能会涉及到需要将字节流转换为字符流,或者将字符流转换为字节流等一些转换操作;另外也有可能需要将这些低级的节点流提高读取和写入效率,因此还需要一些高级流来进行处理,因此这些高级流也被称之为处理流,比如:转换流,缓冲流,打印流等。

转换流

java-io中的转换流主要分为两个:

  1. InputStreamReader:将字节流转换为字符流的桥梁

  2. OutputStreamWriter:将字符流转换为字节流的桥梁

缓冲流

缓冲流的出现主要为了提高节点流的读取和写入效率,使用方式通常为将其他节点流包装起来,io包中的缓冲流分为以下几个:

  1. BufferedReader

  2. BufferedWriter

  3. BufferedInputStream

  4. BufferedOutputStream

转换流&缓冲流综合使用1

public class StreamDemo {
​
    public static void main(String[] args) throws IOException {
        //获取标准输入流
        InputStream is = System.in;
        //将字节流转换为字符流(装饰器模式)  gbk  utf-8   gb2312  gb18030
        InputStreamReader isr = new InputStreamReader(is,"gbk");
        //将低级字符流转换为高级字符缓冲流
        BufferedReader br = new BufferedReader(isr);
        
        String s = br.readLine();
        System.out.println(s);
    }
}

转换流&缓冲流综合使用2

public class StreamDemo3 {
    public static void main(String[] args) throws IOException {
        String msg = "你好世界";
        OutputStream os = System.out;
        //将字符流转字节流的桥梁
        OutputStreamWriter osw = new OutputStreamWriter(os);
        //将低级字符输出流转换为缓冲流
        BufferedWriter bw = new BufferedWriter(osw);
        bw.write(msg);
        bw.close();
​
    }
}

打印流

另外在IO包中还提供了两个特殊的流,这两个流只有输出,没有输入:

  1. PrintStream 字节打印流

  2. PrintWriter 字符打印流

打印流通常可以对其他输出流(Writer,OutputStream)以及文件(File)进行包装,然后通过提供的相关API操作这些流,常见构造器:

  1. PrintStream

    1. PrintStream(File file)

    2. PrintStream(String fileName)

    3. PrintStream(OutputStream os)

    4. PrintStream(OutputStream os,boolean autoFlush)

  2. PrintWriter

    1. PrintWriter(File file)

    2. PrintWriter(String fileName)

    3. PrintWriter(OutputStream os)

    4. PrintWriter(OutputStream os,boolean autoFlush)

    5. PrintWriter(Writer w)

    6. PrintWriter(Writer w,boolean autoFlush)

使用如下:

public class PrintDemo {
​
    public static void main(String[] args) throws FileNotFoundException {
        //创建文件字节输出流(追加模式)
        OutputStream os = new FileOutputStream("C:\\Users\\mrchai\\Desktop\\test.txt",true);
        
//      PrintStream ps = new PrintStream(os);
//      ps.println("谁知盘中餐");
        
        PrintWriter pw = new PrintWriter(os,true);
        pw.println("粒粒皆辛苦");
//      pw.flush();
        
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值