IO流---字节流.Java

一,概述

IO流是存储和读取数据的解决方案。

  • I:input              O:output
  • 流:像水流一样传输数据

因为IO流与File是息息相关的,所以在学习IO流之前,简单回顾一下File:😄😊😊

  • File表示系统中的文件或者文件夹的路径,利用File,我们可以获取文件信息(大小,文件名,修改时间),判断文件类型,创建文件/文件夹,删除文件/空文件夹...

📝注意📝File类只能对文件本身进行操作,不能读写文件里面存储的数据。而想要读写数据必须要用到今天所学的IO流,下面详细说一下IO流的读写作用:

二,作用 

用于读写数据(本地文件,网络)

IO流能做的事情主要是两点: 🍑🍑😊😊🎨

  • 写出:把程序中的数据写出到本地文件中,这个动作也叫做写出数据,output
  • 读取:还可以把本地文件中的数据读取到程序当中,这个动作也叫做读取数据,input

读写数据是以程序(也就是内存,因为程序运行在内存当中)为参照物的。

三,IO流的分类

1,按照流的方向分类:🧩

  • 输入流(读取)
  • 输出流(写出)

2,操作的类型分类:🧩🧩

  • 字节流(可操作所以类型的文件,如音频、视频、图片、文本)
  • 字符流( 只能操作纯文本文件)

📝📝📝什么是纯文本文件:

  • Windows自带的记事本打开能读懂,txt文件,md文件,xml文件,lrc文件...

四,IO流体系

 

🐳字节输入流:读取数据

🐳字节输出流:写出数据

上图当中出现的类都是抽象类,不能直接创建它们的对象,需要看他们的子类(实现类),下面就以字节输出流为例:

1,FileOutputStream

  • 操作本地文件的字节输出流,可以把程序中的数据写到本地文件中

🎨🎨书写步骤:🎨🎨

1)创建字节输出流对象:让程序跟文件之间产生数据传输的通道

  • 细节1:参数是字符串表示的路径或者File对象都是可以的
  • 细节2:如果文件不存在会自动创建一个新的文件,但是要保证父级路径时存在
  • 细节3:如果文件已存在,则会清空文件里的内容
  • 细节4:追加写入

2)写数据write():相当于数据在这个通道中进行传输

  • 细节:write()方法的参数是整数,但实际上写到本地文件中是整数在ASCII上对应的字符

3)释放资源:相当于把这个通道给砸了

  • 细节:每次使用完之后都要释放资源

代码演示:给空白文件aa,添加字符a

public class ByteStreamDemo1 {
    /*
    * 创建字节输出流对象
    * 写数据
    * 释放资源
    */
    public static void main(String[] args) throws IOException,FileNotFoundException {
        
        //给程序和这个文件之间建立一条通道
        FileOutputStream stream = new FileOutputStream("aa.txt");
        //传输所需数据
        stream.write(97);//ASCII表对应a
        //程序和文件之间的通道被砸掉
        stream.close();
    }
}

结果:

🍑🍑🍑🍑🍑🍑🍑🍑🍑🍑🍑🍑🍑🍑🍑🍑🍑🍑🍑🍑🍑🍑🍑🍑🍑🍑🍑🍑🍑🍑🍑

1.1 FileOutputStream写数据的3种方式

方法名称说明
void write ( int  b )一次写一个字节数据
void write ( byte[ ]  b )一次写一个字节数组数据
void write ( byte[ ]  b(数组),  int off(起始索引) , int len(个数))一次写一个字节数组的部分数据

代码演示:

public class ByteStreamDemo2 {
    public static void main(String[] args) throws IOException {
        //创建对象
        FileOutputStream stream = new FileOutputStream("aa.txt");
        //输出数据
        //方式1
        stream.write(98);//b
        //方式2
        byte[] bytes={97,98,99,100,101};
        stream.write(bytes);//abcde
        //方式3
        stream.write(bytes,1,3);//bcd
        //释放资源
        stream.close();
    }
}

结果:

🍑🍑🍑🍑🍑🍑🍑🍑🍑🍑🍑🍑🍑🍑🍑🍑🍑🍑🍑🍑🍑🍑🍑🍑🍑🍑🍑🍑🍑🍑🍑 

1.2 FileOutputStream写数据的两个小问题

