首页 > 编程语言 >毕设学习第四天之Java的IO流

毕设学习第四天之Java的IO流

时间:2025-01-12 22:13:23浏览次数:1  
标签:文件 file 毕设 Java 字节 字符 IO File new

 

File类

File 对象 = new File(路径名)

 

两个静态变量

pathSeparatorChar 提供系统级的路径分隔符字符。

pathSeparator 将其表示为字符串

前者文件分隔符unix下为 :,windows下为 ;,而后者无论哪个分隔符均为 /

 

 四大构造方法

File(String pathname)
通过给定的路径名字符串创建 File 实例。如果路径名是空字符串,生成一个空的路径对象。

File(String parent, String child)
通过父路径名和子路径名创建 File 实例。如果父路径名为 null,则只使用子路径名;否则,父路径表示目录,子路径表示文件或目录。若子路径是绝对路径,则会相对父路径进行解析。

File(File parent, String child)
通过父路径对象和子路径名创建 File 实例。如果父路径对象为 null,则只使用子路径名;否则,父路径表示目录,子路径表示文件或目录。若子路径是绝对路径,也会相对父路径解析。

File(URI uri)
通过给定的 file:// 格式的 URI 创建 File 实例。该 URI 格式根据操作系统不同而不同,转换规则也会有所不同。

常见方法

getAbsolutePath()

获取文件绝对路径

getPath()

获取文件封装路径,由初始化路径决定

getName()

获取文件名

length()

文件长度,即字节数目

createNewFile()

创建新文件

mkdir()

创建新目录

delete()

删除指定路径的文件

isDirectory()

判断是否为文件夹

isFile()

判断是否为文件

exists()

判断文件是否存在

list()

返回一个String数组,为对应文件夹下的文件的名称列表

listFiles()

返回对应文件夹下的File 数组

 

idea的相对路径为project的绝对路径开始的

 

IO流技术:一个设备的数据传输到另一个设备,常用于将内存中需要长久保存的数据输入输出到外存

字节流

所有的数据都可以转换为字节信息,是数据的基础,一切皆字节

两大抽象类

字节输出流:OutputStream

字节输入流:InputStream

字符流

专门操作文本文档

两大抽象类

字符输出流:Writer

字符输入流:Reader

字节和字符的关系,一个字符由于编码方式的不同会占不同个数的字节,这就要求我们在按字符读取时要提前了解文件的编码方式是UTF-8还是GBK等,如果编码不一致会产生乱码现象,而字节流是万能的,不受编码方式的影响,因此对于打印使用字符流,对于文件的复制使用字节流

 

文件的字节输入输出流

FileOutputStream:通过write方法输出字节到外设,有覆盖写和续写两种模式,不同操作系统的换行符不同,windows为\r\n,liunx为\n,mac为\r

FileInputStream:通过read方法输入字节到内存,返回的为对应字符的ASCII码值,末尾固定-1作为结束标志,-1~255其中-1为结束标记

package org.example;


import java.io.*;

public class Main {
    public static void main(String[] args) throws IOException {
        // 文件夹和文件都为一个文件对象,因此需要两个文件对象分别对文件夹,文件进行操作
        // 文件夹对象
        File file=new File("src/main/resources/data");
        file.deleteOnExit();
        file.mkdir();
        file.deleteOnExit();
        // 文件对象
        file=new File("src/main/resources/data/data.txt");
        file.createNewFile();
        file.delete();
        // 开启追加写而非覆盖
        OutputStream out = new FileOutputStream(file,true);
        // write有三个重载,空参,一个字节数组,一个字节数组并切出其中的一部分传入
        out.write("A\r\nB\r\nC\r\nD\r\n".getBytes());
        out.write("a\r\nb\r\nc\r\nd\r\n".getBytes());
        out.close();
        InputStream in = new FileInputStream(file);
        int readByte;
        // read有三个重载,空参,一个字节数组,一个字节数组并切出其中的一部分传入
        while ((readByte=in.read()) != -1) {
            // 将对应的ASCII码值转为对应的字符
            System.out.println(readByte+" ==> "+(char)readByte);
        }
        in.close();
    }
}

