当前位置: 首页 > news >正文

文件操作与IO—文件读写

上篇文章:

文件操作与IO—File类https://blog.csdn.net/sniper_fandc/article/details/146881359?fromshare=blogdetail&sharetype=blogdetail&sharerId=146881359&sharerefer=PC&sharesource=sniper_fandc&sharefrom=from_link

目录

1 数据流

2 InputStream和FileInputStream VS Reader和FileReader

2.1 InputStream

2.2 FileInputStream

2.3 代码实例

2.4 Reader与FileReader

2.5 Scanner

3 OutputStream和FileOutputStream VS Writer和FileWriter

3.1 OutputStream

3.2 代码示例

3.3 Writer和FileWriter

3.4 PrintWriter


1 数据流

        流(Stream)是一种数据的读写方式,读视为输入流,写视为输出流,批量读取数据时,这里的“批量”就是流,而java中数据的读写就是面向流的读写方式。

        Java中读写数据主要有两种方式:

        1.InputStream(读)和OutputStream(写)

        2.Reader(读)和Writer(写)

        其中方式1是以字节流为读写方式(以字节为单位的流),方式2是以字符流的为读写方式(以字符为单位的流)。因此方式1主要用来操作二进制文件,方式2主要用来操作文本文件。

2 InputStream和FileInputStream VS Reader和FileReader

2.1 InputStream

        InputStream是一个抽象类,内部包含如下方法:

返回值

方法

含义

int

read()

读一个字节,返回值0-255表示字节的值,返回值-1表示读到文件结尾

int

read(byte[] b)

最多读b.length字节(如果有的话),返回值实际读到的数量,返回值-1表示读到文件结尾,读到的数据填入字节数组

int

read(byte[] b, int off, int len)

从off下标开始,最多读len字节,最多读b.length字节(如果有的话),返回值实际读到的数量,返回值-1表示读到文件结尾,读到的数据填入字节数组

void

close()

关闭字节流,会抛异常IOException

        注意:打开一个文件,最后一定记得关闭。因为实际中的程序多是服务器程序,即程序持续运行,如果打开文件不关闭,内存中进程对应的文件描述符表对应的文件描述符会一直存在,从而导致文件描述符表最终爆满。及时不使用关闭文件,释放资源(内存+文件描述符表)。

2.2 FileInputStream

        FileInputStream是InputStream的一个具体实现类,用于打开一个输入流(在内存中,用于操作磁盘中的文件,作用类似于“句柄”(Handle))。

构造方法

含义

FileInputStream(File file)

利用File对象创建文件对应的输入流

FileInputStream(String name)

利用路径字符串创建文件对应的输入流

        使用FileInputStream会抛出异常FileNotFoundException,属于IOException的子类。

2.3 代码实例

public class ReadFile {

    public static void main(String[] args) throws IOException {

        InputStream inputStream = null;

        try{

            inputStream = new FileInputStream("newTest.txt");

            while(true){

                int b = inputStream.read();

                if(b == -1){

                    break;

                }

                System.out.println(b);

            }

        } catch (FileNotFoundException e) {

            e.printStackTrace();

        }finally {

            inputStream.close();

        }

    }

}

        这里把close()放到finally中,防止因为抛出异常导致关闭输入流的代码无法执行到。而newTest.txt文件内的内容是:hello,因此读入的字节是对应的ASCII值。

    public static void main(String[] args) throws IOException {

        InputStream inputStream = null;

        try{

            inputStream = new FileInputStream("newTest.txt");

            byte[] b = new byte[1024];

            int length = inputStream.read(b);

            System.out.println(length);

            for(int i = 0;i < length;i++){

                System.out.println(b[i]);

            }

        } catch (FileNotFoundException e) {

            e.printStackTrace();

        }finally {

            inputStream.close();

        }

}

        这是一次性尽可能读入1024字节长度的方式,这种方式IO次数更少,更推荐使用。

        如果把文件中的文本换成中文:你好,输出就变成了如下:

        这是因为在UTF-8字符编码的规则下,一个中文字符占3个字节,因此两个汉字有6个字节,如果按照3个字节组合,就可以还原成原来的汉字。   

 public static void main(String[] args) throws IOException {

        InputStream inputStream = null;

        try{

            inputStream = new FileInputStream("newTest.txt");

            byte[] b = new byte[1024];

            int length = inputStream.read(b);

            System.out.println(length);

            String s = new String(b,0,length,"utf-8");

            System.out.println(s);

        } catch (FileNotFoundException e) {

            e.printStackTrace();

        }finally {

            inputStream.close();

        }

}

        可以看到,InputStream只适合处理字节类型的文件,对于文本类型尤其是中文,操作就繁琐许多。

2.4 Reader与FileReader

        Reader和FileReader的关系和InputStream和FileInputStream类似,都是抽象类和具体实现类的关系,同时其中的方法也类似,只是参数类型变成了char[]。这组类可以解决字符类型文件的读取:

    public static void main(String[] args) throws IOException {

        Reader reader = null;

        try{

            reader = new FileReader("newTest.txt");

            char[] b = new char[1024];

            int length = reader.read(b);

            System.out.println(length);

            String s = new String(b,0,length);

            System.out.println(s);

        } catch (FileNotFoundException e) {

            e.printStackTrace();

        }finally {

            reader.close();

        }

}