1)换行写:🧩

  • 再次写出一个换行符就可以了
  • Windows:\r\n
  • Linux:\n
  • Mac:\r

  📝细节:在Windows操作系统当中,Java对回车换行进行了优化,虽然完整的是\r\n,但                      是只写一个\r或者\n,Java也可以实现换行,因为Java在底层会自动补全。                                                         

  📝建议:不要省略,还是全写。 

代码演示:  

public static void main(String[] args) throws IOException {
        FileOutputStream stream = new FileOutputStream("aa.txt");
        //内容1
        String s="llllla";
        byte[] bytes = s.getBytes();//字符串转换成字节
        stream.write(bytes);//llllla

        //换行
        String s1="\r\n";
        byte[] bytes1 = s1.getBytes();
        stream.write(bytes1);

        //内容2
        String s2="ye!!";
        byte[] bytes2 = s2.getBytes();
        stream.write(bytes2);

        //释放资源
        stream.close();
    }

结果:

2)续写:🧩🧩

  • 如果想要续写,打开续写开关即可
  • 开关位置:创建对象的第二个参数
  • 默认false:表示关闭续写,此时创建对象对清空文件
  • 手动传递true:表示打开续写,此时创建对象不会清空文件

代码演示: 

public class ByteStreamDemo4 {
    /*
    * 2,续写
    * */
    public static void main(String[] args) throws IOException {
        FileOutputStream stream = new FileOutputStream("aa.txt",true);
        String s="XUXIE";
        byte[] bytes = s.getBytes();
        stream.write(bytes);
        stream.close();

    }
}

 结果:

2,FileInputStream

  • 操作本地文件的字节输入流,可以把本地文件中的数据读取到程序之中

 🎨🎨书写步骤:🎨🎨

1)创建字节输入流对象:让程序跟文件之间产生数据传输的通道

  • 细节:如果文件不存在,就直接报错

Java为什么这么设计呢?🤔🤔🤔🤔

输出流:文件不存在,则会创建该文件。

               把数据写到文件当中

输入流:文件不存在,而是报错呢?

              因为创建出来的文件没有数据,读取什么呢?所以说就没有任何意义。

              所以Java就没有设计这种无意义的逻辑,文件不存在直接报错

✏️✏️程序中最重要的是:数据

2)读数据read():把文件中的数据读取到程序当中,返回的是字节

  • 细节1:一次读一个字节,读出来的是数据在ASCII上对应的数字
  • 细节2:读取不到数据,read()方法返回-1
  • 细节3:read()表示读取数据,而且读取一个数据就移动一次指针

3)释放资源:相当于把这个通道给砸了

  • 细节:每次使用完之后都要释放资源

代码演示:读取文件input.txt中的数据abcd(暂时不考虑中文)

package day0528IODemo;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class ByteInputStreamDemo1 {
    /*
    * 字节输入流
    * 1,创建对象
    * 2,读数据
    * 3,强制释放
    * */
    public static void main(String[] args) throws IOException {
        //创建input.txt文件
        File file = new File("input.txt");
        System.out.println(file.createNewFile());
        //创建字节输入流对象
        FileInputStream stream = new FileInputStream("input.txt");//文件文本为abcd

        //读数据   返回的是字节
        int i1 = stream.read();
        System.out.println(i1+"---"+(char)i1);//a

        int i2 = stream.read();
        System.out.println(i2+"---"+(char)i2);//b

        int i3 = stream.read();
        System.out.println(i3+"---"+(char)i3);//c

        int i4 = stream.read();
        System.out.println(i4+"---"+(char)i4);//d

        int i5=stream.read();
        System.out.println(i5+"---"+(char)i5);//如果在文件中读取不到数据,就会返回-1
        //强制释放
        stream.close();
    }
}

 结果:

2.1 FileInputStream循环读取

  • read():表示读取数据,而且读取一个数据就移动一次指针。返回-1,表示读取完毕,没有内容            了。 

📝📝只能说跟迭代器的指针一样,不会复位,每调用一次就会获得当前数据,然会指针后移一位,这也是下面必须定义第三方变量b的原因。

代码演示:读取文件input.txt中的数据abcd