有个小细节要注意就是在一次读取一个字节数组时,是通过循环覆盖的方式,例如字节的数组长度为2,而文件中的字符分别为ABCD,一个字符占一个字节,一开始读入AB,然后在读取C时会覆盖A,即数组变成CB,读完C再读D就是CD了

文件的字符输入输出流

FileWriter:通过write方法输出字符到外设,有覆盖写和续写两种模式,可以传入字节数组和String字符串

FileReader:通过read方法输入字符到内存,返回的为对应字符的ASCII码值

字节和字符输出到外设有一个小细节,字节输出是直达的,写入一个字节文件就更新一个字节,而字符不一样,字符不会直接写入到文件当中,而是写入到内存的一个字符缓冲区中,因为字符往往占多个字节,如果逐个字符写入文件的话效率很低,需要等待上个字符写完才能进行下一个操作,因此我们使用字符缓冲区进行写入操作,而缓冲区进入文件中的操作为flush或者close,close的操作是先刷新再关闭,jdk8中通过trycatch可以实现自动关流

package org.example;


import java.io.*;

public class Main {
    public static void main(String[] args) throws IOException {
        File file=new File("src/main/resources/data/data.txt");
        FileReader fr = new FileReader(file);
        FileWriter fw = new FileWriter(file,true);
        fw.write("你好\n\r我是字符输入输出流\n\r");
        int readChar;
        while ((readChar = fr.read()) != -1) {
            System.out.println(readChar+" => "+(char) readChar);
        }
        fr.close();
        // 刷新缓冲区到文件
        fw.flush();
        fr = new FileReader(file);
        while ((readChar = fr.read()) != -1) {
            System.out.println(readChar+" => "+(char) readChar);
        }
        fw.close();
        fr.close();

    }

}

 

缓冲:作为内存和外存的媒介,由于cpu 和内存交互快,而和外存交互满,因此有了缓冲区这个概念,外存直接和缓冲交互要比直接和内存交互快,我们操作一部分文件然后再将对应的文件放入缓冲区

字节缓冲流

之前所写的Fi1eOutputstream,Fi1eInputstream,FileReader,Filewriter这都叫做基本类,其中Fi1eInputstream和Fi1eoutputstream的读写方法都是本地方法(方法声明上带native),本地方法是和系统以及硬盘打交道的,也就是说这两个对象的读和写都是在硬盘之问进行读写的,效率不高;缓冲流中底层带一个长度为8192的数组(缓冲区),此时读和写都是在内存中完成的(在缓冲区之间完成),内存中的读写效率非常高

字节缓冲流的缓冲区为一个字节数组,默认大小为8192,字节缓冲流基于基本流

字节缓冲输出流:BufferedOutputStream

字节缓冲输入流:BufferedInputStream

package org.example;


import java.io.*;

public class Main {
    public static void main(String[] args) throws IOException {
        File file=new File("src/main/resources/data/data.txt");
        InputStream in = new FileInputStream(file);
        InputStream fis = new BufferedInputStream(new FileInputStream(file));
        long start=System.currentTimeMillis();
        int readByte;
        while ((readByte = in.read()) != -1) {
            System.out.println(readByte+" => "+(char) readByte);
        }
        in.close();
        long end=System.currentTimeMillis();
        System.out.println(end-start);
        start=System.currentTimeMillis();
        while ((readByte = fis.read()) != -1) {
            System.out.println(readByte+" => "+(char) readByte);
        }
        fis.close();
        end=System.currentTimeMillis();
        System.out.println(end-start);
    }

}

文件之前的交互转换为对应文件在内存中缓冲流的交互,文件通过基本流写入写出缓冲流,然后如果要进行文件之前数据的交互只需要在内存中进行两个文件之间缓冲流数据的交互,最好将缓冲流数据通过基本流刷新到文件内,避免了文件直接的慢速交互,内存要比硬盘快的多

字符缓冲流

字符缓冲输出流:BufferedWriter

字符缓冲输入流:BufferedReader

