首页 > 其他分享 >2023年7月25日,File类,IO流

2023年7月25日,File类,IO流

时间:2023-07-25 19:04:22浏览次数:35  
标签:字符 File 25 IO String io new 字节

File类

1. 概述

File,是文件和目录路径的抽象表示 File只关注文件本身的信息,而不能操作文件里的内容 。如果需要读取或写入文件内容,必须使用IO流来完成。

在Java中,java.io.File 类用于表示文件或目录的抽象路径名。它提供了一组方法,可以用于创建、访问、重命名、删除文件或目录,以及获取文件或目录的属性等操作。

2. File类的使用

  1. 创建文件对象:
File file = new File("d:/to/file.txt");  // 使用文件路径创建文件对象
  1. 创建目录:
File dir = new File("d:/to/directory");  // 使用目录路径创建文件对象
boolean created = dir.mkdir();  // 创建目录
  1. 检查文件或目录是否存在:
boolean exists = file.exists();  // 检查文件是否存在
boolean isDirectory = file.isDirectory();  // 检查是否为目录
boolean isFile = file.isFile();  // 检查是否为文件
  1. 获取文件或目录的属性:
String name = file.getName();  // 获取文件或目录的名称
String absolutePath = file.getAbsolutePath();//获取文件或目录的绝对路径
String path = file.getPath();  // 获取文件或目录的相对路径
long size = file.length();  // 获取文件的大小(字节数byte)
long lastModified = file.lastModified();  // 获取文件或目录的最后修改时间
String name = file.getName();//获取文件的名字,包含了文件的扩展名
  1. 文件或目录的操作:
boolean renamed = file.renameTo(new File("f:/path/to/file.txt"));  // 重命名文件或目录
boolean deleted = file.delete();  // 删除文件或目录
  1. 遍历目录下的文件和子目录:
File[] files = dir.listFiles();  // 获取目录下的文件和子目录列表
for (File f : files) {
    if (f.isFile()) {
        // 处理文件
    } else if (f.isDirectory()) {
        // 处理子目录
    }
}
  1. 绝对路径和相对路径:

绝对路径:带有盘符就是绝对路径

相对路径:相对路径是相对于工程目录进行定位

  1. 文件查找和定位

文件查找和定位一般我们都是先找到父级文件夹,再找到具体的文件 这种定位方式我们一般都是通过两个参数来体现

//第一种:第一个参数是父级文件夹路径,第二个参数是文件名
File f1 = new File("d:/io", "test.txt");
System.out.println(f1.exists());
//第二种:第一个参数是父级文件夹对象,第二个参数是文件名
File parent = new File("d:/io");
File f2 = new File(parent, "user.txt");
System.out.println(f2.exists());
  1. 列出文件夹下的所有文件(下一级)
File folder = new File("d:/io");
        //列出文件夹下的所有文件(下一级)
        File[] files = folder.listFiles();
        if(files != null){
            Arrays.stream(files).forEach(System.out::println);
        }

结果:

2023年7月25日,File类,IO流_输出流

  1. 递归扫描文件夹
package com.wz.io;

import java.io.File;

public class ScanTest {
    public static void main(String[] args) {
        String folder = "d:/io";  // 指定要扫描的文件夹路径
        scanFolder(new File(folder));  // 调用scanFolder方法开始扫描
    }

    public static void scanFolder(File folder) {
        if (folder.isFile()) {  // 如果是文件,直接打印文件路径
            System.out.println(folder);
        } else {
            // 如果是文件夹,列出文件夹的下一级子文件
            File[] files = folder.listFiles();
            if (files != null) {
                for (File f : files) {
                    if (f.isDirectory()) {  // 如果是子文件夹,递归调用scanFolder方法
                        scanFolder(f);
                    } else {  // 如果是文件,打印文件路径
                        System.out.println(f);
                    }
                }
            }
        }
    }
}

结果:

2023年7月25日,File类,IO流_输出流_02

  1. 递归删除文件夹
package com.wz.io;

import java.io.File;

public class DeleteTest {
    public static void main(String[] args) {
        String folder = "d:/test";  // 指定要删除的文件夹路径
        deleteFolder(new File(folder));  // 调用deleteFolder方法开始删除
    }

