1.8(java高级特性)file文件与IO

** 前言: **
兄弟们看完之后。给个反馈吧。我还是改不掉我的贪玩,拖延症的习惯啊,有的时候一天看短视频就是4,5小时,哎~~
接下来的文章内容来源于。感谢收看
[硅谷学习路线](2021年度全网最全Java学习路线 - 哔哩哔哩 (bilibili.com))

File类

java.io.File类:文件和文件目录路径的抽象表示形式,与平台无关

File 能新建、删除、重命名文件和目录,但 File 不能访问文件内容本身。 如果需要访问文件内容本身,则需要使用输入/输出流。

想要在Java程序中表示一个真实存在的文件或目录,那么必须有一个File对 象,但是Java程序中的一个File对象,可能没有一个真实存在的文件或目录。

File可以表示文件,目录。但是不能读取和写入文件。读取和写入属于IO操作

File类常见的构造器

构造函数 描述
public File(String pathname) 以pathname为路径创建File对象,可以是绝对路径或者相对路径,如果 pathname是相对路径,则默认的当前java文件相对。 绝对路径:是一个固定的路径,从盘符开始 。 相对路径:是相对于某个位置开始
public File(String parent,String child) 以parent为父路径,child为子路径创建File对象。
public File(File parent,String child) 根据一个父File对象和子文件路径创建File对
public class FileTest {
    
    
    public static void main(String[] args) {
    
    

//        第一种构造器
        File file1 = new File("D:\\myeclipse");
        System.out.println("文件的名字"+file1.getName());

//        第二种构造器
        File file2 = new File("D:\\myeclipse","binary");
        System.out.println("是否是目录"+file2.isDirectory());

//        第三种
        File file3 = new File(file1,"notice.html");
        System.out.println("file3文件的大小"+file3.length());
        
    }
}

在这里插入图片描述

上面说相对路径

java默认的相对路径

指的就是该项目存放的位置

在这里插入图片描述

public class FileTest {
    
    
    public static void main(String[] args) {
    
    

//        java的默认相对位置就是当前项目存放的位置
        File file4 = new File("pom.xml");
        System.out.println(file4.length());
    }
}

在这里插入图片描述

路径分割符

路径中的每级目录之间用一个路径分隔符隔开。

路径分隔符和系统有关:

windows和DOS系统默认使用“\”来表示

UNIX和URL使用“/”来表示

Java程序支持跨平台运行,因此路径分隔符要慎用。

public static final String separator。根据操作系统,动态的提供分隔符。

File file2 = new File("d:" + File.separator + "atguigu" + File.separator + "info.txt");

File常用方法

方法 描述
public String getAbsolutePath() 获取绝对路径
public String getPath() 获取路径
public String getName() 获取名称
public String getParent() 获取上层文件目录路径。若无,返回null
public long length() 获取文件长度(即:字节数)。不能获取目录的长度。
public long lastModified() 获取最后一次的修改时间,毫秒值
public String[] list() 获取指定目录下的所有文件或者文件目录的名称数组
public File[] listFiles() 获取指定目录下的所有文件或者文件目录的File数组

File类的判断方法

方法 描述
public boolean isDirectory() 判断是否是文件目录
public boolean isFile() 判断是否是文件
public boolean exists() 判断是否存在
public boolean canRead() 判断是否可读

File类的创建功能

方法 描述
public boolean createNewFile() 创建文件。若文件存在,则不创建,返回false
public boolean mkdir() 创建文件目录。如果此文件目录存在,就不创建了。 如果此文件目录的上层目录不存在,也不创建。
public boolean mkdirs() 创建文件目录。如果上层文件目录不存在,一并创建 注意事项:如果你创建文件或者文件目录没有写盘符路径,那么,默认在项目 路径下。
public boolean delete() 删除文件或者文件夹

删除注意事项:

Java中的删除不走回收站。 要删除一个文件目录,请注意该文件目录内不能包含文件或者文件目录

JAVA的IO

每年的谷歌都有IO大会(开放中创新),了解一下 。