package org.example;


import java.io.*;

public class Main {
    public static void main(String[] args) throws IOException {
        File file=new File("src/main/resources/data/data.txt");
        BufferedReader br=new BufferedReader(new FileReader(file));
        // 逐行读取
        String line=br.readLine();
        while(line!=null){
            System.out.println(line);
            line=br.readLine();
        }
        br.close();
    }

}

 

转换流

InputStreamReader:传入一个输入基本流和编码方式,字节流向字符的桥梁,即字节转换为字符,根据对应的编码方式

OutputStreamWriter:传入一个输出基本流和编码方式,字符流向字节的桥梁,即字符转换为字节,根据对应的编码方式

转换流:将字节和字符根据自定义的编码方式进行转换

 

序列化流和反序列化流

序列化和反序列化:主要作用就是存储对象,序列化是写对象,反序列化的是读对象

ObjectInputStream:反序列化,将对象读入到内存

ObjectOutputStream:序列化,将对象写入到外存

对于要存储的对象要实现一个Serializable接口,将对象转换为二进制数据在网络上传输,transient修饰的变量成员可以避免序列化

package org.example;


import java.io.*;

class Student implements Serializable{
    String name;
    int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public Student() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

public class Main {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        File file=new File("src/main/resources/data/data.txt");
        ObjectOutputStream out=new ObjectOutputStream(new FileOutputStream(file));
        out.writeObject(new Student("李华",10));
        out.close();
        ObjectInputStream in=new ObjectInputStream(new FileInputStream(file));
        System.out.println(in.readObject());
        in.close();
    }

}

 序列化的注意事项

序列化的实例在编译为class文件中会自动生成一个序列号,该序列号会随实例一起存储到文件中,反序列化是通过编译的class文件中的序列号和外存文件的序列号进行匹配来进行的,如果我们修改源码重新编译的话会生成一个新的序列号,导致二者的序列号匹配失败导致反序列化失败

 

打印流

PrintStream:将文件中的内容打印输出

println():打印并自带换行效果

setout():改变流向,可以将打印输出到控制台转向打印输出到日志文件中

 

Properties集合

Properties 类是 Java 中用于处理配置文件的一个集合类,它继承自 Hashtable,并专门用于存储和操作键值对数据。它通常用于应用程序的配置管理,允许将配置数据存储在 .properties 文件中,并能够轻松地从这些文件加载或保存配置。

主要特点:

  1. 键值对存储Properties 类存储的是键值对,其中键和值都是字符串类型。每个键对应一个值,这些键值对可以表示配置数据,如用户名、密码、数据库连接信息等。

  2. 加载与存储配置Properties 类提供了方便的方法来从文件加载配置数据,或者将配置数据写入文件。它通常用于 .properties 文件,该文件是纯文本格式,包含以 =: 分隔的键值对。

  3. 默认属性支持Properties 类支持默认属性。可以通过构造方法指定一个默认的 Properties 对象,这样当查找某个键时,如果找不到,会返回默认值。

  4. 自动处理流Properties 类的 loadstore 方法自动处理文件输入输出流,因此它非常适合用于读取和保存配置文件。

常用操作:

  • 读取配置:使用 getProperty() 方法可以从 Properties 对象中读取指定键的值。若该键不存在,可以返回一个默认值。

  • 写入配置:使用 setProperty() 方法可以设置或更新键值对数据,使用 store() 方法可以将当前的属性保存到文件中。

  • 获取所有属性:可以使用 stringPropertyNames() 获取当前 Properties 对象中的所有键名,并遍历这些键名来访问所有配置项。

应用场景:

  • 配置管理Properties 最常用于存储和读取应用程序的配置文件,例如数据库连接信息、用户设置、语言选择等。

  • 国际化支持:通过不同的 .properties 文件实现多语言支持,例如不同的语言文件可以存储不同的字符串,然后根据用户的语言设置加载合适的文件。

  • 简单的存储和读取:适用于需要存储简单的键值对数据并且对性能要求不高的场景。

 