    public static void deleteFolder(File folder) {
        if (folder.isDirectory()) {  // 如果是文件夹
            File[] files = folder.listFiles();  // 列出文件夹的下一级子文件
            if (files != null) {
                for (File f : files) {
                    if (f.isDirectory()) {  // 如果是子文件夹,递归调用deleteFolder方法
                        deleteFolder(f);
                    } else {  // 如果是文件,直接删除
                        f.delete();
                    }
                }
            }
        }
        folder.delete();  // 删除文件夹本身
    }
}

IO流

流:是一抽象概念,是对数据传输的总称。也就是说数据在设备间的传输称为流。更具体一点,是内存与存储设备之间传输数据的通道。

IO的概念:IO = input Output,也就是输入和输出,参照物就是内存

针对内存来说,把数据读入内存称为输入,将内存中的数据写出去就是输出。


IO按照读的方式分为字节流和字符流。字节流每次读取的基本单位是字节,字符流每次读取的单位是一个字符=2个字节,因此字节流每次读取8位,字符流每次读取16位。

2023年7月25日,File类,IO流_字符流_03

1. 字节流

1. OutputStream输出流(写数据)

package com.wz.io01_class;

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

public class OutputStreamTest {
    public static void main(String[] args) {
        String path = "d:/io/output.txt";
        File file = new File(path);
        //判断父级目录是否存在
        File parentFile = file.getParentFile();
        if (!parentFile.exists()){
            parentFile.mkdirs();
        }
        //try-with-resources=>JDK1.7提供的新特性 IO流在使用了之后会自动关闭
        //try-with-resources try后面的()中可以写多行代码,但是必须以分号分割开,最后一行代码的
        //分号可以省略。能够写入括号中的内容必须是实现了AutoClosable接口的流的构建
        try (OutputStream os = new FileOutputStream(file,true)) {
            String content = "hello world!!";
            final byte[] data = content.getBytes();//获取字符串的byte数据
            os.write(data);//写入数据
            os.flush();//强制将通道中的数据刷出,写入文件
        }catch (IOException e){
            e.printStackTrace();
        }

    }
}

2. InputStream输入流(读数据)

package com.wz.io01_class;

import java.io.*;

