Java基础IO和文件

  • 思考:

如何从 Input 中把数据读到进程中来?
如何把数据读取到输出 Output 中去?

  • 理解输入与输出:
    当代PC机都基本遵循冯诺依曼体系结构
    在这里插入图片描述
    首先理解 CPU 是直接从内存中读取数据,不会和外设打交道。因为从硬盘读取数据太慢了,所以数据要能够被 CPU 处理,就必须先被拿到内存,才能够被 CPU 处理。

将数据从输入设备拿到 内存,被称为input
将数据从内存输出到外设,被称为output

1、输入源可能有很多
例如:输入流、网络流、文件流等。
2、整个数据流上会有各种的加工厂(一个一个的对象)
例如:图片对象、音频、视频、文本等。

一. 文件

文件是操作系统组织数据的一直方式。
来源:1. 80%是硬盘上的文件;
2. 硬盘、网络、屏幕都有可能被组织成文件(操作系统实现相关)

1.1 文件操作类

File类是 java.io 包里边 用来对文件进行操作(创建、删除、取得信息)的类。

1.2 File 的实例化方法
方法 解释
public File(String pathname) 创建指定路径文件对象
public File(String parent,String child) 同上,但可指明父路径和子路径
1.3 其他常用方法
方法 说明
public boolean exists() 测试指定路径的文件或者目录是否存在
public boolean isDirectory() 判断一个文件是否是目录 / 文件夹
public boolean isFile() 判断该文件是否是文件
public boolean delete() 删除某个文件
publid boolean deleteOnExit() 现在不删除,等待JVM退出的时候删除,是个临时文件
public boolean createNewFile() 之前的 file 指向的文件不存在,创建新文件
public boolean mkdir() 创建一个新的文件夹
public boolean mkdirs() 创建的是一个套娃的文件夹
public File[] listFile() 返回一个 文件(file) 数组
public boolean isHidden() 判断是否为隐藏文件
file.getFreeSpace() 返回文件所在盘符剩余空间的大小
file.getUsableSpace() 返回文件所在盘符剩余空间的大小
file.getTotalSpace() 返回文件所在盘符的总空间大小
file.getAbsolutePath() 返回文件的绝对路径
file.length() 返回文件的大小
package sin_2020_03_01;

import java.io.File;
import java.io.IOException;

public class Main {
    public static void main(String[] args) throws IOException {
        String parent = "E:\\test\\IO流\\新建文件夹";
        File file = new File(parent);
        System.out.println("文件是否存在:"+file.exists());
        System.out.println("文件是否为文件夹:"+file.isDirectory());
        System.out.println("文件所在盘符的可用空间:"+file.getFreeSpace());
        System.out.println("文件所在盘符的可用空间:"+file.getUsableSpace());
        System.out.println("文件所在盘符的总空间:"+file.getTotalSpace());
        System.out.println("文件的绝对路径:"+file.getAbsolutePath());
        System.out.println("文件的父路径:"+file.getParent());
        System.out.println("可读:"+file.canRead());
        System.out.println("可写:"+file.canWrite());
        System.out.println("可操作:"+file.canExecute());

    }
}

在这里插入图片描述
文件的创建及删除
注意:createNewFile() 创建出来的文件是位于,文件启动时所在的路径,即程序.class 文件(经过编译后的文件)所在的路径下

String parent = "E:\\test\\IO流\\新建文件夹";
        File file = new File(parent,"test.txt");
        file.createNewFile();
        file.delete();

一层文件夹的创建,和 套娃文件夹的创建

String parent = "E:\\test\\IO流\\新建文件夹";
        File file = new File(parent,"test.txt");
        file.mkdir();
        File file1 = new File(parent,"\\1\\2\\3\\4");
        file1.mkdirs();

在这里插入图片描述
file.listFile()

public static void Trave(File file){
        File[] files = file.listFiles();
        for(File f : files){
            if(f.isDirectory()){
                Trave(f);
            }else{
                System.out.println(f.getAbsolutePath() + " : "+f.length());
            }
        }
    }

在这里插入图片描述

二. 流

2.1 输入流和输出流
  • 输入流就是将数据从各种输入设备(硬盘、文件、键盘)中读取到内存中
    在这里插入图片描述

  • 输出流 将数据写入到各种输出设备(比如文件、显示器、硬盘等)
    在这里插入图片描述

2.2 字节流 和 字符流

File 类不支持文件内容操作,如果要处理文件内容,必须要通过流的操作模式来完成

  • 字节流:数据流中最小的数据单位是字节,8 位字节。InputStream、OutputStram
  • 字符流:数据流中最小的数据单位是字符,16 位字节。Reader、Writer

在这里插入图片描述

2.3 字节流
1、 FileInputStream 和 FileOutputStream
public class FileInputStream extends InputStream{}
public class FileOutputStream extends OutputStream{}
  • FileInputStream 从文件系统中的某个文件中获得输入字节
  • FileInputStream 用于读取文件的字节流

构造方法:

FileInputStream(File file) // 通过打开与实际文件的连接创建一个 FileInputStream,该文件由文件系统中的 File 对象 file 命名

  • 文件输出流是用于将数据写入到输出流 File 。文件是否可用或可能被创建取决于底层平台。

FileOutputStream(File file) // 创建文件输出流以写入由指定的 File 对象表示的文件