标签:文件,file,毕设,Java,字节,字符,IO,File,new
From: https://www.cnblogs.com/liyiyang/p/18664969

相关文章

  • javaScript介绍
    JavaScript概述JavaScript是世界上最流行的脚本语言Java和JavaScript没有真正上的联系历史https://blog.51cto.com/u_39037/10505185ECMAScript它可以理解为是javaScript的一个标准快速入门引入JavaScript1.内部标签<script>//....</script>2.外部引用a......
  • 从入门到精通:Java 基础语法全解析,快速掌握核心编程技能
    系列文章目录01-从入门到精通:Java基础语法全解析,快速掌握核心编程技能文章目录系列文章目录前言一、Java的基本语法规则1.1Java程序结构1.1.1代码解析1.1.2Java的基本语法规则1.2Java的代码风格和规范二、变量与数据类型2.1变量的定义与使用2.1.1变量的声......
  • 实现无感刷新Token技术:.Net Web API与axios的完美结合
    备忘:https://mp.weixin.qq.com/s?__biz=MjM5MDE5MDM5NA==&mid=2449944319&idx=1&sn=71e84d8ee24769e77b19ca8367333b8f&chksm=b1bb10aa86cc99bc2f20686354e8184023278de74dba857a42d720dc47fabb654c12ecb83524&scene=21#wechat_redirect我们都知道Token是有设置有效期......
  • springboot毕设 花店管理系统 程序+论文
    本系统(程序+源码)带文档lw万字以上文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景随着生活品质的提升,鲜花作为传递情感与美化生活的媒介,其市场需求日益增长。传统花店在运营过程中面临着诸多挑战,如库存管理复杂、客户信息管理混乱、......
  • springboot毕设 汉中市旅游综合服务平台 程序+论文
    本系统(程序+源码)带文档lw万字以上文末可获取一份本项目的java源码和数据库参考。系统程序文件列表开题报告内容研究背景汉中市,作为中国历史文化名城,拥有丰富的自然景观和深厚的文化底蕴,吸引了众多国内外游客前来观光旅游。然而,随着旅游业的快速发展,传统的旅游服务方式已......
  • 2025 年 1 月 TIOBE 指数,一月头条:Python 是 TIOBE 2024 年度编程语言!
    2025年1月TIOBE指数一月头条:Python是TIOBE2024年度编程语言!编程语言Python赢得了“TIOBE2024年度编程语言”称号。该奖项授予一年内评级增幅最高的编程语言。Python在2024年增长了9.3%。这远远领先于其竞争对手:Java+2.3%、JavaScript+1.4%和Go+1.2%。......
  • 方法引用与lambda底层原理&Java方法引用、lambda能被序列化么?
    系列文章目录和关于我0.引入最近笔者使用flink实现一些实时数据清洗(从kafka清洗数据写入到clickhouse)的功能,在编写flink作业后进行上传,发现运行的时候抛出:java.io.NotSerializableException,错误消息可能类似于“org.apache.flink.streaming.api.functions.MapFunctionimplemen......
  • 音视频:JavaCV 两种摄像头视频数据采集的方法
    需要进行简单的音视频编程,如果不是特别熟悉C/C++,那么JavaCV应该是比较好的选择,下面记录一下使用JavaCV采集摄像头的两种方法。1.OpenCV使用OpenCVFrameGrabber采集指定摄像头(索引)的视频数据:publicclassSample01_Camera{ publicstaticvoidmain(String[]args)throwsEx......
  • 音视频:JavaCV 采集桌面画面并显示的方法
    需要进行简单的音视频编程,如果不是特别熟悉C/C++,那么JavaCV应该是比较好的选择,下面记录一下使用JavaCV采集桌面数据的方法。使用FFmpegFrameGrabber采集桌面数据,指定输入源为desktop,format设置为gdigrab。参考雷神的博客:https://blog.csdn.net/leixiaohua1020/article/details/......
  • JAVA开源免费项目 基于Vue和SpringBoot的物资管理系统(附源码)
    本文项目编号T112,文末自助获取源码\color{red}{T112,文末自助获取源码}......