public class InputStreamTest {
    public static void main(java.lang.String[] args) {
        File file = new File("d:/io/output.txt");
        try (InputStream in = new FileInputStream(file);){
            //如果文件比较大,我们需要构建一个容器,来反复读取文件内容
            byte[] buffer = new byte[5];
            int len;
            while ((len = in.read(buffer)) != -1){
                System.out.println(new java.lang.String(buffer,0, len));
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

2. 字符流

字符流(Character Stream)是Java中用于以字符为单位进行读写操作的输入输出流。与字节流不同,字符流以字符作为数据处理的基本单位,而不是字节。

Java提供了两个主要的字符流类:Reader和Writer。这些类通常用于处理字符数据,例如文本文件或网络连接中的文本数据。

Reader类是抽象类,它的子类用于从字符源读取字符数据。常用的Reader子类包括FileReader(从文件中读取字符)、InputStreamReader(从字节流中读取字符)等。

package com.wz.char_class;

import java.io.*;

public class ReaderTest {
    public static void main(String[] args) {
        //字符流的顶层父类,Reader Writer
        try(Reader reader = new FileReader("d:/io/output.txt");
            Writer writer = new FileWriter("d:/io/output03.txt")){
            char[] buffer = new char[2048];
            int len;
            while ((len=reader.read(buffer))!=-1){
                System.out.println(new String(buffer,0,len));
                writer.write(buffer,0,len);
            }

        }catch (IOException e){
            e.printStackTrace();
        }
    }
}

这段代码首先通过FileReader创建一个字符输入流reader,用于读取文件"d:/io/output.txt"的内容。然后,通过FileWriter创建一个字符输出流writer,用于写入内容到文件"d:/io/output03.txt"。

在代码的主体部分,我们使用一个字符数组buffer作为缓冲区,大小设置为2048个字符。reader.read(buffer)方法会将文件的内容读取到buffer中,并返回实际读取的字符数(或者返回-1表示已到达文件末尾)。

然后,通过new String(buffer, 0, len)buffer中的字符转换为字符串,并在控制台打印该字符串。

最后,使用writer.write(buffer, 0, len)buffer中的字符写入到输出文件中。

try-with-resources语句用于自动关闭字符流。这样可以确保在代码块结束时,无论是否发生异常,都会正确关闭字符流。

3. 字节缓冲流

字节缓冲流(BufferedInputStreamBufferedOutputStream)是Java IO流中的一种类型,它们提供了缓冲功能,可以提高读写操作的效率。

字节缓冲流继承自字节流(InputStreamOutputStream),它们通过在内存中创建一个缓冲区(byte数组)来存储数据。当使用字节缓冲流进行读取或写入操作时,数据会先被读取到缓冲区中,然后从缓冲区中读取或写入到目标位置。这样可以减少实际的IO操作次数,提高读写效率。

BufferedInputStream类提供了以下常用方法:

int read()//从输入流中读取一个字节数据,并返回其整数表示(0-255),如果已经读取到流的末尾,则返回-1。
int read(byte[] buffer)//从输入流中读取一定数量的字节数据,并将其存储到指定的字节数组buffer中,返回实际读取的字节数,如果已经读取到流的末尾,则返回-1。
void close()//关闭输入流。

BufferedOutputStream类提供了以下常用方法:

void write(int byteValue)// 向输出流中写入一个字节数据。
void write(byte[] buffer)// 将指定的字节数组buffer中的数据写入到输出流中。
void flush()// 刷新输出流,将缓冲区中的数据立即写入到目标位置。
void close()//关闭输出流。

在使用字节缓冲流进行写入操作时,数据并不会立即写入到目标位置,而是先存储在缓冲区中。如果需要立即将数据写入到目标位置,可以调用flush方法刷新输出流。

字节缓冲流在处理大量数据时能够提供较高的读写效率,特别适用于频繁读写小块数据的场景。在进行文件复制、网络传输等操作时,使用字节缓冲流可以显著提升性能。

  • 利用字节缓冲流进行文件拷贝
package com.wz.charBufferStream;

import java.io.*;

public class Test01 {
    public static void main(String[] args) {
        String sourceFile ="d:/io/IO流理解图.png";
        String destFile = "d:/io/copy.png";
        copyFile(sourceFile,destFile);
    }
    public static void copyFile(String sourceFile,String destFile){
        //创建一个File对象,表示目标文件。
        File file = new File(destFile);
        //获取目标文件的父目录
        File parentFile = file.getParentFile();
        //判断父目录是否存在
        if (!parentFile.exists()) parentFile.mkdirs();
        //创建一个BufferedInputStream对象,并将其初始化为一个FileInputStream对象的包装器,用于读取源文件的数据。
        //创建一个BufferedOutputStream对象,并将其初始化为一个FileOutputStream对象的包装器,用于写入目标文件的数据。
        try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(sourceFile));
             BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFile))) {
            //创建一个字节数组作为缓冲区,用于存储从源文件读取的数据。
            byte[] buffer = new byte[2048];
            while(true){
                int len = bis.read(buffer);
                if (len==-1)break;
                bos.write(buffer,0,len);
                bos.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

4. 字符缓冲流

字符缓冲流是Java IO提供的一种高效的字符流,用于处理字符数据。它是基于字符流的装饰器模式实现的,通过在字符流的基础上添加缓冲功能来提高读写性能。 在Java中,字符缓冲流有两个主要的类:BufferedReader和BufferedWriter。


  • BufferedReader

BufferedReader是字符缓冲输入流,它提供了一些额外的方法来增强字符输入流的功能。它可以缓冲字符,允许高效的读取字符数据。它的构造方法可以接受一个字符输入流作为参数,然后创建一个带有缓冲功能的字符输入流。


常用方法:

readLine()//读取一行字符数据并返回一个字符串,如果到达文件末尾,则返回null。
read()//读取一个字符。
close()//关闭流,同时会关闭基础的字符输入流。
try (BufferedReader reader = new BufferedReader(new FileReader("file.txt"))) {
       String line;
       while ((line = reader.readLine()) != null) {
           System.out.println(line);
       }
   } catch (IOException e) {
       e.printStackTrace();
   }
  • BufferedWriter

BufferedWriter是字符缓冲输出流,它提供了一些额外的方法来增强字符输出流的功能。它可以缓冲字符并提供高效的写入操作。它的构造方法可以接受一个字符输出流作为参数,然后创建一个带有缓冲功能的字符输出流。


常用方法:

write(String str)//将字符串写入流中。
newLine()//写入一个行分隔符。
flush()//刷新缓冲区,将数据写入基础的字符输出流。
close()//关闭流,同时会关闭基础的字符输出流。
try (BufferedWriter writer = new BufferedWriter(new FileWriter("file.txt"))) {
       writer.write("Hello, world!");
       writer.newLine();
       writer.write("This is a test.");
       writer.flush();
   } catch (IOException e) {
       e.printStackTrace();
   }

通过使用字符缓冲流,可以提高字符输入输出操作的性能,尤其是在处理大量字符数据时,它能减少实际IO操作的次数,从而提高程序的效率。

5. 数据流

在Java的I/O流中,数据流(Data Stream)是一种流类别,用于处理基本数据类型和字符串的输入和输出。数据流提供了一种方便的方式来读取和写入原始数据类型(如int,double,boolean等)以及字符串,而无需手动进行数据类型转换。 Java的数据流操作由两个主要类组成:

  • 数据流的部分方法
void writeBoolean(boolean v) throws IOException;//将布尔值作为1个字节写入底层输出通道
void writeByte(int v) throws IOException;//将字节写入底层输出通道
void writeShort(int v) throws IOException;//将短整数作为2个字节(高位在前)写入底层输出通道
void writeChar(int v) throws IOException;//将字符作为2个字节写(高位在前)入底层输出通道
void writeInt(int v) throws IOException;//将整数作为4个字节写(高位在前)入底层输出通道
void writeLong(long v) throws IOException;//将长整数作为8个字节写(高位在前)入底层输出通道
void writeFloat(float v) throws IOException;//将单精度浮点数作为4个字节写(高位在前)入底层输出通道
void writeDouble(double v) throws IOException;//将双精度浮点数作为8个字节写(高位在前)入底层输出通道
void writeUTF(String s) throws IOException;//将UTF-8编码格式的字符串以与机器无关的方式写入底层输出通道。
package com.wz.io01;

import java.io.*;

public class Test01 {
    public static void main(String[] args) {
        dataStream();
    }

    private static void dataStream(){
        String path = "d:/io/test.txt";

        try (DataOutputStream dos = new DataOutputStream(new FileOutputStream(path));){
            dos.writeBoolean(false);
            dos.writeInt(1);
            dos.writeByte(2);
            dos.writeShort(3);
            dos.writeLong(4);
            dos.writeFloat(5.0f);
            dos.writeDouble(6.0);
            dos.writeChar('a');
            dos.writeUTF("Hello World");
            dos.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }

        try (DataInputStream dis = new DataInputStream(new FileInputStream(path))){
            boolean b = dis.readBoolean();
            System.out.println(b);
            int i = dis.readInt();
            System.out.println(i);
            byte b1 = dis.readByte();
            System.out.println(b1);
            short s = dis.readShort();
            System.out.println(s);
            long l = dis.readLong();
            System.out.println(l);
            float v = dis.readFloat();
            System.out.println(v);
            double v1 = dis.readDouble();
            System.out.println(v1);
            char c = dis.readChar();
            System.out.println(c);
            String s1 = dis.readUTF();
            System.out.println(s1);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

结果:

2023年7月25日,File类,IO流_字符流_04

注意:

在数据流中,读取顺序必须与写入顺序保持一致。这是因为数据流中的数据是按照特定的格式写入的,如果读取顺序与写入顺序不一致,就会导致数据读取错误或解析错误。 当使用数据流进行读取时,数据流会按照先后顺序解析数据,并将其转换为相应的数据类型。如果读取顺序与写入顺序不一致,例如尝试先读取一个整数,然后读取一个字符串,这样会导致读取出的数据类型不匹配,造成解析错误。

6. 序列化

将一个对象从内存中写入磁盘文件中的过程称之为序列化,反之就是反序列化。序列化必须要求该对象所有类型实现序列化的接口Serializable


注意: 序列化和反序列化的对象版本一致性,即序列化期间的Java类版本与反序列化期间的Java类版本应保持一致。如果版本不一致,可能会导致对象反序列化失败或数据丢失。

Serializable接口仅仅只用于标识序列化


实现了Serializable接口的类可以通过ObjectOutputStream类进行序列化,通过ObjectInputStream类进行反序列化。

package com.wz.io02;

import java.io.*;

public class Test {
    public static void main(String[] args) {
        serialize();
    }
    public static void serialize(){
        Student student = new Student("ZhangSan", 18, '男');
        try(ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("d:/io/test.txt"))){
            oos.writeObject(student);
            oos.flush();
        }catch (IOException e){
            e.printStackTrace();
        }

        try(ObjectInputStream ois = new ObjectInputStream(new FileInputStream("d:/io/test.txt"))) {
            Student s = (Student) ois.readObject();
            System.out.println(s);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
    }
}


标签:字符,File,25,IO,String,io,new,字节
From: https://blog.51cto.com/u_15098423/6848275

相关文章

  • 基于32位Cortex®-M4内核MK26FN2M0VMI18、MK22FN256VMP12、MK22FN512VLL12 180MHz/120
    一、MK26FN2M0VMI18KinetisK2032位微控制器是一款低功耗MCU,通过智能片上集成节省了大量BOM。该MCU基于Arm®Cortex®-M4核心,提供完整和可选的高速USB2.0(OTG控制器),包括无晶器件功能选项。此器件具有2MB的闪存,256KB的SRAM和多达2个USB控制器。详细描述:ARM®Cortex®-M4Kine......
  • 学习生理基础 | 记忆的四个环节2——保持 | 2023年7月25日
    小虾米原创作品,转载请注明出处:https://www.cnblogs.com/shrimp-can/p/17580595.html我们都想高效学习,但如何实现呢?网络上充斥着各种记忆、学习的技巧,能给予我们很大的帮助。但我始终认为,要做好一件事,须得“顺势而为”。那对于学习,什么是这个“势”呢?我认为便是人学习的生理和心......
  • Mentions组件设计
    前言 Mentions组件通常用在评论@某人。Antd是基于textarea实现,功能单一,无法对@xx进行样式设置。功能 基础API熟悉1.Range&Selection在阅读上述Mdn文档后,我们有以下的点需要注意1)如果当前已经有选区,则调用selection.addRange添加新的range会不生效,需要先取消选区sele......
  • 7.25
    #include<iostream>#include<stdio.h>#include<string>usingnamespacestd;intmain(){intn;cin>>n;inta[1001]={0};for(inti=0;i<n;i++){inttemp;cin>>temp;f......
  • GDI+区域(Region)排除与路径(GraphicsPath)叠加透明
    1、区域(Region)排除 1CRectrt;2GetClientRect(&rt);34GraphicsPathpa;5pa.AddEllipse(0,0,rt.Width(),rt.Height());6Regionrg(Rect(0,0,rt.Width(),rt.Height()));7rg.Exclude(&pa);8graphics.FillRegion(&SolidBrush(Color(255,0,......
  • Navigation的用法
    一.Navigation的诞生单个Activity嵌套多个Fragment的UI架构模式,已经被大多数的Android工程师所接受和采用。但是,对Fragment的管理一直是一件比较麻烦的事情。我们需要通过FragmentManager和FragmentTransaction来管理Fragment之间的切换。页面的切换通常还包括对应用程序App......
  • springsession 配置redis集群
    SpringSession配置Redis集群教程1.流程概述在本教程中,我们将详细介绍如何使用SpringSession来配置Redis集群。整个流程可以总结为以下几个步骤:添加SpringSession和Redis依赖配置Redis集群连接信息配置SpringSession使用Redis集群测试SpringSession与Redis集群的连接......
  • 洗衣机语音芯片NV170D,静态电流小于2uA一线MCU串口控制,IO口丰富
    洗衣机加入语音提示功能的主要是为了提高用户体验和方便用户使用。通过语音提示,洗衣机可以告诉用户当前洗涤、漂洗、脱水等不同阶段的进展状态,让用户更好地掌握洗衣机的工作情况,方便用户进行时间安排。此外,语音提示功能对于老年人或视力不好的人来说也非常有用,能够让他们更轻松地使......
  • 7.25总结
    今天那个idea过期了,原来我以为弄的学生认证可以,但是发现不知为啥没有成功,我也不愿意再搞这个了,后来想起来可以在淘宝买密钥啊,于是找了一个发现买了之后0元,这令我震惊啊正好白嫖,然后昨晚弄的GitHub不是很成功,今天成功上传了项目,但是再往里面传入另外一个就不行,还在找错误......
  • vue 项目打包iOS 配置
    Vue项目打包iOS配置Vue.js是一款用于构建用户界面的渐进式JavaScript框架。在开发过程中,我们经常需要将我们的Vue项目打包成iOS应用程序。本文将向您介绍如何配置一个Vue项目以打包成iOS应用程序,并提供代码示例供参考。安装依赖在开始之前,我们需要安装一些必要的......