java-IO基本知识点

IO

  本节内容在我们开发需求中十分常见,我个人认为理解java IO知识点的重中之重在于理解java.io包下每一种流之间存在的关系。下面我将关系图、基本操作放出(自己敲一遍,且找一下各类存在的关系有助于加深印象)。
在这里插入图片描述

一、字节流

1.关系图
字节流
2.使用代码

package com.example.io;
import org.junit.jupiter.api.Test;
import java.io.*;
/**
 * @author lqh
 * @date 2020/6/10
 */
public class ByteStreamTest {
    /**
     * IO(input/output)在计算机用语中时指输入输出,流是一种抽象的数据传输结构,
     * 主要用于进行数据的传输,所以IO流就是指用流的形式来进行数据传输。
     *
     *流的概念:流就像是一个通道,将两个设备之前建立连接,然后数据在通道直接传输
     *
     *      流的分类
     *          一、按操作数据的单位分:字节流和字符流
     *          二、按数据流的流向分:输入流和输入流
     *      四种常用流
     *          FileInputStream、FileOutputStream,FileReader,FileWriter
     *
     */
    @Test
    public void testFileInputStream(){
        /**
         * FileInputStream,字节输入流
         * 该流用于从文件读取数据,
         *      常用API:
         *      public int read() throws IOException                //到达文件末尾,则返回-1
         *      public int read(byte[] b) throws IOException
         *      public int read(byte[] b,int off,int len) throws IOException
         */
        File file=new File("E:"+File.separator+"AioDir"+File.separator+"fileInput.txt");
        InputStream f=null;
        if(!file.getParentFile().exists()) {
            file.getParentFile().mkdir();
        }
        try {
            if(!file.exists()){
                file.createNewFile();
            }
             f=new FileInputStream(file);
 /*           int  n=0;
            StringBuffer sBuffer=new StringBuffer();
            while (n!=-1)  //当n不等于-1,则代表未到末尾
            {
                n= f.read();//读取文件的一个字节(8个二进制位),并将其由二进制转成十进制的整数返回
                char by=(char) n; //转成字符
                sBuffer.append(by);
            }
            System.out.println(sBuffer);*/
            byte[] b=new byte[2];
            int len=0;
            while ((len=f.read(b))!=-1)  //当n不等于-1,则代表未到末尾
            {
                System.out.println(new String(b,0,len)); //读取后的字节数组内容
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(f!=null){
                try {
                    f.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    @Test
    public void testFileOutStream(){
        /**
         * FileOutputStream,字节输出流
         * 该流用于向文件中写数据
         * 如果该流打开文件进行输出时,目标文件不存在,那么该流就会创建文件
         *      常用API:
         *           public void write(int b) throws IOException
         *           public void write(byte[] b) throws IOException {}
         *           public void write(byte[] b,int off,int len) throws IOException{}
         *           public void close() throws IOException{}
         */
        File file=new File("E:"+File.separator+"AioDir"+File.separator+"fileOutput.txt");
        OutputStream f=null;
        try {
            f=new FileOutputStream(file,true);
            f.write("\n\rabc".getBytes());
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(f!=null){
                try {
                    f.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

二、字符流

1.关系图(注:FileReader和FileWriter的父类)

字符流
2.使用代码

package com.example.io;

import org.junit.jupiter.api.Test;

import java.io.*;

/**
 * @author lqh
 * @date 2020/6/11
 */
public class CharacterStreamTest {
    @Test
    public void testFileReader(){
        /**
         * int read():每次读取一个字符,读到最后返回 -1
         * int read(char[] buffer):将字符读进字符数组,返回结果为读取的字符数
         * int read(char[] buffer,int off,int len):将读取的字符存储进字符数组 buffer,返回结果为读取的字符数,从索引 off 开始,长度为 len
         */
        File file=new File("E:"+File.separator+"AioDir"+File.separator+"fileReader.txt");//文件编码:UTF-8
        Reader fileReader=null;
        //此处省略目录检查,假设文件存在
        try {
            fileReader=new FileReader(file);
            int len=0;
/*            while ((len=fileReader.read())!=-1){
                System.out.println((char)len);
            }*/

            //int read(char[] buffer,int off,int len)
            char[] buffer = new char[10]; //每次读取 10 个字符
            while((len=fileReader.read(buffer,0,10))!=-1){
                System.out.println(new String(buffer,0,len));
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(fileReader!=null){
                try {
                    fileReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    @Test
    public void TestFileWriter(){
        File file=new File("E:"+File.separator+"AioDir"+File.separator+"fileWriter.txt");
        /***
         * void write(int c):向外写出一个字符
         * void write(char[] buffer):向外写出多个字符 buffer
         * void write(char[] buffer,int off,int len):把 buffer 数组中从索引 off 开始到 len个长度的数据写出去
         * void write(String str):向外写出一个字符串
         */
        Writer fileWriter=null;
        try {
             fileWriter=new FileWriter(file,true);
             fileWriter.write("abc你好123");
             fileWriter.write("abc你好".toCharArray());
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(fileWriter!=null){
                try {
                    /**
                     * 此处如果注释flush和close,内容不能够写入
                     */
                    fileWriter.flush();
                    fileWriter.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

三、转换流

1.关系图
转换流
2.使用代码

/**
 * @author lqh
 * @date 2020/6/11
 */
public class ConversionFlowTest {
    /**
     * OutputStreamWriter
     * InputStreamReader
     */
    @Test
    public void testOutputStreamWriter(){
        File file=new File("E:"+File.separator+"AioDir"+File.separator+"fileOutput.txt");
        try {
            OutputStream outputStream=new FileOutputStream(file); //字节流
            Writer outputStreamWriter=new OutputStreamWriter(outputStream); //字节流转字符流
            outputStreamWriter.write("www.baidu.com");
            outputStreamWriter.write("\r\n你好");
            outputStreamWriter.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    @Test
    public void testInputStreamReader(){
        File file=new File("E:"+File.separator+"AioDir"+File.separator+"fileInput.txt");
        try {
            InputStream inputStream=new FileInputStream(file); //字节流
            Reader inputStreamReader=new InputStreamReader(inputStream); //字节流转字符流
            int len=0;
            char[] buffer = new char[10]; //每次读取 10 个字符
            while((len= inputStreamReader.read(buffer,0,10))!=-1){
                System.out.println(new String(buffer,0,len));
            }
            inputStreamReader.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

四、内存流(以字节内存流为例)

1.关系图
字节内存流关系图
2.使用代码


/**
 * @author lqh
 * @date 2020/6/11
 */
public class MemoryStreamTest {
    @Test
    public void testByteArrayOutputStream() throws IOException{
        /**
         * 内存流:在内存中读写数据 (特点:数据在内存中处理比磁盘(硬盘)要更快一些,有时候可能需要临时在内存中保存并处理数据,内存流效率会更高)
         * 好处及应用场景:
         *   1.代码中需要交换的数据,读写的数据,仅仅是代码之间需要交换,就没必要内存  ==》 磁盘   磁盘 ==》内存 【仅仅可以在内存读写上提高了效率】
         *   2.好处:提高了读写的效率,即数据处理的效率
         *   3.安全性:线程安全
         * ByteArrayInputStream :包含一个内部缓冲区,该缓冲区包含从流中读取的字节。内部计数器跟踪 read 方法要提供的下一个字节。
         * ByteArrayOutputStream : 此类实现了一个输出流,其中的数据被写入一个 byte 数组。缓冲区会随着数据的不断写入而自动增长。可使用 toByteArray() 和 toString() 获取数据。
         * CharArrayReader: 此类实现一个可用作字符输入流的字符缓冲区。
         * CharArrayWriter:此类实现一个可用作 Writer 的字符缓冲区。缓冲区会随向流中写入数据而自动增长。可使用 toCharArray() 和 toString() 获取数据。
         *
         * 注意:void close():关闭 内存流 无效。 之前的IO流都是跟磁盘文件建立了连接,需要关闭连接即关闭流! 而关闭内存流跟连接无关
         */
        //内存字节流
        ByteArrayOutputStream baos = new ByteArrayOutputStream();//不需要路径,写入内存,跟磁盘无需关联
        baos.write("ByteArrayOutputStream".getBytes());//将字符串变成字节数组,写入内存
        baos.close();//此处关闭内存流无效 下面的数据也可写入
        baos.write("\r\nhelloworld".getBytes());//注意:之前的IO流都是跟磁盘文件建立了连接,需要关闭连接即关闭流! 而关闭内存流跟连接无关
        byte[] byteArray = baos.toByteArray();//获取内存中存数据的数组
                 //使用内存输入流 读取获得内存中的保存数据的数组
        ByteArrayInputStream bais = new ByteArrayInputStream(byteArray);//ByteArrayInputStream(byte[] buf):创建一个 ByteArrayInputStream,使用 buf 作为其缓冲区数组。
                //读
        int len;
        byte[] b = new byte[1024];
        while((len = bais.read(b)) != -1){
            System.out.println(new String(b,0,len));
        }


        //内存字符流
        CharArrayWriter caw = new CharArrayWriter();
        caw.write("CharArrayWriter");
        char[] ch = caw.toCharArray();
            //使用内存输入流 读取获得内存中的保存数据的数组
        CharArrayReader car = new CharArrayReader(ch);
            //读
        int len2;
        char[] c = new char[10];
        while((len2 = car.read(c)) != -1){
            System.out.print(new String(c,0,len2));
        }
    }
}

五、打印流(以字节打印流为例)

1.关系图

字节打印流关系图
2.使用代码

    @Test
    public void testStream() throws FileNotFoundException {
        /**
         * 提供了一系列重载的print()和println()方法,用于多种数据类型的输出。
         * PrintStream和PrintWriter的输出不会抛出IOException异常。
         * PrintStream和PrintWriter有自动flush功能。
         * PrintStream 打印的所有字符都使用平台的默认字符编码转换为字节。 在需要写入字符而不是写入字节的情况下,应该使用 PrintWriter 类。
         * System.out返回的是PrintStream的实例。
         *
         */
        File file=new File("E:"+File.separator+"AioDir"+File.separator+"printFile.txt");
        PrintStream printStream=new PrintStream(file);
        printStream.println(123);
        printStream.println("你好");
        printStream.println("1+1="+2);
        printStream.printf("姓名:%s;年龄:%d;成绩:%f;性别:%c","tom",18,99.5f,'男') ;
        printStream.close();
    }

六、RandomAccessFile

1.关系图
随机访问文件

2.使用代码

    @Test
    public void testRandomAccessFile(){
        /**
         * 优点:
         *      1.既可以读也可以写
         *      2.可以指定位置进行读写
         * 构造器中定义的四种模式
         *          r   以只读的方式打开文本
         *          rw  读和写操作都是被允许的(文件不存在,自动创建)
         *          rws 相当于“rw”,要求对文件内容或元数据的每个更新都同步写入底层设备
         *          rwd 相当于“rw”,要求对文件内容的每个更新都同步写入底层设备
         *  操作文件记录指针:
         *          long getFilePointer():返回文件记录指针的当前位置
         *          void seek(long pos) : 将文件记录指针定位到pos位置
         */
        RandomAccessFile randomAccessFile=null;
        try {
             randomAccessFile=new RandomAccessFile("E:"+ File.separator+"AioDir"+File.separator+"randomAccessFile.txt","rw");
             System.out.println(randomAccessFile.getFilePointer());
             randomAccessFile.write("abcd123".getBytes());
             System.out.println(randomAccessFile.getFilePointer());
             randomAccessFile.seek(5);
             System.out.println(randomAccessFile.readLine());
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(randomAccessFile!=null){
                try {
                    randomAccessFile.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
        }
    }

七、缓冲流

1.关系图
在这里插入图片描述
2.使用代码

 @Test
    public void testCharBufferedStream(){
        File file=new File("E:"+File.separator+"AioDir"+File.separator+"bufferedOutputFile.txt");
        try {
            FileOutputStream outputStream=new FileOutputStream(file);
            BufferedOutputStream bufferedOutputStream=new BufferedOutputStream(outputStream);
            bufferedOutputStream.write("abcdefg".getBytes());
            bufferedOutputStream.close();
            outputStream.close();
            FileInputStream fileInputStream=new FileInputStream(file);
            BufferedInputStream bufferedInputStream=new BufferedInputStream(fileInputStream);
            byte[] b=new byte[1024];
            int len=0;
            while ((len=bufferedInputStream.read(b))!=-1){
                System.out.println(new String(b,0,len));
            }
            bufferedInputStream.close();
            fileInputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    @Test
    public void testCharacterBufferStream(){
        /**
         * 使用字符缓存流可以边读边写
         */
        File file=new File("E:"+File.separator+"AioDir"+File.separator+"bufferedCharacterFile.txt");
        try {
            FileReader reader=new FileReader(file);
            BufferedReader bufferedReader=new BufferedReader(reader);
            File file1=new File("E:"+File.separator+"AioDir"+File.separator+"writeBufferedCharacterFile.txt");
            FileWriter writer=new FileWriter(file1);
            BufferedWriter bufferedWriter=new BufferedWriter(writer);
            String str="";
            while ((str=bufferedReader.readLine())!=null){
                System.out.println(str);
                bufferedWriter.write(str);
                bufferedWriter.newLine();
            }
          char[] c=new char[1024];
            int len=0;
            while ((len=bufferedReader.read(c))!=-1){
                bufferedWriter.write(c,0,len);
            }
            bufferedWriter.flush();
            bufferedWriter.close();
            bufferedReader.close();
            writer.close();
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

八、对象流

1.关系图
对象流

2.使用代码

public class ObjectStream {
    /**
    * ObjectOutputStream:序列化
    * ObjectInputStream:反序列化
    *不能序列化Static和Transient修饰的成员变量
    **/
    public static void main(String[] args) {
        /**
         * ObjectOutputStream:序列化
         * ObjectInputStream:反序列化
         *不能序列化Static和Transient修饰的成员变量
         * 要序列化的对象必须实现Serializable接口,并且尽量显示的声明serialVersionUID常量
         *
         **/
        File file=new File("D:"+ File.separator+"TestIo"+File.separator+"demo.txt");
        //序列化:将内存中对象或基本类型数据序列化到磁盘中
        try {
            FileOutputStream fileOutputStream=new FileOutputStream(file);
            ObjectOutputStream oos=new ObjectOutputStream(fileOutputStream);
            oos.writeObject(new String("1223"));
            oos.flush();
            oos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        //反序列化:将磁盘中的可序列话文件反序列化到内存中
        try {
            FileInputStream fileInputStream=new FileInputStream(file);
            ObjectInputStream ois=new ObjectInputStream(fileInputStream);
            try {
                Object object=ois.readObject();
                System.out.println(object);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            ois.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值