基础IO的总结知识

File 文件操作类

  • File类使用-准备
方法解释
public File(String pathname)创建指定路径文件对象
public File(String parent, String child)同上,但可指明父路径和子路径
  • File类常用方法-基本文件操作
方法说明
public boolean exists()测试指定路径中文件或者目录是否存在
public boolean isDirectory()判定一个文件是目录
public boolean isFile()判定是否是文件
public boolean delete()删除文件
public boolean createNewFile() throws IOException创建一个新文件
import java.io.File;
import java.io.IOException;
public class FileDemo {
    public static void main(String[] args) {
        String path="E:\\java_code\\file\\";
        String name="demo.txt";
        String pathname=path+name;

        File file=new File(pathname);
        if(file.exists()){
            file.delete();
            System.out.println("文件"+pathname+"存在,删除之");
        }else{
            try{
                file.createNewFile();
                System.out.println("文件"+pathname+"不存在,创建之");
            } catch (IOException e) {
                System.out.println("文件"+pathname+"创建失败");
                e.printStackTrace();
            }
        }
    }
}
  • File类常用方法-目录操作
方法解释
public boolean mkdir()创建一个空目录
public boolean mkdirs()创建目录(无论有多少级父目录,都会创建)
public String getParent()取得父路径
public File getParentFile()取得父File对象
  • File类常用方法-文件属性操作操作
方法解释
public long length()取得文件大小(字节)
public long lastModified()最后一次修改日期
  • 绝对路径与相对路径
    绝对路径:
    是指目录下的绝对位置,直接到达目标位置,通常是从盘符开始的路径。完整的描述文件位置的路径就是绝对路径 。如: E:\javacode\Java8\Test.java 。
    相对路径:
    相对与某个基准目录的路径 。如当前路径为E:\javacode ,要描述上述路径( E:\javacode\Java8\Test.java ),只需输入: Java8\Test.java 。此时的路径是相对 E:\javacode 来说的。
  • File类常用方法-其他操作
方法解释
public File[] listFiles()列出一个目录指定的全部组成
import java.io.File;
import java.io.IOException;
public class FileDemo {
    public static void main(String[] args) {
        File file=new File("C:\\users\\whb\\");
        listAllFiles(file);
    }

    private static void listAllFiles(File file) {
        if(file.isDirectory()){
            File[] result=file.listFiles();
            if(result!=null){
                for(File file2:result){
                    listAllFiles(file2);
                }
            }
        }else{
            System.out.println(file);
        }
    }
}

  • 流:
    数据在两设备间的传输称为流,流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。
  • 输入就是将数据从各种输入设备(包括文件、键盘等)中读取到内存中。
    输出则正好相反,是将数据写入到各种输出设备(比如文件、显示器、磁盘等)。
  • 字节流:数据流中最小的数据单元是字节 InputStream、OutputStream
    字符流:数据流中最小的数据单元是字符 Reader、Writer
    在这里插入图片描述

1. 字节流(FileInputStream 和 FileOutputStream)
FileInputStream:从文件系统中的某个文件中获得输入字节
FileOutputStream:是用于将数据写入到输出流 File 或一个 FileDescriptor 。

	public static void main(String[] args) throws IOException{
        FileInputStream fin=new FileInputStream("E:\\bit\\bit.jpg");
        FileOutputStream fout=new FileOutputStream("E:\\bit\\bit\\BitCopy.jpg");
        int len=0;
        byte[] buff=new byte[1024];
        while((len=fin.read(buff))!=-1){
            fout.write(buff,0,len);
        }
        fin.close();
        fout.close();
    }

2. 字节缓冲流(BufferedInputStream 和 BufferedOutputStream)

为什么需要缓冲流?当我们用read()读取文件时,每读一个字节,访问一次硬盘,效率很低。文件过大时,操作起来也不是很方便。因此我们需要用到buffer缓存流动,当创建buffer对象时,会创建一个缓冲区数组。当我们读一个文件时,先从硬盘中读到缓冲区,然后直接从缓冲区输出即可,效率会更高。

	public static void main(String[] args) throws IOException {
        File file=new File("bit.txt");
        if(!file.isFile()){
            return;
        }
        BufferedInputStream bfis=new BufferedInputStream(new FileInputStream(file));
        // copy到src目录下
        BufferedOutputStream bfos=new BufferedOutputStream(new FileOutputStream("src\\"+file.getName()));
        byte[] bytes=new byte[1024];
        int temp=0;
        while((temp=bfis.read())!=-1){  // 读
            bfos.write(bytes,0,temp);  // 写
        }
        bfos.flush();
        bfos.close();
        bfis.close();
        System.out.println("copy成功!");
    }

3. 字符流(FileReader 和 FileReader)
FileReader:从文件中读取内容。FileReader 是用于读取字符流。 要读取原始字节流,请考虑使用 FileInputStream。
FileWriter:向文件中写入内容。FileWriter 是用于写入字符流。 要编写原始字节流,请考虑使用 FileOutputStream。

方法解释
FileReader(File file)创建一个新的FileReader,给出 File 读取。
FileReader(String fileName)创建一个新的FileReader ,给定要读取的文件的名称。
	public static void main(String[] args) throws IOException {
        // 创建输入流对象
        FileReader fr=new FileReader("E:\\bit\\bitSrc.java");
        // 创建输出流对象
        FileWriter fw=new FileWriter("E:\\bit\\bitCopy.java");
        
        // 读写数据
        int ch;
        while((ch=fr.read())!=-1){
            fw.write(ch);
        }
        
        // 释放资源
        fr.close();
        fw.close();
    }

