编程技术是改变世界的力量。
本站
当前位置:网站首页 > 后端语言 > 正文

「Java」一文认识IO操作流 java基础io全部流详解

gowuye 2024-04-04 11:54 12 浏览 0 评论

快速上手IO流

一、什么是文件?

这个我想大家都知道,ppt啊,world文件,都是文件

二、什么是文件流

文件是在程序中已流的形式来操作的

实在不行你们就理解为下面的 (杯子是文件)(水是数据)

水到胃就是输入流,往肚子里面输,

胃到水就是输出流,往肚子外吐。

三、常用的文件操作

1.创建文件

方式一

public static void main(String[] args) throws IOException {
 
        //方式1
        String filePath = "e:\\news1.txt"; //声明存放的地方,和文件名
        File file = new File(filePath); //把信息放出来
        file.createNewFile();			//创建文件
        System.out.println("创建成功");
    }

方式二 (根据父目录(就是存放路径)+子路径(就是文件名))

public static void main(String[] args) throws IOException {
 
        File filePath = new File("E:\\test");  //存放路径
        String fileName = "news2.txt";          //文件名称
        File file = new File(filePath,fileName);
        file.createNewFile();
        System.out.println("创建成功");
    }

有人在想为什么有第一个File对象 ,下面还有一个?

其实在计算机,如果有File对象,只是在内存中有这么一个对象,但是在硬盘里面还没有,我们需要createNewFile()这个操作,把这个对象放进去硬盘。

相当于:孩子妈肚子里有孩子,但是没有出来,需要createNewFile(),才可以出来。

方式三

public static void main(String[] args) throws IOException {
 
        String filePath = "E:\\test";  //存放路径
        String fileName = "news3.txt";          //文件名称
        File file = new File(filePath,fileName);
        file.createNewFile();
        System.out.println("创建成功");
    }

也是上面差不多,只不过上面的是File 对象,加String

这个是2个String

要注意存放路径 \\ ,也可以使用一个/

2.获取文件的相关信息

public static void main(String[] args) {
 
        String filePath = "e:\\news1.txt";
        File file = new File(filePath);
        System.out.println("得到文件名"+file.getName());
        System.out.println("得到文件绝对路径"+file.getAbsolutePath());
        System.out.println("得到文件父级目录"+file.getParent());
        System.out.println("得到文件大小(按字节)"+file.length());  //utf-8 一个英文1个字节1个汉字3个字节
        System.out.println("文件是否存在"+file.exists());
        System.out.println("是不是一个文件"+file.isFile());
        System.out.println("是不是一个目录"+file.isDirectory());

    }

输出

3.目录的创建和文件删除

判断e:\news1.txt文件是否存在,存在就删除

delete方法返回的是布尔值

public static void m1(){
 
        String filePath = "e:\\news1.txt";
        File file = new File(filePath);
        if (file.exists()){
 
           if (file.delete()){
 
               System.out.println("删除成功");
           }else{
 
               System.out.println("删除失败");
           }
        }else{
 
            System.out.println("文件不存在");
        }
    }

需要注意java中目录也是一个特殊的文件 也可以进行操作

public static void m2(){
 
        String filePath = "E:\\del";  //这里是目录
        File file = new File(filePath);
        if (file.exists()){
 
            if (file.delete()){
 
                System.out.println("删除成功");
            }else{
 
                System.out.println("删除失败");
            }
        }else{
 
            System.out.println("目录不存在");
        }
    }

需注意:目录里面有文件 delete删除不了

判断目录是否存在,没有就创建

需注意mkdirs()是创建多级目录,创建一级目录(就是一个文件夹)使用mkdir(),不正确使用会报错

public static void m3(){
 
        String DirectoryPath = "E:\\del\\a\\b\\c";
        File file = new File(DirectoryPath);
        if (file.exists()){
 
            System.out.println("目录存在");
        }else{
 
            if (file.mkdirs()){
 
                System.out.println("该目录创建成功");
            }else{
 
                System.out.println("创建失败");
            }
        }
    }

四、IO流原理及流的分类

1.流的分类和原理:

1)按照数据单位不同分为:

字节流(8 bit),字符流

注意字符流并不可以确定是多大单位,因为是要看编码格式的,

它们的效率谁好,那肯定字符流,因为字节流读取单位小,

应用场景:

那为什么要字节流,字节流可以操作二进制文件,比如音乐,视频,可以进行无损操作。

字符流用来操作文本文件这样的比较好。

2)按照数据流的流向分为:

输入流

输出流

3)按照流的角色不同分为:

节点流,处理流/包装流

字节流和字符流分别对应两种流

