文件---IO

文件IO实际就是针对文件内容进行操作,包括打开,读取/写入,关闭文件;I就是Input,O就是Output;

针对文件IO,就要说要“流”(stream)这个概念了;

说要流,我们就会想到水流,源源不断的水流,我们要接100ml的水,可以一次性接完,也可以两次接完,一次接50ml,还有很多种接法;

对于要读取100字节的数据,你可以选择一次性接100字节,也可以分两次,一次接50字节;这与接水非常相似,也可以叫文件流;

对于文件内容的操作,我们通常有两种方法:字节流字符流

字节流

就是以字节为单位从文件读取/写入数据到文件,一般用于二进制文件;

当要从文件读取数据时,使用InputStream抽象类,针对文件,有专门的类FileInputStream实现;

FileInputStream的构造方法

方法签名说明
FileInputStream(String filePath)用文件的路径作为参数
FileInputStream(File file)用文件对象作为参数

通过以上两种构造方法打开文件,以便读取文件数据;

读取文件数据的三种主要方法

第一种  read()

读取数据的方法是每一次读取一个字节的数据,读到数据返回0-255,读到文件末尾返回-1;

看到这里你是否会有一个疑问,为什么要用int接收,而不是byte?

  • 第一:为的是有足够的空间返回-1;
  • 第二:确保读到的数都是正整数,实际上byte作为有符号整数的取值范围是-128-+127,但是作为字节,本身应该是无符号的,以确保取值范围可以是0-255,而用int接收,就是确保读到的都是正整数
  • 第三:为什么不用short,而使用int呢?
  • 建议大家忘记short,直接用int;就像用到float的时候,我们都会直接使用double,以提高精度;
第二种 read(byte[] )

读取的数据方式,就是要传入一个byte数组,文件数据都会尽量填满这个数组,填不满就意味着读到文件末尾了,返回读到的字节个数,返回-1就表示读到文件末尾了;

第三种 read(byte[] b,int off, int len)

方式就是第二种方式的改变,从off下标开始填入数据,读取len个字节,返回读到的字节个数,返回-1就表示读到文件末尾了;

最常用的是第二种方法,快捷方便,比较符合符合实际情况;每次读取一个字节是一个数组的开销是一样的,但是后者可以更快;

代码演示(文本内容是hello)

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class demo1 {
    public static void main(String[] args) throws IOException {
        InputStream inputStream=new FileInputStream("D:/test.txt");
        byte[] read=new byte[1024];
        while(true){
            int len=inputStream.read(read);
            System.out.println(len);
            if(len==-1){
                break;
            }
            for (int i = 0; i < len; i++) {
                System.out.printf("0x%x ",read[i]);//十六进制
            }
            System.out.println();
        }
    }
}

写入数据到文件(字节流)

依旧是用FileOutputStream打开文件,实现OutputStream抽象类;

FileOutputStream的构造方法

方法签名说明
FileOutputStream(String filePath,boolean append)用文件的路径作为参数,appned表示追加,true表示写入数据追加到文件末尾,false表示清除文件原有内容,进行覆盖写入
FileOutputStream(File file,boolean append)用文件对象作为参数,appned表示追加,true表示写入数据追加到文件末尾,false表示清除文件原有内容,进行覆盖写入

写入方法

相信只要看到参数,大概就能懂了,唯一需要注意就是第二种传入整数范围应该是0-255;对应ASCII码表;

代码演示

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

public class demo2 {
    public static void main(String[] args) throws IOException {
        OutputStream outputStream=new FileOutputStream("D:/test.txt",true);
        for (int i = 0; i < 3; i++) {
            outputStream.write(97);
            outputStream.write(98);
            outputStream.write(99);
            outputStream.write(100);
        }
    }
}

字符流

以字符为单位读取文件数,写入数据到文件;

分别用到的是Reader读取Writer写入抽象类,对于文件有FileReaderFileWriter的具体类实现数据读取和写入;

打开文件的构造方法与上面字节流的构造方法的雷同

区别就是写入和读取的方法签名不一样;

读取文件的方法签名

read(charBuffer target)    ----->read(char[] target)

方法与字节流的方法相同,多了第三种方法,这个方法其实就是标准库把这个字符数组进行了一个封装,实际还是char[];

写入文件的方法签名

写入数据的方法虽然多了几种,但是也只是数据类型不一样;

值得注意的是,以字符流写入数据到文件的时候,需要用到两个方法,flush()和close(),不然会无法写入数据?

  • FileWriter内置了一个缓冲区,会将要写入的数据先放置在缓冲区,如果不主动关闭文件流,就会使得jvm结束的时候把文件流强制关闭了,数据也就自然无法正常写入 ;
  • 使用flush(),会将缓冲区的数据全部写入文件,文件流还能继续使用;
  • 使用close(),回先将缓冲区的数据全部写入文件,然后关闭文件流,释放文件资源;

关闭文件

上面一直在讲述如何打开文件,读写文件,却一直没有说如何关闭文件,及时关闭文件流,释放资源是非常重要的

关闭文件流的重要性

系统内核有一个文件描述表,专门用来存放打开的文件的相关信息的  ,主要是因为这个文件描述符表是有限制大小的,就意味着不能一直只是打开文件不释放文件,虽然程序结束,文件流会主动关闭,但是如果在大型的程序当中,没有及时关闭文件流,就会使得文件描述表被占满,以至于后续要打开文件都会失败,所以不及时不关闭文件流就是一个会随时爆炸的炸弹;

关闭文件的三种方法(有待补充)
第一种

最直接的方法,在使用完文件之后就调用close()关闭文件流。但是这也存在一定的弊端,如果在关闭之前,代码出现错误,救会使得close()方法无法被执行,导致文件无法关闭;

第二种

使用try--catch--finally格式,将close()放在finally中,这样就可以保证即使代码出现死循环也能够确保close()被执行到;

第三种

使用try with resource,代码如下

       try(Reader reader=new FileReader("D:/test.txt")){
            while(true){
                int c=reader.read();
                if(c==-1){
                    break;
                }
                char ch=(char)c;
                System.out.println(ch);
            }
        }catch (IOException e){
            e.printStackTrace();
       }

将打开文件放在try后面,这个打开文件的方法,会附带主动关闭文件流; 如果使用第二种,你会发现代码有点长,第三种方法就是在第二种方法进行简化代码,同时也保证了不会忘记调用close();

  • 26
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

a添砖Java

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值