2.5 Scanner

        Scanner类提供了更加强大的文本读取工具,也是推荐使用的文本类型文件的读取方式。

    public static void main(String[] args) throws IOException {

        InputStream inputStream = null;

        try{

            inputStream = new FileInputStream("newTest.txt");

            //接受来自键盘的输入

            //Scanner scanner = new Scanner(System.in);

            //接受来自输入流的输入

            Scanner scanner = new Scanner(inputStream);

            String s = scanner.next();

            System.out.println(s);

        } catch (FileNotFoundException e) {

            e.printStackTrace();

        }finally {

            inputStream.close();

        }

    }

3 OutputStream和FileOutputStream VS Writer和FileWriter

3.1 OutputStream

        OutputStream也是一个抽象类,内部包含如下方法:

返回值

方法

含义

void

write(int b)

一个字节,字节范围0-255表示字节的值

void

write(byte[] b)

将字符数组b中的数据全部写入文件

void

write(byte[] b, int off, int len)

在b中从off下标开始,len长度的字节

void

close()

关闭字节流,会抛异常IOException

void

flush()

将缓冲区的数据刷新到磁盘

        由于磁盘IO速度很慢,因此OutputStream 为了减少IO次数,在写数据的时候都会将数据先暂时写入内存的一个指定区域里(缓冲区),待数据写满了或者满足一定条件再写入磁盘。为了写入文件后续能及时读到写入的数据,就需要调用flush()强制刷新。

3.2 代码示例

public class WriteFile {

    public static void main(String[] args) {

        try(OutputStream outputStream = new FileOutputStream("newTest.txt");){

            outputStream.write(104);

            outputStream.write(101);

            outputStream.write(108);

            outputStream.write(108);

            outputStream.write(111);

            outputStream.write('h');

            outputStream.write('e');

            outputStream.write('l');

            outputStream.write('l');

            outputStream.write('o');

        } catch (IOException e) {

            e.printStackTrace();

        }

    }

}

        这里需要注意,写入字节和写入ascll字符是等效的,因此代码最终写入了两个hello。并且写入的方式是覆写(打开一次文件,所有写入的内容会覆盖原文内容。在同一次打开的文件中多次写,是续写)。

        代码中还用到了try with resources,含义详细见代码模版部分。

3.3 Writer和FileWriter

  public static void main(String[] args) {

        try(Writer writer = new FileWriter("newTest.txt");){

            writer.write("hello java");

        } catch (IOException e) {

            e.printStackTrace();

        }

}

        Writer类提供了多种writer方法,由于字符串可以和字符数组转化,因此writer方法可以接收字符串参数来进行写入(其他参数的方法和输入流类似)。

3.4 PrintWriter

    public static void main(String[] args) {

        try(OutputStream outputStream = new FileOutputStream("newTest.txt");){

            PrintWriter printWriter = new PrintWriter(outputStream);

            printWriter.println("hello world");

            printWriter.println("hello java");

            printWriter.flush();

        } catch (IOException e) {

            e.printStackTrace();

        }

}

        PrintWriter类对标读文件时的Scanner类,也提供了更丰富地写文件的方法,比如println(),这是换行写入的方法。需要注意:如果写入的内容在文件中不显示,一定要及时调用flush()方法,问题可能就出现在写入的数据还在缓冲区未及时刷新到文件中。

下篇文章:

相关文章:

  • 开源手机号码价值评估系统
  • AI Agent系列(八) -基于ReAct架构的前端开发助手(DeepSeek)
  • Spring笔记04-注解注入
  • Python每日一题(11)
  • oracle执行计划
  • 《异常检测——从经典算法到深度学习》30. 在线服务系统中重复故障的可操作和可解释的故障定位
  • 42. 接雨水
  • Flutter敏感词过滤实战:基于AC自动机的高效解决方案
  • 二分查找:原理、循环不变量与边界处理
  • 设置网站主题色color-scheme
  • 【Easylive】HttpServletRequest、HttpServletResponse、HttpSession 介绍
  • Leetcode hot 100刷题之路(day 1)
  • 黑盒测试的场景法(能对项目业务进行设计测试点)
  • ngx_monotonic_time
  • Git Fetch 和 Git Pull 的区别
  • 双层板模组天线设计指南,50欧姆阻抗匹配设计
  • B-tree 索引失效 避坑指南
  • x265不同preset级别控制的编码参数与编码性能影响
  • BFS(广度优先搜索)
  • 使用DeepSeek API进行情感分析:超简单
  • 澳门网站做推广违法吗/学网络运营需要多少钱
  • 免费ppt模板下载党建/北京网优化seo优化公司
  • 如何做自己的电影网站/云优化软件
  • 建设网站门户/百度官方平台
  • 网站开发单子/深圳公关公司
  • dedecms做网站怎么查看/广州竞价托管公司