示例 用FileInputStream 和 FileOutputStream 实现文件拷贝

public static void main(String[] args) throws IOException {
        String sour = "E:\\test\\IO流\\测试文件.txt";
        String des = "E:\\test\\IO流\\目标文件.txt";

        File fileSour = new File(sour);
        File fileDes = new File(des);

        InputStream is = new FileInputStream(fileSour);
        OutputStream os = new FileOutputStream(fileDes);

        int len;
        byte[] buff = new byte[1024];
        while((len = is.read(buff)) != -1){
            os.write(buff,0,len);
        }
        is.close();
        os.close();
    }
2、字节缓冲流 BufferedInputStream 和 BufferedOutputStream

问题一:为什么要有缓冲流?

答:当我们用 read() 读取文件时,每读一个字节都需要访问一次硬盘,当文件过大时,效率就会变得特别低。因此我们需要用到 buffer 缓冲流,当我们读取一个文件时,先从硬盘中全部读取到缓冲区,然后从缓冲区输出即可效率会提高很多。当创建 buffer 对象的时候,会创建一个缓冲区数组

public class BufferedInputStream extends FileInputStream{}
public class BufferedOutputStream extends FileOutputStream{}

BufferedInputStream(InputStream in)
BufferedOutputStream(OutputStream os)

有无缓冲区两种情况下读数据花费时间的对比

package sin_2020_03_01.about_stream;
import java.io.*;
public class Compare {
    public static void main(String[] args) throws IOException {
        File file = new File("C:\\Users\\wp\\测试.docx");

        // 无缓冲区
        InputStream is = new FileInputStream(file);
        long time = System.currentTimeMillis();
        int len;
        while((len = is.read()) != -1){

        }
        time = System.currentTimeMillis() - time;
        System.out.println("无缓冲区:" + time);

        // 有缓冲区
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
        long time1 = System.currentTimeMillis();
        int tmp = 0;
        while((tmp = bis.read()) != -1){

        }
        time1 = System.currentTimeMillis() - time1;
        System.out.println("有缓冲区" + time1);
    }
}

在这里插入图片描述

2.4 字符流
1、字符流 FileReader 和 FileWriter
public class FileReader extends InputStreamReader{}
public class FileWriter extends OutputStreamWriter{}
  • 使用 FileReader 子类可以从文件中读取内容
  • FileReader 是用于读取字符流

FildeReader(File file) // 创建一个新的 FileReader,给出 File 读取

  • 使用 FIleWriter 子类向文件中写入字符流。

FileWriter(File file) // 给一个 File 对象构造一个 FileWriter 对象

示例使用FileReader 和 FileWriter 复制文件

package sin_2020_03_01.about_stream;
import java.io.*;
import java.util.Arrays;
public class CopyPicture3 {
    public static void main(String[] args) throws IOException {
        File file = new File("E:\\test\\IO流\\测试文件.txt");
        File file1 = new File("E:\\test\\IO流\\目标文件3.txt");

        FileReader fr = new FileReader(file);
        FileWriter fw = new FileWriter(file1);

        char[] buff = new char[20];
        int len = fr.read(buff);
        fw.write(buff);
        System.out.println(len);
        System.out.println(Arrays.toString(buff));
        fr.close();
        fw.close();
    }
}

2、字符缓冲区 BufferedReader 和 BufferWriter

为了提高字符流读写的效率,引入了缓冲机制,进行字符批量的读写。
当 BufferedReader 在读取文本文件时,会先尽量从文件中读入字符数据并放满缓冲区,而之后使用 read() 方法,会先从缓冲区中进行读取。如果缓冲区数据不足,才会再从文件中读取。
使用 BufferedWriter 时,写入的数据并不会先输出到目的地,而是先存储至缓冲区中。如果缓冲区中的数据写满了,才会一次对目的地进行写出。

public class BufferedReader extends Reader{}
public class BufferedWriter extends Writer{}
  • 从字符输入流读取文本,缓冲字符,以提供字符、数组和行的高效率读取。

BufferedReader(Reader in) // 使用默认大小的输入缓冲区的缓冲字符输入流

  • 将文本写入字符输出流,换成字符以提供单个字符,数组和字符串的高效写入。

BufferedWriter (Writer os)

示例使用BufferedReader 和 BufferWriter进行文件拷贝

package sin_2020_03_01.about_stream;

import java.io.*;
import java.util.Scanner;

public class CopyPicture4 {
    public static void main(String[] args) throws IOException {
        File file = new File("E:\\test\\IO流\\测试文件.txt");
        File file1 = new File("E:\\test\\IO流\\目标文件4.txt");

        //BufferedReader br = new BufferedReader(new FileReader(file));
        Scanner sc = new Scanner(System.in);
        BufferedWriter bw = new BufferedWriter(new FileWriter(file1));

        String content = "";
        while((content = sc.nextLine()) != null){
        //while((content = br.readerLine()) != null){    
            bw.write(content+"\r\n");
            System.out.println(content);
            bw.flush();
        }
        sc.close();
        // br.close();
        bw.close();
    }
}

其中 scanner 代表的时从键盘输入。

三. 序列化与反序列化

序列化与反序列化

发布了98 篇原创文章 · 获赞 5 · 访问量 6450

猜你喜欢

转载自blog.csdn.net/weixin_43580746/article/details/104593206