字节流的两大类:字节输入流,字节输出流

它们2个的顶级父类,分别是InputSream 和OutputStream 都是抽象类

使用的时候要实现它们的子类才可以

字符流的两大类:字符输入流,字符输出流

它们2个的顶级父类,分别是Reader 和Writer 都是抽象类

使用的时候要实现它们的子类才可以

Java的IO有40多个类,实际上非常规则,都是从上面4个抽象类派生出来的

由这四个类派生出来的子类名称都是以其父类名当子类名后缀。

IO流体系图:

文件 vs 流:

我们通过画图来看清楚流到底是什么:

物品(数据) 通过外卖小哥(流) 来传达到用户(程序)手上

反之一样

2.常用的类

2.1 字节流的常用流

  1. FileInputStream:文件输入流
  2. BufferedInputStream:缓冲字节输入流
  3. ObjectInputStream:对象字节输入流

来看看关系,发现BufferedInputStream的父类其实是FilterInputStream,但是这个父类也是InputStream的子类

2.1.1 FileInputStream常用类

构造方法:

那些参数是什么意思呢,其实我们看第一个就比较形象了,File对象是个文件(这里当物品/东西),FileInputStream 是外卖小哥,小哥拿着物品去送出去,物品和小哥之间有一定的联系。

开始操作:

使用read()无参数构造方法,读取完毕返回-1

public static   void readFile01(){
 
        String filepath = "E:\\test\\hello.txt";
        FileInputStream fileInputStream = null;  //如果定义在try里面 finally使用不了
        int readDate = 0;
        try {
 
            //创建FileInputStream对象用于读取文件
             fileInputStream = new FileInputStream(filepath);
            //read() 返回-1代表读取完毕
            while((readDate =  fileInputStream.read()) != -1){
    //为什么要循环因为读取的内容可能不是一次
                System.out.print((char)readDate);
            }
        } catch (IOException e) {
 
            e.printStackTrace();
        }finally {
 
            //关闭流 流是一种资源,不关闭会造成浪费
            try {
 
                fileInputStream.close();
            } catch (IOException e) {
 
                e.printStackTrace();
            }
        }

    }

使用read无参构造方法,其实还是有不好的单个效率太低,我们可以使用read的其他构造参数。

使用read()字符数组构造方法,读取完毕返回-1,未结束反复字符数组的长度,

public static   void readFile02(){
 
        //字节数组
        byte[] buf = new byte[8];//一次读8个字节
        int readDate = 0; //接收字符的长度
        String filepath = "E:\\test\\hello.txt";

        FileInputStream fileInputStream = null;  //如果定义在try里面 finally使用不了
        try {
 
            //创建FileInputStream对象用于读取文件
            fileInputStream = new FileInputStream(filepath);
            //read() 返回-1代表读取完毕
            while((readDate =  fileInputStream.read(buf)) != -1){
    //为什么要循环因为读取的内容可能不是一次
                System.out.print(new String(buf,0,readDate));//
            }
        } catch (IOException e) {
 
            e.printStackTrace();
        }finally {
 
            //关闭流 流是一种资源,不关闭会造成浪费
            try {
 
                fileInputStream.close();
            } catch (IOException e) {
 
                e.printStackTrace();
            }
        }
    }

2.1.2 FileOutputStream常用类

构造方法:

类图:

题目:

public static void writerFile(){
 
         //创建一个FileOutPutStream
        String filePath = "E:\\test\\a.txt";
        FileOutputStream fileOutputStream = null;

        try {
 
            //得到FileOutputStream对象
            fileOutputStream = new FileOutputStream(filePath);
            //写入一个字节
            //fileOutputStream.write('a');
            //写入一个字符串
            String str = "hello,world";
            fileOutputStream.write(str.getBytes());
             // String的方法,把字符串转为字符数组,write() 会覆盖
            System.out.println("写入成功");
        } catch (IOException e) {
 
            e.printStackTrace();
        }finally {
 
            try {
 
                fileOutputStream.close();
            } catch (IOException e) {
 
                e.printStackTrace();
            }
        }

    }

Write ()会覆盖,如果不想覆盖就,第二个参数变成true,追加到文字后。

2.1.3 使用字节输入输入出流拷贝一个文件

