IO流常用小知识

1.IO流概述

1.1 什么是IO流

I/O,即输入(Input)/ 输出(Output),IO流指的是数据像连绵的流体一样进行传输。Java中I/O的操作是指使用java.io包下的内容进行输入、输出操作。

1.2 IO流的分类

按数据的流向分为:输入流 和 输出流

按数据的类型分为:

  • 字节流:以字节为单位来操作数据。
    • InputStream:字节输入流的顶层抽象类.
      • FileInputStream:普通的字节输入流.
      • BufferedInputStream:高效的字节输入流(也叫: 字节缓冲输入流)
    • OutputStream:字节输出流的顶层抽象类
      • FileOutputStream:普通的字节输出流
      • BufferedOutputStream:高效的字节输出流(也叫: 字节缓冲输出流)
  • 字符流:以字符为单位来操作数据
    • Reader:字符输入流的顶层抽象类
      • FileReader:普通的字符输入流
      • BufferedReader:高效的字符输入流(也叫: 字符缓冲输入流)
    • Writer:字符输出流的顶层抽象类
      • FileWriter:普通的字符输出流
      • BufferedWriter:高效的字符输出流(也叫: 字符缓冲输出流)

2.File类

  • java.io.File 类是专门对文件进行操作的类,只能对文件本身进行操作,不能对文件内容进行操作。
  • java.io.File 类是文件和目录路径名的抽象表示,主要用于文件和目录的创建、查找和删除等操作。
  • 也就是说,File类只能针对文件和目录进行操作,不能对文件内容进行读写操作。

2.1构造方法

构造方法:File类有三个常用的构造方法

//1.根据字符串形式获取File对象
public File(String pathname);
//2.根据字符串形式的父目录以及子目录创建File对象
public File(String parent, String child);
//3.根据父目录对象以及字符串形式的子目录对象获取File对象
public File(File parent, String child);
String pathname = "E:\\test\\1.txt"
String parent = "E:\\test\\"
String child = "1.txt"
//方式一:根据字符串形式获取File对象
File file1 = new File(pathname);
//方式二:根据字符串形式的父目录以及子目录创建File对象
File file2 = new File(parent,child);
//方式三:根据父目录对象以及字符串形式的子目录对象获取File对象
File file3 = new File(new File(parent),child);

2.1常用方法

  • createNewFile():创建文件 。
  • mkdir()和mkdirs():创建单极目录和多级目录。
  • isDirectory():判断File对象是否为目录。
  • isFile():判断File对象是否为文件。
  • exists():判断File对象是否存在。
  • getAbsolutePath():获取绝对路径。
  • getPath():获取文件的相对路径。
  • getName():获取文件名。
  • list():获取指定目录下所有文件(夹)名称数组。
  • listFiles():获取指定目录下所有文件(夹)File数组。
//在 E:\test\ 文件夹下创建 1.txt 文件
File file1 = new File("E:\\test\\2.txt");
Boolean flag = file1.createNewFile();
System.out.println(flag);
//在 E:\test\ 下创建 test1 文件夹,创建单极目录
File file2 = new File("E:\\test\\test1");
file2.mkdir();
//在 E:\test\ 下创建 a\b\c 文件夹,创建多极目录
File file3 = new File("E:\\test\\a\\b\\c");
file3.mkdirs(); //创建多级目录

System.out.println("------------------测试判断功能------------------");
File file4 = new File("E:\\test\\a\\b\\c");
file8.mkdirs();
System.out.println("测试file4是否是文件夹"+file4.isDirectory());
System.out.println("测试file4是否是文件"+file4.isFile());
System.out.println("测试file4是否存在"+file4.exists());

System.out.println("------------------测试获取功能------------------");
File file5 = new File("a/1.txt");
//获取绝对路径
String path1 = file5.getAbsolutePath();
System.out.println("绝对路径: "+path1);
//获取相对路径
String path2 = file5.getPath();
System.out.println("相对路径:"+path2);
//获取文件名
String filename = file5.getName();
System.out.println("文件名:"+filename);

System.out.println("------------------------------------");
//获取lib文件夹下所有文件(夹)的:名称数组String[]
File file6 = new File("a");
String[] names = file6.list();
for (String name:names){
	System.out.println(name);
}
//获取lib文件夹下所有文件(夹)的:File对象数组 File[]
File[] files = file6.listFiles();
for(File file:files){
	System.out.println(file);
}

3.字符流

3.1 字符输入流

构造方法
// 创建一个新的 FileReader ,给定要读取的File对象。
FileReader(File file)
// 创建一个新的 FileReader ,给定要读取的文件的字符串名称。
FileReader(String fileName)
字符流读数据 – 按单个字符读取

读取字符:read方法,每次可以读取一个字符的数据,提升为int类型,读取到文件末尾,返回-1,循环读取,代码使用演示:

public class TestReader {
    public static void main(String[] args) throws Exception {
        //通过字符流读取数据
        Reader reader = new FileReader("a/1.txt");
        int ch;
        while ((ch = reader.read()) != -1){
            System.out.println((char)ch);
        }
        //关闭资源
        reader.close();
    }
}
字符流读数据 – 按字符数组读取
public class TestReader2 {
    public static void main(String[] args) throws IOException {
        //通过字符数组读取数据
        Reader reader = new FileReader("a/1.txt");
        char[] chs = new char[3];
        int len = 0;
        // 读取字符到数组中,返回读取的字符数,若到达流的末尾,返回-1
        while ((len = reader.read(chs))!=-1){
            String s = new String(chs,0,len);
            System.out.println(s);
        }
        reader.close();
    }
}

3.2字符输出流

构造方法
//创建一个新的 FileWriter,给定要读取的File对象。
FileWriter(File file)
//创建一个新的 FileWriter,给定要读取的文件的名称。
FileWriter(String fileName)
字符流写数据 – 按单个字符写入
public class TestWrite {
    public static void main(String[] args) throws IOException {
        // 使用文件名称创建流对象
        FileWriter fw = new FileWriter("1.txt");     
      	// 写出数据
      	fw.write(97); // 写出第1个字符
      	fw.write('b'); // 写出第2个字符
      	fw.write('C'); // 写出第3个字符
        //关闭资源。
        // fw.close();
    }
}
字符流写数据 – 按字符数组写入
public class Testwriter {
    public static void main(String[] args) throws IOException {
        Writer writer = new FileWriter("a/1.txt");
        //每写入一次会覆盖之前的内容
        char[] chars = {'女','朋','朋','很','帅'};
        writer.write(chars,0,3);
        writer.write("好好学习");
        writer.close();
    }
}

3.3 FileReader和FileWriter完成文本复制

每次读取一个字符,效率太低,因此我们一般都采用数组进行读写操作。

public class CopyFile {
    public static void main(String[] args) throws IOException {
        //将 1.txt 文件中的内容拷贝到 2.txt 中
        //创建输入流对象
        FileReader fileReader = new FileReader("1.txt");
        //创建输出流对象
        FileWriter fileWriter = new FileWriter("2.txt");
        int len;
        char[] chars = new char[1024];
        while ((len = fileReader.read(chars))!=-1){ //读数据
      		//写数据
            fileWriter.write(chars,0,len);
        }
        fileReader.close();
        fileWriter.close();
    }
}

最后强调:字符流,只能操作文本文件,不能操作图片,视频等非文本文件。当我们单纯读或者写文本文件时使用字符流其他情况使用字节流

4.字节流

4.1 构造方法

FileInputStream的构造方法:

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

FileOutputStream的构造方法:

//根据File对象为参数创建对象。
public FileOutputStream(File file)
//根据名称字符串为参数创建对象。
public FileOutputStream(String name)

一般使用第二种构造方法。

字节流的用法和字符流大体一致,因此在这里我们直接进行应用,上面介绍的字符流无法对图片进行读写操作,因此下面我们用字节流对图片进行读写操作来举例。

4.2 字节流拷贝文件 – 按单个字节读写

public class CopyFile{
    public static void main(String[] args) throws IOException {
    	// 使用文件名称创建字节流读文件对象
        FileInputStream fls = new FileInputStream("1.png");
        // 使用文件名称创建字节流写文件对象
        FileOutputStream fos = new FileOutputStream("2.png");
        int len;
        while ((len = fls.read())!=-1){
            fos.write(len);
        }
        fls.close();
        fos.close();
    }
}

4.3 字节流拷贝文件 – 按字节数组读写

在开发中一般强烈推荐使用数组读取文件,代码如下:

public class CopyFile {
    public static void main(String[] args) throws IOException {
    	// 使用文件名称创建字节流读文件对象
        FileInputStream fls = new FileInputStream("1.png");
        // 使用文件名称创建字节流写文件对象
        FileOutputStream fos = new FileOutputStream("2.png");
        int len;
        //定义字节数组,每次读取1024个字节
        byte[] bytes = new byte[1024];
        while ((len = fls.read(bytes))!=-1){
            fos.write(bytes,0,len);
        }
        fls.close();
        fos.close();
    }
}

5.缓冲流

缓冲流的基本原理:

  1. 使用了底层流对象从具体设备上获取数据,并将数据存储到缓冲区的数组内。
  2. 通过缓冲区的read()方法从缓冲区获取具体的字符数据,这样就提高了效率。
  3. 如果用read方法读取字符数据,并存储到另一个容器中,直到读取到了换行符时,将另一个容器临时存储的数据转成字符串返回,就形成了readLine()功能。

