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

003-存储读取数据的方案

存储&读取数据的方案

File简介

  • File是java.io.包下的类,File类的对象,用于代表当前操作系统的文件(可以是文件或文件夹
  • 注意:File类只能对文件本身进行操作,不能读写文件里面存储的数据。

IO流简介

  • 用于读写数据的(可以读写文件或网络中的数据...)

File

  • File类的对象可以代表文件/文件夹,并可以调用其提供的方法对象文件进行操作

  • 创建File类的对象

    image-20250728172617150

  • 注意:

    • File对象既可以代表文件,也可以代表文件夹。

    • File封装的对象仅仅是一个路径名,这个路径可以是存在的,也允许是不存在的

    • 相对路径是不带盘符的,默认是到IDEA工程(必须确保是工程)下直接寻找文件的。一般用来找工程下的项目文件的项目文件

      image-20250728173324161

  • File类创建文件的功能

    image-20250728173653721

  • File类删除文件的功能

    image-20250728173713352

    • 注意:delete方法默认只能删除文件和空文件夹,删除后的文件不会进入回收站
  • File类提供的遍历文件夹的功能

    image-20250728174210955

    • 使用listFile方法时的注意事项:
      • 当主调是文件或者路径不存在时,返回null
      • 当主调是空文件夹时,返回一个长度为0的数组
      • 当主调十一个有内容的文件夹时,将里面所有一级文件和文件夹的路径放在File数组中返回
      • 当主调是一个文件夹,且里面有隐藏文件时,将里面所有文件和文件夹的路径放在File数组中返回,包含隐藏文件
      • 当主调是一个文件夹,但是没有权限访问该文件夹时,返回null
  • 获取文件对象的绝对路径

    image-20250728174510752

递归

  • 递归是一种算法,在程序设计语言中广泛应用

  • 从形式上说,方法调用自身的形式称呼为方法递归(recursion)

  • 递归可能出现死循环,导致、栈内存溢出

文件搜索

  • 示例

    image-20250729174904803

    image-20250729174954294

字符集

标准ASCII字符集

  • ASCII:美国信息交换标准代码,包括了英文、符号等
  • 标准ASCII使用1个字节存储一个字符,首位是0,因此,总共可表示128个字符,对美国来说完全够用

GBK(汉字内码扩展规范,国标)

  • 汉字编码字符集,包含了2万多个汉字等字符,GBK中一个中文字符编码成两个字节的形式存储
  • 注意:GBK兼容了ASCII字符集。
    • GBK规定:汉字的第一个字节的第一位必须是1。所以读到1就读两个字节表示汉字,读到0就读一个字节的ASCII码

Unicode字符集(统一码,也叫万国码)

  • Unicode是国际组织制定的,可以容纳世界上所有文字、符号的字符集

    • UTF-32:四个字节表示一个字符

      • 缺点:奢侈,占存储空间大,通信效率变低
    • UTF-8

      • 是Unicode字符集的一种编码方案,采取可变长编码方案,分四个长度区:1个字节,2个字节,3个字节,4个字节

      • 英文字符、数字等只占1个字符(兼容ASCII编码),汉字字符占用3个字节。

        image-20250730174325531

  • 注意:程序员在开发中应该使用UTF-8!

使用程序对字符进行编码和解码操作

  • 对字符编码

    image-20250730175228732

  • 对字符解码

    image-20250730175248554

  • 编码器和解码器不同时会乱码,但英文和数字一般不会乱码,因为都兼容ASCII

IO流

  • IO流的分类

    image-20250730180114358

  • IO流的体系

    image-20250730180214429

    image-20250730180255804

    image-20250730180446656

字节流

FileInputStream(文件字节输入流)

  • 作用:以内存为基准,可以把磁盘文件中的数据以字节的形式读入到内存中去

    image-20250730180706072

  • 示例:

    • 每次读一个字节

      image-20250730181433284

    • 每次读多个字节

      image-20250730182058687

  • 结论:

    • 使用FileInputStream每次读取一个字节,读取性能较差,并且读取汉字输出会乱码

    • 使用FileInputStream每次读取多个字节,读取性能得到了提升,但读取汉字输出还是会乱码

    • 使用字节流读取中文,如何保证输出不乱吗,如何解决?

      • 定义一个与文件一样大的字节数组,一次性读取完全部字节文件

      • 官方为FileInputStream提供了如下方法,可以直接把文件的全部字节读取到一个字节数组返回

        image-20250730182446268

      • 示例

        image-20250730182837593

    • 直接把文件数据全部读取到一个字节数组可以避免乱码,是否存在问题?

      • 如果文件过大,创建的字节数组也会过大,可能引起内存溢出

FileOutputStream(文件字节输出流)

  • 作用:以内存为基准,把内存中的数据以字节的形式写出到文件中去

    image-20250730183114430

  • 字节输出流写数据的方法

    image-20250730183830989

    • len这个参数的单位是字节,中文在utf8中是3个字节
  • 字节输出流如何实现写出去的数据可以换行?

    os.write("\r\n".getBytes());
    // \r是为了在win之外的系统也可以换行,两个写一起兼容性更好
    
  • 用完管道要用.close()把管道关掉

  • 示例

    image-20250730184044034

文件复制

  • 示例

    image-20250730184956989

  • 字节流非常适合做文件的复制操作

    • 任何文件的底层都是字节,,字节流做复制时一字不漏的转移完全部字节,指导赋值后的文件格式一致就没问题
  • 注意:复制的目标文件必须写名字,因为该操作无法自动生成一个文件

资源释放的方案

  • try-catch-finally

    image-20250730185324623

    • finally代码区的特点:无论try中的程序是正常执行了还是出现了异常,最后都一定会执行finally区,除非JVM终止

    • 作用:一般用于在程序执行完后新型资源的释放操作(专业级做法)

    • ctrl+alt+t可以创建try-catch-finally

    • 在try中定义管道变量的话,在finally块中检测不到这个变量,但在try之前创建又会异常报错,所以应该在外面创建空变量,在try中new出来

    • finally中程序会担心是否变量已经被释放了从而再次异常报错,这时候就需要在finally中再try、catch异常

      image-20250730190009314

    • 这种方法使用起来代码十分臃肿

  • try-with-resource

    • jdk7开始,为了解决try-catch-finally中,finally解决方法代码臃肿,且finally中时常有其他结束操作的问题。

    • 提供了更简单的资源释放方案try-with-resource

      image-20250730190310904

    • 在try后括号中定义资源,该资源使用完毕后,会自动调用其close()方法,完成对资源的释放

    • 示例

      image-20250730190511914

    • 注意:try后的括号里只能放资源对象,不能定义一个变量

      • 什么是资源?

        • 资源一般指的是最终实现了AutoCloseable接口

          image-20250730190648620

字符流

FileReader文件字符输入流

  • 作用:以内存为基准,可以把文件中的数据以字符的形式读入到内存中去

    image-20250801010933638

  • 示例

    image-20250801011546866

FileWriter文件字符输出流

  • 作用:以内存为基准,把内存中的数据以字符的形式写出到文件中去

    image-20250801011903844

  • 字符输出流的注意事项

    • 字符输出流写出数据后,必须刷新流,或者关闭流,写出去的数据才能生效

      image-20250801012651164

    • 为什么要刷新?

      • 不刷新的话IO调用次数过多,所以就先把内存缓冲区写完之后再同步一次IO,这样IO次数就变少了
    • 如果不刷新缓冲区,直接结束程序,那数据可能不会存到文件中

    • 刷新后,流可以继续使用

    • 关闭方法包含刷新,但关闭后就无法继续使用

    • 利用jdk7的特性,在try后的括号中new出的流会在try结束后自动调用关闭方法,所以使用这个特性后就不需要主动的关闭流!!!

缓冲流

image-20250801013622053

  • 缓冲流是改进了普通流,提高了普通流的性能

BufferedInputStream/BufferedOutputStream缓冲字节输入/输出流

  • 缓冲字节输入/输出流默认有8kB的缓冲池,减少了传输次数

    image-20250801014010099

BufferedReader缓冲字符输入流

  • 作用:自带8K(8192个)的字符缓冲池,可以提高字符输入流读取字符数据的性能

    image-20250801014600278

  • 字符缓冲输入流新增的功能:按照行读取字符

    image-20250801014643003

    • 这里想用readLine方法的话就不用多态写法了,因为这是BufferedReader独有的
  • 示例:

    image-20250801015216828

BufferedWriter缓冲字符输出流

  • 作用:自带8K的字符缓冲池,可以提高字符输出流写字符数据的性能

    image-20250801015327888

  • 字符缓冲输出流新增的功能:换行

    image-20250801015355360

性能分析

原始流、缓冲流的性能分析

  • 背景:使用四种流复制一个大文件
    • 低级字节流:按照一个一个字节的形式复制文件
      • 非常慢,简直让人无法忍受,直接淘汰,禁止使用
    • 低级字节流:按照字节数组的形式复制文件
      • 是比较慢的,但还可以接收
    • 高级的缓冲字节流:按照一个一个字节的形式复制文件
      • 虽然是高级管道,但一个一个字节的复制还是太慢了,无法忍受,直接淘汰
    • 高级的缓冲字节流:按照字节数组的形式复制文件
      • 非常快,推荐使用
  • 低级管道只要把桶加大(例如把字符数组加大),性能也能变得好,所以低级流不一定就比高级流性能差

其他流

InputStreamReader字符输入转换流

image-20250802170156460

  • 解决不同编码时,字符流读取文本内容乱码问题
  • 解决思路:先获取文件的原始字节流,再将其按真实的字符集编码转成字符输入流,这样字符输入流中的字符就不乱码了

image-20250802170813045

  • 背景:不同编码读取乱码问题
    • 例如UTF-8的代码编码,读取GBK文件时出现乱码
    • 示例

打印流

image-20250802171122565

PrintStream/PrintWriter(打印流)

  • 作用:打印流可以实现更方便、更高效的打印数据出去,能实现打印啥出去就是啥出去(比如97就会打印出97,而不会转为char中的'a')

    image-20250802171342587

特殊数据流

image-20250802171655351

DataOutputStream(数据输出流)

  • 允许把数据和其类型一并写出去

    image-20250802171841895

  • 写进去很多时候看起来是乱码,但这个一般不是给人看的,而是给别人读取用的

DataInputStream(数据输入流)

  • 用于读取数据输出流写出去的数据

    image-20250802172226329

  • 读取的时候要和写入时的类型顺序一致,怎么发就怎么收

IO框架

  • 什么是框架?

    • 框架(Framework)是一个预先写好的代码库或一组工具,旨在简化和加速开发过程
    • 框架的形式:一般把类、接口等编译成class形式,再压缩成一个.jar结尾的文件发行出去
  • 什么是IO框架?

    • 分装了Java提供的对文件、数据进行操作的代码,对外提供了更简单的方式来对文件进行操作、对数据进行读写等
  • 步骤:

    image-20250802172717245

  • Commons-io框架

    • 是apache开源基金组织提供的一组有关IO操作的小框架,目的是提高IO流的开发效率

      image-20250802173056313

      image-20250802173157177

    • 示例

      image-20250802173429018

      下面一行是java提供的

    • 删除操作不考虑是否非空,调用会直接删除,谨慎使用!

http://www.sczhlp.com/news/6835/

相关文章:

  • 004-多线程
  • 安科瑞分布式光伏监控系统:筑牢10kV光伏电站的智能监测防线 - 实践
  • 什么是供应链 - 智慧园区
  • 泛微e8获取当前操作者并与明细行的项目负责人对比,不同就隐藏明细行
  • 25.8.5python模块
  • 在K8S中,同⼀个Pod的不同容器互相可以访问是怎么做到的?
  • 基于图像识别与分类的中国蛇类识别系统 - 教程
  • 对于项目调用方法的解析
  • 在K8S中,不同的Pod之间互相可以访问是怎么做到的?
  • 在K8S中,如果容器没有bash命令,如何进入容器排查问题?
  • 在K8S中,如果是因为开发写的镜像问题导致pod起不来该怎么排查?
  • 在K8S中,在服务上线的时候Pod起不来怎么进行排查?
  • 在K8S中,cronjob的使用场景?
  • 在K8S中,Deployment支持扩容吗?它与HPA有什么区别?
  • [浅谈数学]浅谈博弈论
  • mysql 定位慢sql - xiao-jie
  • 在K8S中,K8S⼆进制和kubeadm安装的方式有什么区别?
  • 在运维工作中,k8s中service和ingress的有什么区别?
  • 8.4 NOIP 模拟赛
  • panic、defer、recover
  • 使用JDK 自带jstack工具排查问题 - xiao-jie
  • 嵌入式软件架构漫谈
  • 数据服务_数据服务项目开发总结
  • 数据集_具身智能数据集了解
  • 深入解析:各种信号分解、模态分解方法合集【MATLAB实现】
  • 小样本学习在语言理解任务中的突破
  • 枚举-熄灯问题
  • 乞丐哥的私房菜(Windows OpenCV篇——Image Processing 节 之 Adding borders to your images 给你的图像加上边框)十二 - 指南
  • GIST 复发风险预测升级!影像 + 病理 + 临床多模态模型来了,精准度再突破
  • 应聘记录