public static void main(String[] args) {
 
        //src 原目标文件   dest 拷贝到什么位置
        String srcfilePath = "C:\\Users\\Administrator\\Pictures\\Saved Pictures\\QQ图片20210806104237.jpg";
        String destfilePath = "D:\\A1\\QQ.jpg";
        FileInputStream fileInputStream = null;
        FileOutputStream fileOutputStream = null;

        try {
 
            fileInputStream = new FileInputStream(srcfilePath);  //先图片输入到程序
            fileOutputStream = new FileOutputStream(destfilePath); //在从程序输出到文件夹
            //定义字节数组提高效率
            byte []  buf =  new byte[1024];
            int readLen = 0;
            while ((readLen = fileInputStream.read(buf))!= -1){
 
                //读取到程序就由程序写出去 通过fileOutputStream
                //边读边写
                fileOutputStream.write(buf,0,readLen);
                //一定使用这个方法 带这些参数 为什么呢?因为怕其他的冗余数据进去 破坏文件 1039个字节,一次1024 还有剩余可能会有问题
            }
            System.out.println("拷贝OK");
        } catch (IOException e) {
 
            e.printStackTrace();
        }finally {
 
            //关闭输入输出流
            if(fileInputStream != null){
 
                try {
 
                    fileInputStream.close();
                } catch (IOException e) {
 
                    e.printStackTrace();
                }
            }
            if(fileOutputStream != null){
 
                try {
 
                    fileOutputStream.close();
                } catch (IOException e) {
 
                    e.printStackTrace();
                }
            }
        }

    }

2.2 字符流的常用流

  1. FileReader:

类图:

  1. FileWriter:

类图:

2.2.1 FileReader常用类

public static void main(String[] args) {
 
        String filePath = "E:\\test\\story.txt";
        //1.创建一个对象
        FileReader fileReader = null;
        int date = 0;
        try {
 
            fileReader = new FileReader(filePath);
            while((date = fileReader.read())!=-1){
 
                System.out.print((char) date);
            }

        } catch (IOException e) {
 
            e.printStackTrace();
        }finally {
 
            try {
 
                fileReader.close();
            } catch (IOException e) {
 
                e.printStackTrace();
            }
        }

    }

使用字符数组来

public static void main(String[] args) {
 
        String filePath = "E:\\test\\story.txt";
        //1.创建一个对象
        FileReader fileReader = null;
        int readLen = 0;
        char [] buf = new char[1024];
        try {
 
            fileReader = new FileReader(filePath);
            //循环读取 使用read(buf) ,返回实际读取到的字符数,返回-1 文件结束
            while((readLen = fileReader.read(buf))!=-1){
 
                System.out.print(new String(buf,0,readLen));
            }

        } catch (IOException e) {
 
            e.printStackTrace();
        }finally {
 
            try {
 
                fileReader.close();
            } catch (IOException e) {
 
                e.printStackTrace();
            }
        }
    }

new String(buf,0,readLen) 从什么数组,从几下标开始,取多少个

2.2.2 FileWriter常用类

public static void main(String[] args) {
 
        String FilePath = "E:\\test\\a.txt";
        FileWriter fileWriter = null;
        char [] chars = {
 'y','y'};
        try {
 
            fileWriter = new FileWriter(FilePath);
            //写入单个字符
            fileWriter.write('H');
            //写入指定的数组
            fileWriter.write(chars);
            //写入数组的指定部分
            fileWriter.write("Blog,666".toCharArray(),0,4);
            //写入整个字符串
            fileWriter.write("北京你好");
            //写入字符串指定的指定部分
            fileWriter.write("上海天津",0,2);
        } catch (IOException e) {
 
            e.printStackTrace();
        }finally {
 
            try {
 
                fileWriter.close();
                //对应FileWriter ,一定要关闭流,或者flush才可以真正的把数据写进去
            } catch (IOException e) {
 
                e.printStackTrace();
            }
        }
    }

注意一定要使用close()或者flush()方法,不然数据不会成功写入。

这篇文章就不讲为什么,有兴趣的可以自己去那个方法的底层看看或者看看别人的博客。

3.节点流,处理流

节点流:可以简单说是直接与数据源进行操作,是什么类型的文件就使用支持的节点流(上面有分类)

但是我们现在要对数组进行操作,我们还得换一个节点流。一点不灵活

但是我们现在想让文件操作功能变得强大一点就使用包装流类,也就是上面说的处理流,可以即对文件类型操作,也可以对数组源来操作, 我们使用BufferedReader 和 BufferedWriter

那么为什么他们可以这么灵活呢,我们去看看源码

BufferedReader 的源码里面就有个属性Reader, 这个Reader的子类有那些节点流子类,那么就说我们以后可以直接使用Reader的任意子类。

Reder的子类有多少呢,我们来看一部分

BufferedWriter也是一样的,里面有个属性Writer

类图:Writer的子类

所以这就是BufferedReader 和 BufferedWriter的强大的地方