package day0528IODemo;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class ByteInputStreamDemo2 {
   
    public static void main(String[] args) throws IOException {
        //创建对象
        FileInputStream stream = new FileInputStream("input.txt");//文件文本内容为abcd
        //循环读取
        int b=0;
        while ((b=stream.read())!=-1){
            System.out.print((char) b);//abcd
        }
        //释放资源
        stream.close();
    }
}

 结果:

2.2 FileInputStream一次读取多个字节

public int read()一次读一个字节数据(返回值为字节,也就是字符对应的ASCII值)
public int read(byte[] buffer) 一次读一个字节数组数据(返回值为读取的长度)

代码演示:

package day0528IODemo;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class ByteInputStreamDemo3 {
    /*
    * FileInputStream一次读多个字节
    *
    * 注意:一次读一个字节数组数据,每次读取会尽可能把数组装满
    * */
    public static void main(String[] args) throws IOException {
        FileInputStream stream = new FileInputStream("input.txt");

        //自定义了一个长度为2的数组
        byte[] bytes = new byte[2];
        int len = stream.read(bytes);//将读取到的数据放入数组,返回值为读取的长度

        //将数组转换成字符串,打印
        String s = new String(bytes);
        System.out.println(len);
        System.out.println(s);

        int len1=stream.read(bytes);
        String s1 = new String(bytes);
        System.out.println(len1);
        System.out.println(s1);

        int len2=stream.read(bytes);//文件内容已读取完,没有数据可读,所以返回-1
        String s2 = new String(bytes);//因为没有读取到内容,所以数组里面还是上次读取的内容
        System.out.println(len2);
        System.out.println(s2);

        stream.close();
    }

}

 结果: 

📝📝📝因为每次读取的数据都会放到字节数组中,覆盖上一次的数据,如果读取的内容不能装满数组,就会保持上一次的数据,然后也会把上一次的数据再次转换成字符串,就出现了重复。为了避免返回重复的数据,可以只将字节数组中,从0所以开始到read(byte[] buffer)方法读取的长度(返回值)转换成字符串。 

byte[] bytes = new byte[2];
int len = stream.read(bytes);//返回值为读取到的字节数,不是数组长度
String s = new String(bytes,0,len);//只将数组中0-len长度的内容转换成字符串
System.out.println(s);

3,文件拷贝

       前面我们已经学习过了写出和读取。写:就是把程序中的数据写到文件当中;读取:就是把文件中的数据读取到程序当中。那我们是不是可以边读取边写出把文件进行拷贝了呢🤔🤔🤔🤔

代码演示:

package day0528IODemo;

import java.io.*;

public class CopyDemo {
    public static void main(String[] args) throws IOException {
        long start = System.currentTimeMillis();
        //创建对象
        FileInputStream input = new FileInputStream("D:\\java\\copy.mp4\\刺绣video - Trim.mp4");
        FileOutputStream output = new FileOutputStream("copy1.mp4");

        //边读边写
        int b=0;
        
        
        //方法一:一个字节一个字节的读取
       /* while ((b=input.read())!=-1){
            output.write(b);
        }*/
        
        
        //方法二:定义字节数组,一次读取一个数组的长度      更快速
        byte[] bytes = new byte[1024 * 1024 * 5];
        while ((b=input.read())!=-1){
            output.write(bytes,0,b);
        }
        //释放资源
        output.close();
        input.close();

        long end = System.currentTimeMillis();
        System.out.println(end-start);
    }
}

 结果: 

查看拷贝的视频: 

五,不同JDK版本的try...catch异常处理方式(了解即可)

快捷键:异常代码全选中+ctrl+alt+T

1,基本做法 

