首页 > 编程语言 >IO流详解--Robyn编程学习(Java)

IO流详解--Robyn编程学习(Java)

时间:2022-09-25 17:34:43浏览次数:71  
标签:读取 Java 字节 filePath -- Robyn close new String

为什么要学习IO流

文件在程序中是以流的形式来操作的(流也是Java程序和磁盘文件交互的方式)

IO流则是针对程序而已,I是输入,O是输出

IO流的知识体系

字节流与字符流

  • 字节流输入:FileInputStream
 public void readFile02() {
        String filePath = "F:\\hello.txt";
        //定义一个字节数组(一次读取8个字节)
        byte[] bytes = new byte[8];
        int readLen = 0;//这里表示读取的长度
        FileInputStream fileInputStream = null;//创建空输入流
        try {
            fileInputStream = new FileInputStream(filePath);//创建输入流
            while((readLen = fileInputStream.read(bytes)) != -1){//这里是按数组读取,一个回车直接读了一行
                System.out.println(new String(bytes,0,readLen));
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fileInputStream.close();//关闭输入流
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

小TIPS:这里的read()方法读取换行符会直接读取为一个空行,readline()方法在包装流bufferreader会用到,届时再详细区分。

  • 字节流输出:FileoutputStream
public void writeFile(){
        String filrepath = "F:\\hello.txt";
        FileOutputStream fileOutputStream = null;
        //创建一个写入对象
        try {
            fileOutputStream = new FileOutputStream(filrepath,true);
            String str = "hsp!world!";
            //也可以定义一个字节数组,提高写入的效果
            byte[] buf = new byte[1024];
            int readLen = 0;
            while ((readLen = fileInputStream.read(buf)) != -1) {
            fileOutputStream.write(buf, 0, readLen);//一定要使用这个方法
            }
            fileOutputStream.write(str.getBytes());//写入一个字符串数组,这里记住必须是字节数组
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fileOutputStream.close();//关闭字符串流
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

其实就是根据文件路径创建流,然后使用read()和write()方法

  • 字符流输入: FileReader
public void readFile02(){
        String filePath = "F:\\hello.txt";
        FileReader fileReader = null;
        //设置读取的字符
        int readLen = 0;
        char[] chars = new char[9];
        //创建读取对象
        try {
            fileReader = new FileReader(filePath);//原理跟字节流的一模一样!!!
            while((readLen = fileReader.read(chars))!= -1){
                System.out.println(new String(chars,0,readLen));
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                fileReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
  • 字符流输出:FileWriter
public void fileWriter(){
    String filePath = "F:\\hello.txt";
    FileWriter fileWriter = null;
    char[] chars = {'a','b','c'};
        try {
        fileWriter = new FileWriter(filePath);
        fileWriter.write(chars);//默认是覆盖写入,也可以直接用数组写入
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            fileWriter.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
        }

字节流与字符流的区别

1、定义

字节流是一种执行8位字节输入和输出的机制,基本单元为字节;而字符流是Java中执行16位Unicode输入和输出操作的机制,基本单元为Unicode码元

2、结尾

字节流以stream结尾;而字符流以reader和writer结尾

3、处理方式

字节流是最基本的,采用ASCII编码;它通常用于处理二进制数据,它是按字节来处理的,实际上它可以处理任意类型的数据,但它不支持直接写入或读取Unicode码元。

字符流采用Unicode编码,它是按虚拟机的encode来处理,也就是要进行字符集的转化;它通常处理文本数据,它支持写入及读取Unicode码元。

4、缓冲区

字节流默认不使用缓冲区;字符流使用缓冲区

节点流与包装流

在实际应用中,通常使用包装流来对底层的字节流进行包装,比如增加缓冲区,换行读取等方法,提高输入输出的效率。

  1. BufferedReader(在基础字符流上FileReader包装得到)

    public void BufferFile02(){
            String filePath = "F:\\hello.txt";
            FileReader fileReader = null;
            //设置读取的字符
            String line;
            //创建读取对象
            try {
                fileReader = new FileReader(filePath);//原理跟字节流的一模一样!!!
                BufferedReader bos = new BufferedReader(fileReader);//对字节流进行包装
                while((line = bos.readLine())!= null){
                    System.out.println(line);//直接按行读取,极大地提高了读取的效率
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    bos.close();//只需要关闭包装流就好,节点流可以自动关闭
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    
  2. BufferWriter (在基础字符流上FileWriter修饰得到)

    String filePath = "e:\\ok.txt";
    //创建 BufferedWriter
    //说明:
    //1. new FileWriter(filePath, true) 表示以追加的方式写入
    //2. new FileWriter(filePath) , 表示以覆盖的方式写入
    BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filePath));
    bufferedWriter.write("hello, 韩顺平教育!");//直接写入
    bufferedWriter.newLine();//插入一个和系统相关的换行
    bufferedWriter.write("hello3, 韩顺平教育!");
    bufferedWriter.newLine();
    //说明:关闭外层流即可 , 传入的 new FileWriter(filePath) ,会在底层关闭
    bufferedWriter.close();
    

    ———此外,为了防止每一次输入输出都要从底层调用数据,buffer流设置了缓冲区,这个在网络通讯中起到了很大的作用。

序列化与对象流(包装流的一部分)

​ 由于ObjectOutputStream实现了Serializable,因此常用来进行数据的序列化

String filePath = "e:\\data.dat";
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath));
oos.writeInt(100);// int -> Integer (实现了 Serializable)数据的序列化
oos.writeBoolean(true);// boolean -> Boolean (实现了 Serializable)

转换流(包装流)

相当于writer和reader的子类,可以把字节流转换编码格式,同时转化为字符流。

//2. 指定编码 gbk
InputStreamReader isr = new InputStreamReader(new FileInputStream(filePath), "gbk");
//3. 把 InputStreamReader 传入 BufferedReader
BufferedReader br = new BufferedReader(isr);
br.close();//只需要关闭外层流

close()和flush()的区别

close包含flush功能,但是flush具备刷新完,还可以继续写操作,close执行完了就流关闭了,不能再写入,所以,不能用close来代替flush。

此处贴个链接,学习一下大佬通过动手来分清两者差异的真操作

分清close和flush的区别

Properties

其实就是一个键值对的配置文件

//1. 创建 Properties 对象,读取配置文件
Properties properties = new Properties();
//2. 加载指定配置文件
properties.load(new FileReader("src\\mysql.properties"));
//3. 把 k-v 显示控制台
properties.list(System.out);
//4. 根据 key 获取对应的值
String user = properties.getProperty("user");
String pwd = properties.getProperty("pwd");
System.out.println("用户名=" + user);
System.out.println("密码是=" + pwd);

网络通讯中IO流的应用

服务器端与客户端的数据传输:

这里就是用了包装流对于基本的输入输出流进行包装

 //服务器端代码:接受并输出
//创建一个serverSocket对象,在本机的8888端口监听(serverSocket相当于一个服务)
        ServerSocket serverSocket = new ServerSocket(8888);
        //返回客户端连接的对象(找到socket)
        Socket socket = serverSocket.accept();
        //将客户端写入数据通道的数据接口,或者socket接口的输入流
        InputStream ios = socket.getInputStream();
        //将基础字节流转换为字符流(涉及到两个包装流)
        BufferedReader bos = new BufferedReader(new InputStreamReader(ios));

        //服务器端的处理逻辑
        String s = bos.readLine();//直接来读取方法
        String answer = "";
        if("name".equals(s)){
            answer = "我是本机";
        }else if("hobby".equals(s)){
            answer = "编写计算机程序";
        }else{
            answer = "我听不懂你说的话";
        }

        //5. 获取socket相关联的输出流(因为默认是字节传输的方式,所以需要努努力改成字符传输的方式)
        OutputStream outputStream = socket.getOutputStream();
        //    使用字符输出流的方式回复信息
        BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
        bufferedWriter.write(answer);
        bufferedWriter.newLine();// 插入一个换行符,表示回复内容的结束
        bufferedWriter.flush();//清空缓冲区数据,但是不关闭流

        //关闭外层流
        bos.close();
        bufferedWriter.close();
        //关闭网络服务
        socket.close();
        serverSocket.close();
 //客户端代码
//连接到服务端的8888接口,产生socket对象
        Socket socket = new Socket(InetAddress.getLocalHost(),8888);
        OutputStream outputStream = socket.getOutputStream();
        BufferedWriter bof = new BufferedWriter(new OutputStreamWriter(outputStream));//转化为字符流

        //从键盘读取用户问题
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入你的问题:");
        String question = scanner.next();

        bof.write(question);
        bof.newLine();
        bof.flush();//字符流必须得手动刷新一下才能写入数据通道(不然的话容易缓冲区堵塞)

        //4. 获取和socket关联的输入流. 读取数据(字符),并显示
        InputStream inputStream = socket.getInputStream();
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        String s = bufferedReader.readLine();
        System.out.println(s);

        //关闭外层流和对象
        bof.close();
        bufferedReader.close();
        socket.close();
        System.out.println("客户端退出!");

标签:读取,Java,字节,filePath,--,Robyn,close,new,String
From: https://www.cnblogs.com/robyn2022/p/16728302.html

相关文章

  • 常用的修饰符
    表单修饰符:.lazy  输入框失去光标修改模型数据.mumber 将得到的数据转为mumber类型.trim清除首尾空格 事件修饰符.once事件只执行一次.capture实现事件捕......
  • linux文件内容查看命令 实验报告
    实验任务Linux查看文件基础命令 实验环境一台centos7 实验步骤1.显示文件全部内容Cat+想要查看的文件名  2.显示文件全部内容并加行号  3.空行不......
  • Linux命令
    1.1 根目录 /bin/存放系统命令,普通用户和root都可以执行。放在/bin下的命令在单用户模式下也可以执行/boot/系统启动目录,保存与系统启动相关的文件,如内核文......
  • 使用Godaddy续费我的域名时遇到支付问题
    最近我的域名快到期了,需要跑到Godaddy上续费,因为听说续费时可以使用优惠码,我便在网上搜了一个优惠码PromoCode,试了一下的确是有效的也能便宜6元,然后便下单。结果在下单支......
  • OpenJudge 1.5.35:求出e的值
    35:求出e的值总时间限制:1000ms内存限制:65536kB描述利用公式e=1+1/1!+1/2!+1/3!+...+1/n!求e。输入输入只有一行,该行包含一个整数n(2<=n<=15),表示计......
  • 环境变量与多版本共存
    我们在cmd窗口内查找资源的时候1.先在当前路径查找2.如果没有则去系统环境变量中查找​修改环境变量之后需要使用新的cmd窗口多版本共存​拷......
  • mysql进阶
    1表的设计     一对一比如一个学生有一个账户,一个账户也只能被一个学生注册一对多可以创建两个表,一个学生表一个班级表  多对多  1号学生选......
  • 【博学谷学习记录】超强总结,用心分享|Java基础分享-HTTP 基本概念
    目录1.Http基本概念1.1协议1.2.传输1.3.超文本2.HTTP常见的状态码有哪些?   HTTP基本概念1.HTTP是什么?HTTP是超文本传输协议,也就是HyperText Transfer ......
  • 如何使用pandas中的时序数据分组运算
    https://www.zhihu.com/search?type=content&q=Pandas聚合时间序列数据注意以下的聚合是从当前时间点往后一段时间计算的。tmp_group=ori_data.groupby(['cols',pd.Gr......
  • 20201306吴龙灿第七、八章学习笔记
    知识点归纳一、文件操作1.文件操作级别​文件操作分为五个级别,按照从低到高的顺序可以如下表示:硬盘级别​这些操作多是针对系统的实用程序,一般用户不会涉及到它......