java中的IO:

I/O是Input/Output的缩写, I/O技术是非常实用的技术,用于 处理设备之间的数据传输。如读/写文件,网络通讯等。

Java程序中,对于数据的输入/输出操作以“流(stream)” 的 方式进行。

java.io包下提供了各种“流”类和接口,用以获取不同种类的 数据,并通过标准的方法输入或输出数据。

流的分类

按操作数据单位不同分为

字节流(8 bit),字符流(16 bit)

**字节流:**一般用于处理图片,视频等

**字符流:**处理文件。

按数据流的流向不同分为

输入流,输出流

**输入流input:**读取外部数据(磁 盘、光盘等存储设备的数据)到 程序(内存)中。

**输出output:**将程序(内存) 数据输出到磁盘、光盘等存储设 备中。

按流的角色的不同分为

节点流,处理流

**节点流:**表示其他设备直接向内存中进行操作

在这里插入图片描述

**处理流:**表示在节点流之上在做一层处理的操作。可以使流的效率提高

在这里插入图片描述

在这里插入图片描述

Java的IO流共涉及40多个类,实际上非常规则,都是从如下4个 抽象基类派生的。

由这四个类派生出来的子类名称都是以其父类名作为子类名后缀。

在这里插入图片描述

下面主要介绍这些实现类

在这里插入图片描述

操作步骤

File类的实例化:先找到指定的文件

流实现类的加载文件

读写操作

资源的关闭。确保资源的使用,用完就关闭

InputStream

常用方法

方法 描述
int read() 从输入流中读取数据的下一个字节。返回 0 到 255 范围内的 int 字节值。如果因 为已经到达流末尾而没有可用的字节,则返回值 -1。
int read(byte[] b) 从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中。如果因为已 经到达流末尾而没有可用的字节,则返回值 -1。否则以整数形式返回实际读取 的字节数。
int read(byte[] b, int off,int len) 将输入流中最多 len 个数据字节读入 byte 数组。尝试读取 len 个字节,但读取 的字节也可能小于该值。以整数形式返回实际读取的字节数。如果因为流位于 文件末尾而没有可用的字节,则返回值 -1。
public void close() throws IOException 关闭此输入流并释放与该流关联的所有系统资源。

示例

这个示例中展示了输入流

讲文件内容输入到内存中,从而在内存中进行打印

在这里插入图片描述