也就是说在创建流对象时,会创建一个内置的默认大小的缓冲区数组,通过缓冲区读写,减少系统IO次数,从而大大提高读写的效率。

5.1字节缓冲流

构造方法
//创建一个新的缓冲输入流,注意参数类型为InputStream。
public BufferedInputStream(InputStream in)
//创建一个新的缓冲输出流,注意参数类型为OutputStream。
public BufferedOutputStream(OutputStream out)
字节缓冲流拷贝文件的标准代码
public class CopyFile{
    public static void main(String[] args) throws IOException {
    	//记录开始时间
    	long start = System.currentTimeMillis();
    	//创建字节缓冲流对象
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("1.png"));
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("2.png"));
        int len;
        while ((len = bis.read())!=-1){ //读数据
        	//写数据
            bos.write(len);
        }
        bis.close();
        bos.close();
        //记录结束时间
        long end = System.currentTimeMillis();
        System.out.println("缓冲流使用数组复制时间:"+(end - start)+" 毫秒");
    }
}

那么能不能更快呢,答案是可以的,下面我们使用字节缓冲流和字节数组进行读写操作,代码如下:

public class CopyFile{
    public static void main(String[] args) throws IOException {
    	//记录开始时间
    	long start = System.currentTimeMillis();
    	//创建字节缓冲流对象
        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("1.png"));
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("2.png"));
        int len;
        byte[] bytes = new byte[2048];
        while ((len = bis.read(bytes))!=-1){ //读数据
        	//写数据
            bos.write(bytes,0,len);
        }
        bis.close();
        bos.close();
        //记录结束时间
        long end = System.currentTimeMillis();
        System.out.println("缓冲流使用数组复制时间:"+(end - start)+" 毫秒");
    }
}

5.2字符缓冲流

构造方法
//创建一个新的缓冲输入流,注意参数类型为Reader。
public BufferedReader(Reader in)
//创建一个新的缓冲输出流,注意参数类型为Writer。
public BufferedWriter(Writer out)
字符缓冲流特有方法

字符缓冲流的使用方法和字节缓冲流的方法基本一致,但字符缓冲流具有一些特有的方法。

  • BufferedReader:public String readLine():读一行数据。 读取到最后返回null。
  • BufferedWriter:public void newLine(): 换行,由系统属性定义符号。
字符缓冲流拷贝文件的标准代码

我们使用字符缓冲流和字节数组进行读写操作

public class 拷贝文件标准代码 {
    public static void main(String[] args) throws IOException {
        //记录开始时间
    	long start = System.currentTimeMillis();
        //1.创建字符缓冲输入流读文件对象
        BufferedReader br = new BufferedReader(new FileReader("1.txt"));
        //1.创建字符缓冲输出流读文件对象
        BufferedWriter bw = new BufferedWriter(new FileWriter("2.txt"));
        int len;
        char[] chars = new char[1024];
        while ((len = br.read(chars))!=-1){ //读数据
        	//写数据
            bw.write(chars,0,len);
        }
        br.close();
        bw.close();
        //记录结束时间
        long end = System.currentTimeMillis();
        System.out.println("缓冲流使用数组复制时间:"+(end - start)+" 毫秒");
    }
}
  • 46
    点赞
  • 114
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 34
    评论
很抱歉,作为文本AI助手,我无法绘制思维导图。但是,我可以为您提供一个简要的java IO流知识点总结。 Java IO流Java中用于处理输入和输出的机制。它提供了一种有效的方式来读取和写入数据,以及与文件、网络和其他设备进行交互。 Java IO流包括字节流和字符流两种类型。字节流以字节为单位进行操作,适用于处理二进制数据。而字符流以字符为单位进行操作,适用于处理文本数据。 常用的字节流包括InputStream和OutputStream类,用于读取和写入字节数据。常用的字符流包括Reader和Writer类,用于读取和写入字符数据。可以通过使用字节流和字符流的组合来实现不同类型数据的读写操作。 在Java IO流中,还有一些特殊的流,如缓冲流、转换流、对象流等。缓冲流提供了缓冲区来提高IO性能。转换流用于处理字符编码和解码。对象流用于对Java对象进行读写操作。 此外,Java IO流还包括一些常用的类和方法,如File类用于处理文件和目录,RandomAccessFile类用于对文件进行随机访问,FileInputStream和FileOutputStream类用于读写文件等。 通过组合和使用不同类型的流和类,您可以实现各种复杂的IO操作,如读写文件、网络通信、序列化对象等。 希望这个简要总结对您有所帮助。如果您有任何更具体的问题,请随时提问。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [万字长文+思维导图帮你梳理 Java IO 流,还学不会你来打我(值得收藏)](https://blog.csdn.net/a1405/article/details/116766237)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

熠熠98

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值