package day0528IODemo;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class TryCatchDemo {
    /*
    * 利用try...catch...finally捕获拷贝文件中代码出现的异常
    * 格式:
    * try {

      }catch (){

      }finally {

      }
    * */
    public static void main(String[] args) {
        FileInputStream input =null;
        FileOutputStream output=null;
        try {
            input = new FileInputStream("D:\\java\\copy.mp4\\刺绣video - Trim.mp4");
            output = new FileOutputStream("copy1.mp4");

            //边读边写
            int b=0;
            byte[] bytes = new byte[1024 * 1024 * 5];
            while ((b=input.read())!=-1){
                output.write(bytes,0,b);
            }

        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            //释放资源   先定义的后释放
            //非空判断  null调用任何方法都必然报错
            if (output!=null) {
                try {
                    output.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            if (input!=null) {
                try {
                    input.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }

    }
}

2,JDK7版本 

JDK7版本对try...catch异常处理做了简化方案,增加了接口:AutoCloseable ,资源用完最后自动释放

package day0528IODemo;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class TryCatchDemoJDK7 {
    public static void main(String[] args) {
        try(FileInputStream input = new FileInputStream("D:\\java\\copy.mp4\\刺绣video - Trim.mp4");
            FileOutputStream output = new FileOutputStream("copy1.mp4");) {
            
            //边读边写
            int b=0;

            byte[] bytes = new byte[1024 * 1024 * 5];
            while ((b=input.read())!=-1){
                output.write(bytes,0,b);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

3,JDK9版本 

JDK7中,在try()中创建对象阅读性底,所以JDK9可以在外面创建对象,在try()中只用写对象名就行,其余的执行逻辑都和JDK7一样

package day0528IODemo;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class TryCatchDemoJDK9 {

    public static void main(String[] args) throws FileNotFoundException {
        FileInputStream input = new FileInputStream("D:\\java\\copy.mp4\\刺绣video - Trim.mp4");
        FileOutputStream output = new FileOutputStream("copy1.mp4");

        try(input;output) {

            //边读边写
            int b=0;
            byte[] bytes = new byte[1024 * 1024 * 5];
            while ((b=input.read())!=-1){
                output.write(bytes,0,b);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/673961.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数据结构--数组(详细分析)

目录 🍉引言 🍉数组 🍈数组的特性 🍈数组的优缺点 🍍优点: 🍍缺点: 🍈数组的声明与初始化 🍈数组的常见操作 🍍 插入操作 🍍…

QTP——功能测试

一、前言(课设目的及内容) QTP是quicktest Professional的简称,是一种自动测试工具。使用QTP的目的是想用它来执行重复的手动测试,主要是用于回归测试和测试同一软件的新版本。因此你在测试前要考虑好如何对应用程序进行测试&…

46、Flink 的 异步 I/O 算子详解

异步 I/O 1.需求 在与外部系统交互(用数据库中的数据扩充流数据)时,需要考虑与外部系统的通信延迟对整个流处理应用的影响。 同步交互:使用 MapFunction访问外部数据库的数据, MapFunction 向数据库发送一个请求然后…

企业软件产品和服务 之 设计保证安全 七项承诺

1. 引言 公司如何保护自己免受数据泄露的影响?标准答案就是: “启用多因素身份验证”——MTA(Enable multifactor authentication)。 但是,目前很多公司仍然盲目地只使用密码作为唯一的身份来源。 网络安全的核心是…

IPD推行成功的核心要素(九)需求管理助力产品从一次成功走向一直成功

在当今竞争激烈的商业环境中,项目的成功与否往往取决于其能否满足用户和利益相关者的需求。然而,理解、捕捉和有效管理这些需求并非易事。因此,需求管理在项目管理中扮演着至关重要的角色。需求管理是一个系统性的过程,旨在确保项…

直播分享|深入解析ts-morph:通过注释生成类型文档

♪ ♫ 你看小狗在叫 树叶会笑 风声在呢喃♫ ♪ 乘风追梦,童心未泯 OpenTiny 预祝所有大朋友、小朋友儿童节快乐~ 与此同时,OpenTiny 贡献者直播也即将开启啦~ 直播主题:【深入解析ts-morph:通过注释生成类型文档】 6月1日&am…

前驱图,程序执行和进程状态

目录 前驱图 程序的执行 顺序执行 并发执行 进程的定义 进程的状态 总结 前驱图 现在有两个任务分别为p1,p2; 只有执行了p1,才可以执行p2,此时可以称p1为p2的前驱。通过符号语言表示如下: p1->p2 程序的执行 下面引进一段代码来理解进程的概念…

IDEA 学习之 疑难杂症系列

IDEA 学习之 疑难杂症系列 1. Mapstruct 编译空指针问题 1.1. 现象 NullPointerException at org.mapstruct.ap.internal.processor.DefaultVersionInformation.createManifest1.2. 原因 MapStruct 在 IDEA 2020.3 版本编译 NPE 问题 1.3. 解决办法 2. IDEA 学习之 编译内…

什么牌子的开放式耳机质量好?2024超强实力派品牌推荐!

耳机对于一个音乐人有重要这个不必多说,我朋友是个音乐编辑,他经常需要长时间佩戴耳机进行音频编辑和混音工作。在尝试过多款开放式耳机后,都没找到合适的。今天,我将从专业角度为大家带来几款热门开放式耳机的测评报告&#xff0…

Python 高级数据类型

列表List 定义列表 可以将不同的基本数据类型或者列表装到一个列表里 my_list [1,2,3,4,5] print(my_list) # [1, 2, 3, 4, 5] 直接打印出列表的内容 print(type(my_list)) # <class list>my_list ["1","2","3","4","…

MYSQL之安装

一&#xff0c;下载仓库包 wget -i -c https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm二&#xff0c;安装仓库 yum -y install mysql80-community-release-el7-3.noarch.rpmsed -i s/gpgcheck1/gpgcheck0/g mysql-community.repo三&#xff0c;安装MY…

免费SSL证书的安全性与获取指南

SSL证书是一种数字凭证&#xff0c;用于加密用户与网站之间的信息交换&#xff0c;以确保传输的数据不被第三方窃取。它像是一个数字版的密封印章&#xff0c;为数据的传输过程提供了一层保护膜。 免费的SSL证书通常由CA机构提供&#xff0c;它们同样可以提供基础数据的加密服…

瑞吉外卖项目整体介绍

黑马程序员瑞吉外卖 文章目录 一、项目介绍二、产品原型展示三、技术选型四、功能架构五、角色 一、项目介绍 二、产品原型展示 产品原型&#xff0c;就是一款韩品成型之前的一个简单的框架&#xff0c;就是将页面的排版布局展现出来&#xff0c;使产品的初步构思有一个可视化…

跟着大佬学RE(一)

学了一个 map&#xff08;&#xff09;函数的使用 import base64rawData "e3nifIH9b_CndH" target list(map(ord, rawData)) # map 函数将 rawData 中的每个字符传递给 ord 函数。ord 函数返回给定字符的 Unicode 码点 print(target) # 打印 map 对象的内存地址&…

Prism 入门02,区域介绍

一.区域概念和使用方式 什么是区域(Region)?区域,在Prism 框架中,区域是模块化的核心功能之一,其主要作用是降低应用程序和模块之间的耦合度 。使用方式:在应用程序的界面中,划分出某块区域,并为这个区域定义一个唯一的区域名称。那么通过这个区域名称,应用程序就可以…

Android Display Graphics #1 整体框架介绍一

软件基础 Android的framework层提供了一系列的图像渲染API&#xff0c;可绘制2D和3D。简单理解就是上层开发APP的小伙伴提供了接口&#xff0c;开发者可以直接显示对应的自己内容。但如果掌握了Display底层逻辑再写上层app&#xff0c;会有掌控力&#xff0c;出问题可以根据lo…

【Mybatis】源码分析-自定义框架

1、自定义持久层框架 1.1、分析JDBC操作问题 package blnp.net.cn.jvm.demos;import java.sql.*;/*** <p></p>** author lyb 2045165565qq.com* createDate 2024/5/24 14:24*/ public class JdbcTest {public static void main(String[] args) {Connection conne…

大模型+RAG,全面介绍!

1 介绍 大型语言模型&#xff08;LLMs&#xff09;在处理特定领域或高度专业化的查询时存在局限性**&#xff0c;如生成不正确信息或“幻觉”。**缓解这些限制的一种有前途的方法是检索增强生成&#xff08;RAG&#xff09;&#xff0c;RAG就像是一个外挂&#xff0c;将外部数…

环路检测00

题目链接 环路检测 题目描述 注意点 返回环路的开头节点 解答思路 快慢指针确认链表中是否有环&#xff0c;如果无环则快指针最终会到达链表尾部&#xff0c;如果有环则快慢指针会相遇&#xff0c;当快慢指针相遇&#xff0c;此时新的节点node从head开始出发&#xff0c;与…

探索数据结构:便捷的双向链表

&#x1f511;&#x1f511;博客主页&#xff1a;阿客不是客 &#x1f353;&#x1f353;系列专栏&#xff1a;渐入佳境之数据结构与算法 欢迎来到泊舟小课堂 &#x1f618;博客制作不易欢迎各位&#x1f44d;点赞⭐收藏➕关注 ​​ 前言 前面我们学习了单链表&#xff0c;它解…