public class FileTest {
    
    
    public static void main(String[] args) {
    
    

//        java的默认相对位置就是当前项目存放的位置
        File file4 = new File("C:\\Users\\HP\\Desktop\\ByteTest.txt");

//        可以看到checked异常处理
        try {
    
    

            InputStream inputStream = new FileInputStream(file4);
            System.out.println("开始字节文件输出");
            int read = inputStream.read();
            while (read != -1) {
    
    
                System.out.print((char) read);
                read = inputStream.read();
            }

            inputStream.close();

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

        try {
    
    
            FileReader fileReader = new FileReader(file4);
            System.out.println("开始字符流输出");
            int read = fileReader.read();
            while (read != -1) {
    
    
                System.out.print((char) read);
                read = fileReader.read();
            }

            fileReader.close();

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


    }
}

在这里插入图片描述

上面我们同时使用了字节流和字符流对全是英文的内容做处理

接下来我们换成中文试一试。

在这里插入图片描述

在这里插入图片描述

发现结果变为,字节流产生乱码,字符流可以进行完整打印

Reader

常用的方法

方法 描述
int read() 读取单个字符。作为整数读取的字符,范围在 0 到 65535 之间 (0x00-0xffff)(2个 字节的Unicode码),如果已到达流的末尾,则返回 -1
int read(char[] cbuf) 将字符读入数组。如果已到达流的末尾,则返回 -1。否则返回本次读取的字符数。
int read(char[] cbuf,int off,int len) 将字符读入数组的某一部分。存到数组cbuf中,从off处开始存储,最多读len个字 符。如果已到达流的末尾,则返回 -1。否则返回本次读取的字符数。
public void close() throws IOException 关闭此输入流并释放与该流关联的所有系统资源。

合理的使用上面的方法,即可完成对应的操作

OutputStream

常用方法

方法 描述
void write(int b) 将指定的字节写入此输出流。write 的常规协定是:向输出流写入一个字节。要写 入的字节是参数 b 的八个低位。b 的 24 个高位将被忽略。 即写入0~255范围的。
void write(byte[] b) 将 b.length 个字节从指定的 byte 数组写入此输出流。write(b) 的常规协定是:应该 与调用 write(b, 0, b.length) 的效果完全相同。
void write(byte[] b,int off,int len) 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此输出流。
public void flush()throws IOException 刷新此输出流并强制写出所有缓冲的输出字节,调用此方法指示应将这些字节立 即写入它们预期的目标。
public void close() throws IOException 关闭此输出流并释放与该流关联的所有系统资源。

图片的复制示例

package FileTest;

import java.io.*;

public class pictureCope {
    
    
    public static void main(String[] args) {
    
    

//        创建以file表示指定的图片
        File file = new File("C:\\Users\\HP\\Desktop\\mr.jpg");

//        再次创建file,此时指定的文件不存在。
//        默认当指定不存在的文件会进行创建
        File file01 = new File("C:\\Users\\HP\\Desktop\\mr01.jpg");

//        因为是图片等需要使用字节流
        try {
    
    
//            字节流的输入流
            FileInputStream fileInputStream = new FileInputStream(file);

            FileOutputStream fileOutputStream = new FileOutputStream(file01);


//            先去进行一点一点的读取,读取的时候进行传入
            int read = fileInputStream.read();
            while (read !=-1){
    
    
                fileOutputStream.write(read);
                read = fileInputStream.read();
            }

            fileInputStream.close();
            fileOutputStream.close();
        } catch (FileNotFoundException e) {
    
    
            e.printStackTrace();
        }catch (IOException e){
    
    
            e.getMessage();
        }


    }
}

在这里插入图片描述

Writer

方法 描述
void write(int c) 写入单个字符。要写入的字符包含在给定整数值的 16 个低位中,16 高位被忽略。 即 写入0 到 65535 之间的Unicode码。
void write(char[] cbuf) 写入字符数组。
void write(char[] cbuf,int off,int len) 写入字符数组的某一部分。从off开始,写入len个字符
void write(String str) 写入字符串。
void write(String str,int off,int len) 写入字符串的某一部分。
void flush() 刷新该流的缓冲,则立即将它们写入预期目标。
public void close() throws IOException 关闭此输出流并释放与该流关联的所有系统资源。

示例

public class ReadTest {
    
    
    public static void main(String[] args) {
    
    

        File file = new File("C:\\Users\\HP\\Desktop\\ByteTest.txt");
        try {
    
    
            FileWriter fileWriter = new FileWriter(file);

            System.out.println("指定写入的内容:");
            fileWriter.write("加油华为,5G领导者");

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

    }
}

在这里插入图片描述

根据结果发现,确实写入了

但是内容被覆盖了。想要不覆盖。在构造函数中设置参数

FileWriter fileWriter = new FileWriter(file,true);

缓冲流

为了提高数据读写的速度,Java API提供了带缓冲功能的流类,

在使用这些流类 时,会创建一个内部缓冲区数组,缺省使用8192个字节(8Kb)的缓冲区。

在这里插入图片描述

缓冲流要“套接”在相应的节点流之上,根据数据操作单位可以把缓冲流分为:

字节流对应的:BufferedInputStream 和 BufferedOutputStream

字符流对应的:BufferedReader 和 BufferedWriter

在这里插入图片描述

示例

在图片复制基础上进行添加代码

package FileTest;

import java.io.*;

public class pictureCope {
    public static void main(String[] args) {

//        创建以file表示指定的图片
        File file = new File("C:\\Users\\HP\\Desktop\\mr.jpg");

//        再次创建file,此时指定的文件不存在。
//        默认当指定不存在的文件会进行创建
        File file01 = new File("C:\\Users\\HP\\Desktop\\mr02.jpg");

//        因为是图片等需要使用字节流
        try {
//            字节流的输入流
            FileInputStream fileInputStream = new FileInputStream(file);
//             字节的输出流
            FileOutputStream fileOutputStream = new FileOutputStream(file01);

//            添加缓冲流
//            输入流的缓冲,讲输入流带入
            BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
            BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);


//            先去进行一点一点的读取,读取的时候进行传入
            int read = bufferedInputStream.read();
            while (read !=-1){
                bufferedOutputStream.write(read);
                read = bufferedInputStream.read();
            }

//            先关闭最外层的缓冲流,在关闭内部的节点流
            bufferedInputStream.close();
            bufferedOutputStream.close();

            fileInputStream.close();
            fileOutputStream.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }catch (IOException e){
            e.getMessage();
        }

    }
}

根据结果确实实现功能。缓冲流可以提高效率

注意

关闭流的顺序和打开流的顺序相反。只要关闭最外层流即可,关闭最外层流也 会相应关闭内层节点流

如果是带缓冲区的流对象的close()方法,不但会关闭流,还会在关闭流之前刷 新缓冲区,关闭后不能再写出

转换流

转换流提供了在字节流和字符流之间的转换

Java API提供了两个转换流:

  1. InputStreamReader:将InputStream转换为Reader
  2. OutputStreamWriter:将Writer转换为OutputStream

字节流中的数据都是字符时,转成字符流操作更高效。

在这里插入图片描述

InputStreamReader

实现将字节的输入流按指定字符集转换为字符的输入流。

构造函数

public InputStreamReader(InputStream in)

public InputSreamReader(InputStream in,String charsetName)

第二种指定类转换的字符编码

示例

//            讲字节流的输入流转换为字符流的输入流
            InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream);

OutputStreamWriter

实现将字符的输出流按指定字符集转换为字节的输出流。

构造函数

public OutputStreamWriter(OutputStream out)

public OutputSreamWriter(OutputStream out,String charsetName)

示例

//            讲字节流的输出流转换为字符流的输出流
            OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fileOutputStream);

字符编码

编码表的由来

计算机只能识别二进制数据,早期由来是电信号。为了方便应用计算机,让它可以识 别各个国家的文字。就将各个国家的文字用数字来表示,并一一对应,形成一张表。 这就是编码表。

常见的编码表

ASCII:美国标准信息交换码。 用一个字节的7位可以表示。

ISO8859-1:拉丁码表。欧洲码表 用一个字节的8位表示。

GB2312:中国的中文编码表。最多两个字节编码所有字符

GBK:中国的中文编码表升级,融合了更多的中文文字符号。最多两个字节编码

Unicode:国际标准码,融合了目前人类使用的所有字符。为每个字符分配唯一的 字符码。所有的文字都用两个字节来表示。

UTF-8:变长的编码方式,可用1-4个字节来表示一个字符。

GBK的问题解决

因为GBK表示中文的字符编码,一个字符最多使用两个字节。

但是当计算机中存在两个字节的时候。

如何判断它算是一个字符还是两个字符

通过第一个字节上面的其实数组是0或1。0表示一个字符1表示1两个字符

Unicode的问题和解决

在这里插入图片描述

在这里插入图片描述

这一段可以去看一看硅谷的课程,讲的特别生动。

在这里插入图片描述

其他流

流的分布存在很多,感兴趣可以多了解亿点点

标准输入输出流

System.in和System.out分别代表了系统标准的输入和输出设备

默认输入设备是:键盘,输出设备是:显示器

System.in的类型是InputStream

System.out的类型是PrintStream,其是OutputStream的子类 FilterOutputStream 的子类

在最开始我们经常使用的输入输出

  Scanner sc = new Scanner(System.in);
  System.out.println("请输入信息");

おすすめ

転載: blog.csdn.net/weixin_46401545/article/details/121538576