3.1节点流和处理流的区别和联系

节点流很底层的~~直接和数据打交道

3.2 处理流-BufferedReader 和 BufferedWriter

3.2.2 BufferedReader

看看关系先

关闭的时候,其实会自己去关闭他的包装的节点流

操作案列~~

代码:

public static void main(String[] args) throws Exception {
 
        //要操作的文件路径
        String pathFile = "E:\\test\\j.txt";
        //创建BuffeReader
        BufferedReader bufferedReader = new BufferedReader(new FileReader(pathFile));
        //读取
        String line;
         //按行读取,效率高
        //1.bufferedReader.readLine() 按行读取 返回空 读取完毕
        while((line = bufferedReader.readLine())!=null){
 
            System.out.println(line);
        }
        //关闭流 只需要关闭外层流(BufferedReader) 会自己关闭FileReader的
        bufferedReader.close();
    }

我们来看看为什么直接关闭外层流,其实他底层是关闭的是那个参数的close();

可以看出来这个in就是你使用的那个对象的节点流.

3.2.3 BufferedWriter

代码:

public static void main(String[] args) throws IOException {
 
        String filePath = "E:\\test\\a.txt";
        //创建一个BufferedWriter
        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filePath));
        bufferedWriter.write("哈哈哈写进文件1");
        bufferedWriter.newLine();         //插入一个和系统相关的换行符
        bufferedWriter.write("哈哈哈写进文件2");
        bufferedWriter.newLine();         //插入一个和系统相关的换行符
        bufferedWriter.write("哈哈哈写进文件3");
        //插入一个换行
        //关闭外层流即可
        bufferedWriter.close();
    }

newLine() 插入一个和系统相关的换行符,没有这个不会换行

如果我们要追加,不可以到bufferedWriter加true,因为不支持

但是我们可以到

这个后面加true

3.2.4BufferedReader 和 BufferedWriter 完成文本拷贝

public static void main(String[] args) throws IOException {
 
        String srcFilePath ="E:\\test\\j.txt";
        String descFilePath = "E:\\test\\T2\\j1.txt";

        String  ScrLine ;

        // 把源文件写到程序里面
        BufferedReader bufferedReader = new BufferedReader(new FileReader(srcFilePath));

        // 把程序的源文件写到硬盘中
        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(descFilePath));

        while((ScrLine  = bufferedReader.readLine())!= null){
 
                //读取一行就写进去  没有带换行符
                bufferedWriter .write(ScrLine);
                //换行
                bufferedWriter.newLine();
        }
        //关闭流
        bufferedReader.close();
        bufferedWriter.close();
    }

这里建议try finally 这样保证关闭资源,不过我这里就简单搞搞,知道大概意思就可以了。

3.3 处理流-BufferedInputStream 和 BufferedOutputStream

BufferedInputStream

看看BufferedInputStream 的类图:

来看看他们的属性参数:

父类的属性in 类型是一个inputStream 那么就是说只要是inputStream的子类节点流都可以操作。

BufferedOutputStream

BufferedOutputStream的类图

本类的buf是缓冲区 进行了优化,父类也有out 也是outPutStreamread 类型,子类的字节流操作都可以使用

3.3.4 使用BufferedInputStream 和 BufferedOutputStream拷贝文件

public static void main(String[] args) {
 
        String srcFilePath = "E:\\test\\QQ1.jpg";
        String DescFilePath = "E:\\test\\T2\\QQ2.jpg";

        //创建BufferedInputStream和BufferedInputStream对象
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;

        try {
 
            //为什么使用这个 因为我们要操作的不是一个文本,
            // 我们最好使用字节流来操作,无损,所以使用这个字节流,而且是InputStream的子类
            bis = new BufferedInputStream(new FileInputStream(srcFilePath));
            bos = new BufferedOutputStream(new FileOutputStream(DescFilePath));

            //循环读取文件 ,并写入到DescFilePath
            byte [] buf = new byte[1024];
            int readlen =0;
            //read() 没有文件返回-1
            while((readlen =  bis.read(buf))!= -1){
 
                bos.write(buf,0,readlen);  //写
            }
        } catch (IOException e) {
 
            e.printStackTrace();
        }
        finally {
 

            //关闭流
            if (bis!=null){
 
                try {
 
                    bis.close();
                } catch (IOException e) {
 
                    e.printStackTrace();
                }
            }

            if (bos!=null){
 
                try {
 
                    bos.close();
                } catch (IOException e) {
 
                    e.printStackTrace();
                }
            }
        }
    }

原文链接:https://blog.csdn.net/qq_46874327/article/details/124565152?utm_source=tuicool&utm_medium=referral