4. 字符缓冲流(BufferedReader 和 BufferedWriter)
BufferedReader 用于加快读取字符的速度
BufferedWriter 用于加快写入的速度

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

  • 从字符输入流读取文本,缓冲字符,以提供字符,数组和行的高效读取
  • 将文本写入字符输出流,缓冲字符,以提供单个字符,数组和字符串的高效写入
方法解释
BufferedReader(Reader in)创建使用默认大小的输入缓冲区的缓冲字符输入流。
BufferedReader(Reader in, int sz)创建使用指定大小的输入缓冲区的缓冲字符输入流。
BufferedWriter(Writer out)创建使用默认大小的输出缓冲区的缓冲字符输出流。
BufferedWriter(Writer out, int sz)创建一个新的缓冲字符输出流,使用给定大小的输出缓冲区。

5. 字节流对比字符流

  • 字节流操作的基本单元是字节;
    字符流操作的基本单元为Unicode码元。
  • 字节流在操作的时候本身不会用到缓冲区的,是与文件本身直接操作的;
    而字符流在操作的时候使用到缓冲区的。
  • 所有文件的存储都是字节(byte)的存储,在磁盘上保留的是字节。
  • 在使用字节流操作中,即使没有关闭资源(close方法),也能输出;而字符流不使用close方法的话,不会输出任何内容。

6. 字符字节转换流(InputStreamReader 和 OutputStreamWriter)
InputStreamReader:将输入的字节流转换成字符流
OutputStreamWriter:将输出的字符流转换成字节流

// InputStreamReader
	public static void main(String[] args) {
        // 创建字节流对象 System.in 代表从控制台输入
        InputStream in=System.in;
        // 创建字符流对象
        BufferedReader br=null;
        BufferedWriter bw=null;

        try{
            // 实例化字符流对象,通过InputStreamReader将字节输入流转换成字符输入流
            br=new BufferedReader(new InputStreamReader(in));
            bw=new BufferedWriter(new FileWriter("a.txt"));

            // 定义读取数据的行
            String line=null;
            // 读取数据
            while((line=br.readLine())!=null){
                // 如果输入的是 exit 就退出
                if("exit".equals(line)){
                    break;
                }
                // 将数据写入文件
                bw.write(line);
                // 写入新的一行
                bw.newLine();
                // 刷新数据缓冲
                bw.flush();
            }
        }catch(Exception e){
            e.printStackTrace();
        }finally {
            // 释放资源
            try{
                if(bw!=null)
                    bw.close();
                if(br!=null)
                    br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

// OutputStreamWriter
	public static void main(String[] args) {
        // 定义字节输出流的对象 System.out
        OutputStream out=System.out;
        // 定义字符流的对象
        BufferedWriter bw=null;
        BufferedReader br=null;

        try{
            // 通过OutputStreamWriter将字符流转换成字节流对象
            bw=new BufferedWriter(new OutputStreamWriter(out));
            br=new BufferedReader(new FileReader("a.txt"));

            String line=null;
            // 读取数据
            while((line=br.readLine())!=null){
                // 输出到控制台
                bw.write(line);
                // 新的一行
                bw.newLine();
                // 刷新缓冲
                bw.flush();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            // 释放资源
            try{
                if(bw!=null)
                    bw.close();
                if(br!=null)
                    br.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

IO过程:
在这里插入图片描述
单纯站在数据角度:CPU直接从内存里读取数据,不会和外设打交道,为什么呢?因为硬盘太慢了…
所以数据要能够被CPU处理,就必须先被拿到内存,才能够被CPU处理!
将数据从输入设备拿到内存,我们称之为 input,将数据从内存输出到外设,我们称之为 output,简称这个过程为IO。

文件读写:硬盘
硬盘既可以充当输入设备(input),又可以充当输出设备(output)
在这里插入图片描述

序列化与反序列化

序列化:把内存里面的这些对象给变成一连串的字节描述的过程。
(序列化本身与语言无关)

什么时候需要序列化?
1、把内存中的对象状态保存到一个文件中或者数据库中的时候;
2、用套接字在网络上传送对象的时候。

静态变量的值是不会被进行序列化的
transient 修饰的变量,是不能被序列化的

import java.io.*;

public class Test2 {
    public static void main(String[] args) throws Exception {
        serializePerson();
        Person person=deserializePerson();
        System.out.println(person.toString());
    }

    // 序列化
    private static void serializePerson() throws IOException {
        Person person=new Person();
        person.setName("bit");
        person.setAge(10);
        person.setSex("男");
        person.setStuId(100);

        // ObjectOutputStream 对象输出流,将person对象存储到E盘的 person.txt 文件中,完成对 person 对象的序列化操作
        ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream(new File("E:/person.txt")));
        oos.writeObject(person);
        System.out.println("person对象序列化成功!");
        oos.close();
    }

    // 反序列化
    private static Person deserializePerson() throws Exception {
        ObjectInputStream ois=new ObjectInputStream(new FileInputStream(new File("E:/person.txt")));
        Person person=(Person)ois.readObject();
        System.out.println("person对象反序列化成功!");
        return person;
    }
}

ObjectOutputStream 代表对象输出流:它的 writeObject(Object obj) 方法可对参数指定的 obj 对象进行序列化,把得到的字节序列写到一个目标输出流中。
ObjectInputStream 代表对象输入流:它的 readObject() 方法从一个源输入流中读取字节序列,再把它们反序列化为一个对象,并将其返回。

小结:

  • 一个类如果想被序列化,那么需要实现一个Serializable接口。
  • 类中的静态变量的值是不会被进行序列化的,transient 修饰的属性,是不会被序列化的,内置类型为对应0值,引用类型为null。
  • 在实现这个Serializable 接口的时候,一定要给这个 serialVersionUID 赋值,最好设置为1L,这个L最好大写来区分,不然小写看起来像是1,不同的 serialVersionUID 的值,会影响到反序列化。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值