相关推荐

嵌入式C语言中常量的应用实例(嵌入式c语言中常量的应用实例是什么)

常量,我们都知道,就是数值保持不变的量。在C语言中,常量一旦初始化了,它的值将在整个程序运行周期内,不允许发生任何变化。常量与变量是相对的,我们实际项目中经常会用到它。定义常量的两种方式C语言中主要有...

C语言编程基础知识汇总学习,适合初学者!更新常量知识

(二)整型常量整型常量有3种形式:十进制整型常量、八进制整型常量和十六进制整型常量。(注意:c语言中没有直接表示二进制的整型常量,在c语言源程序中不会出现二进制。)书写方式如下:十进制整型常量:123...

【C语言】第二章第六节:字符串常量

第二章第六节:字符串常量。下表C语言中的常用转义字符。·字符形式功能:ASCIl码(十进制形式)。→\t水平制表(横向跳格:跳到下一个tab位置)。→\b退格8。→\r回车(不换行,光标移到本行行首)...

「GCTT 出品」Go 系列教程——5. 常量

这是我们Golang系列教程的第五篇。定义在Go语言中,术语”常量”用于表示固定的值。比如5、-89、IloveGo、67.89等等。看看下面的代码:varaint=50v...

每日C语言-常量指针、指针常量、指向常量的指针常量

一、常量指针1)什么是常量指针?通过该指针不可以修改其所指向存储单元中的值指针本身即地址可以被修改2)定义:类型说明符const*指针变量;类型说明符表示指针所指向存储单元中的值得数据类型指针...

C语言-符号常量、常变量、变量之我见

更新内容:新增音频。音频和文章一起更配oHello,大家好,又和大家见面了~~相信很多朋友们听了C语言的“符号常量”、“常变量”、“变量”后还是对这三者一脸懵逼吧。不管老师怎么歇斯底里地讲解,同学们迷...

零基础带你学习C语言:四:探索常量与变量

前言常量与变量学习;一:分析:short、float、long类型#include<stdio.h>intmain(){shortage=18;floatweight=12...

C语言中是如何定义常量的?那定义字符串呢?

常量有整型常量、浮点型常量、字符型常量及字符串常量。‘常量定义是指定义符号常量,用一个标识符来代表一个常量,通过宏定义预处理指令来实现。常量的定义:#definecount60这就定义了一个常量...

C语言符号常量的优点,会是那几点?

符号常量是一个常量,是不变量,所以,在编译的时候,就把符号常量出现的地方,替换为符号常量对应的常量。符号常量一般用户定义一个全局使用的数据,而且要改变该数据的时候,只需要改变符号常量的值,代码中引用符...

嵌入式开发- C语言数据类型-常量(c语言嵌入式是干嘛的)

基本数据类型的常量-掌握**整型常量:**常量是指在程序运行期间其数值不发生变化的数据。整型常量通常简称为整数整数可以是十进制数、八进制数、十六进制数八进制06334十六进制0xd1...

c语言解剖课:只读变量、常量、字面量傻傻分不清?

写在前面本篇主题的缘起,是因为一个计算机专业的大学生在和我讨论c语言问题时,说const常量如何如何,我说变量被const修饰了,还是变量,不是“常量”。他给了我一个截图:他说大模型都是这样回答的,变...

C/C++编程笔记:C数组、字符串常量和指针!三分钟弄懂它

想弄懂C语言中数组和指针的关系吗?这篇文章就占据你三分钟时间,看完你肯定会有收获!数组数组声明为数据类型名称[constant-size],并将一个数据类型的一个或多个实例分组到一个可寻址的位...

C语言入门到精通【第008讲】——C语言常量

C语言常量常量是固定值,在程序执行期间不会改变。这些固定的值,又叫做字面量。常量可以是任何的基本数据类型,比如整数常量、浮点常量、字符常量,或字符串字面值,也有枚举常量。常量就像是常规的变量,只不过常...

这是C语言无法修改得东西,C语言基础教程之常量解析

常量是指程序在执行期间不会改变的固定值。这些固定值也称为文字。常量可以是任何基本数据类型,如整数常量,浮点常量,字符常量或字符串文字,还有枚举常量。常量被视为常规变量,除了它们的值在定义后无法修改。整...

C语言中的单精度、双精度、常量等都有什么意思?

刚接触C语言时,对于常量,变量,浮点,单精度,双精度等问题的理解,大都很模糊不清,其实在程序运行过程中,其值不能改变的量称为常量。如12、0、-3为整型常量,4.6、-1.23为实型常量,'a'、'...

取消回复欢迎 发表评论: