一文讲透Java面试必考点:IO流

Java大联盟

共 13343字,需浏览 27分钟

 ·

2023-09-08 05:30

     
     
  Java大联盟

  致力于最高效的Java学习

关注


         
         


     
     


       
       
原文链接
https://cloud.tencent.com/developer/article/2318311


选题思路

每当有小白学习JAVA基础的IO流时,总是一看就会,一写就废,就算学过后过段时间也会忘记,特别是在每次要用时,还得上度娘,这种现象其实就说明还是对IO流的理解深度不够。

所以今天将以下原则,关键点,还有逻辑明确,面试时徒手撸IO就不是梦。

创作提纲

1.玩转IO四条基本原则

2.File类是什么

3.什么是IO

4.字节流与字符流的爱恨情仇

5.缓冲流

6.转换流

1.四条基本原则

在动手撸代码前,了解需求是必要的,了解完分析实现思路,无论再怎么复杂按照以下四条思路来写准没错。

(1) 确定数据是数据源还是数据目的,就是说我们要将这些数据是从磁盘读出还是写入

(2) 确定你要操作的数据是文本还是字节,可以提高处理效率。

(3) 确定数据所在的设备。

(4) 确定有无读写效率上的需求,是否要使用到缓冲流,转换流等。

2.File类是什么

java.io.File IO操作中使用最频繁的类,也特别重要,它很好理解只是代表我们要操作的文件夹或者文件对象,但是File跟流无关,所以File类不能直接对文件数据进行读和写也就是输入和输出。

要注意的点:           

  1.一个File对象代表硬盘中实际存在的一个文件或者目录。      
2.File类构造方法不会给你检验这个文件或文件夹是否真实存在,因此无论该路径下是否存在文件或者目录,都不影响File对象的创建。
 public static void main(String[] args) {       //代表文件       File f = new File("c:\\aa\\bb.java");        //代表文件夹        File f1 = new File("c:\\aa");
}
}

3.什么是IO

可以简单理解为数据的流动,JAVA中的具体体现就是java.io包下的那些类用来对数据进行输入(读取数据)输出(写出数据),就是IO操作。

可以大致分为一下几类:

1.输入流:将数据从其他设备(如硬盘)上读取到内存上的流

2.输出流:把内存中的数据写到其他设备(也可以是硬盘)上的流。

3.字节流:以字节为最小单位,进行读写操作字节数据的流。

4.字符流:以字符为最小单位,进行读写操作字符数据的流。

根据以上分类可分成以下超级父类:字节输入流 InputStream,字节输出流 OutputStream,字符输入流 Reader,字符输出流 Writer。其他常用的类都是这些超类的子类。

重点:计算机中所有的文件数据不管是文本,音频视频还是图片,全都是保存为二进制的数据,所以都是一个又一个的字节,所以其实字节流可以传输任何的文件数据,(其实字符流的底层也是传输二进制数据,只是如果用字节流还要对照编码表去翻译,不然会乱码)。

4.字节流与字符流的爱恨情仇

字节输入流IputStream

<font color="red">基本方法功能:</font>

(1) public void close() :关闭此输入流并释放与此流相关联的任何系统资源。

(2)public abstract int read():从输入流读取数据的下一个字节。

(3) public int read(byte[] b):该方法返回的int值代表的是读取了多少个字节,读到几个返回几个,读取不到返回-1

FileInputStream类是文件输入流,从文件中读取字节,也是最常用的,继承inputStream

<font color="blue">构造方法:</font>(当你创建这个流对象时,如果你指定的路径下没有该文件,就会抛出FileNotFoundException异常)

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

2、 FileInputStream(String name):通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的路径名name命名。(推荐)

<font color="blue">常用方式:</font>

package io;
import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;
public class input2 { public static void main(String args[]){ FileInputStream inputStream = null; try { inputStream = new FileInputStream("a.txt");//创建流对象 int len = 0 ; byte[] bys = new byte[1024];//缓冲数组 while ((len = inputStream.read(bys)) != -1) {//循环读取数据 System.out.println(new String(bys,0,len)); } } catch (IOException e) { e.printStackTrace(); }finally { try { inputStream.close();//关闭流 } catch (IOException e) { e.printStackTrace(); } }
}}

字节输出流OutputStream

<font color="red">基本方法功能:</font>

(1) public void close() :关闭此输出流并释放与此流相关联的任何系统资源。

(2) public void flush() :刷新此输出流并强制任何缓冲的输出字节被写出。

(3 )public void write(byte[] b):将 b.length个字节从指定的字节数组写入此输出流。

(4) public void write(byte[] b, int off, int len) :从指定的字节数组写入 len字节,从偏移量 off开始输出到此输出流。也就是说从off个字节数开始读取一直到len个字节结束

(5) public abstract void write(int b) :将指定的字节输出流。

FileOutputStream类是文件输出流,将字节写入文件,也是最常用的,继承outputStream

<font color="blue">构造方法:</font>(当你创建这个流对象时,如果你指定的路径下没有该文件,就会自动给你新建一个)

1、 public FileOutputStream(File file):根据File对象为参数创建对象。

2、 public FileOutputStream(String name):根据名称字符串为参数创建对象。(推荐)

<font color="blue">常用方式:</font>

public class FOSWrite {    public static void main(String[] args) throws IOException {        // 使用文件名称创建流对象        FileOutputStream fos = new FileOutputStream("a.txt");             // 字符串转换为字节数组        byte[] b = "可恶的老六".getBytes();        // 写出字节数组数据        fos.write(b);        // 关闭资源        fos.close();    }}输出结果:可恶的老六

字符输入流Reader

<font color="red">基本方法功能:</font>

(1)public void close() :关闭此流并释放与此流相关联的任何系统资源。

(2) public int read():从输入流读取一个字符。

(3) public int read(char[] cbuf):从输入流中读取一些字符,并将它们存储到字符数组 cbuf中

FileReader类是读取字符文件的便利类。构造时使用系统默认的字符编码和默认字节缓冲区。

<font color="blue">构造方法:</font>

1、FileReader(File file):创建一个新的 FileReader ,给定要读取的File对象

2、 FileReader(String fileName):创建一个新的 FileReader ,给定要读取的文件的字符串名称

<font color="blue">常用方式:</font>

public class FRRead {    public static void main(String[] args) throws IOException {        // 使用文件名称创建流对象         FileReader fr = new FileReader("a.txt");        // 定义变量,保存数据        int b ;// 循环读取        while ((b = fr.read())!=-1) {            System.out.println((char)b);        }    // 关闭资源        fr.close();    }}

字符输出流 Writer

<font color="red">基本方法功能:</font>

(1)void write(int c) 写入单个字符。

(2)void write(char[] cbuf)写入字符数组。

(3) abstract void write(char[] cbuf, int off, int len)写入字符数组的某一部分,off数组的开始索引,len写的字符个数。

(4) void write(String str)写入字符串。

(5)void write(String str, int off, int len) 写入字符串的某一部分,off字符串的开始索引,len写的字符个数。

(6)void flush()刷新该流的缓冲。

(7)void close() 关闭此流,但要先刷新它。

FileWriter类是写出字符到文件的便利类。构造时使用系统默认的字符编码和默认字节缓冲区。

<font color="blue">构造方法:</font>

1、 FileWriter(File file):创建一个新的 FileWriter,给定要读取的File对象。

2、FileWriter(String fileName):创建一个新的 FileWriter,给定要读取的文件的名称。

<font color="blue">常用方式:</font>

public class FlushDemo {    public static void main(String[] args) throws Exception {        //源   也就是输入流【读取流】 读取a.txt文件        FileReader fr=new FileReader("a.txt");  //必须要存在a.txt文件,否则报FileNotFoundException异常        //目的地  也就是输出流        FileWriter fw=new FileWriter("b.txt");  //没有会自动创建b.txt,        int len;        while((len=fr.read())!=-1){           fw.write(len);        }     fr.close();     fw.flush();     fw.close();
}}

<font color="red">【注意】:</font>关闭资源时,与FileOutputStream不同。仔细看这里的close()方法,并没有进行刷新,所以要先使用flush()方法刷新缓存,再用close()方法关闭流对象。

5.缓冲流

缓冲流也叫高效是对以上四个流的效率增强流。

  • 字节缓冲流BufferedInputStreamBufferedOutputStream

  • 字符缓冲流BufferedReaderBufferedWriter

  • <font color="red">基本原理:</font>

  • 1、使用了底层流对象从具体设备上获取数据,并将数据存储到缓冲区的数组内。

  • 2、通过缓冲区的read()方法从缓冲区获取具体的字符数据,这样就提高了效率。

  • 3、如果用read方法读取字符数据,并存储到另一个容器中,直到读取到了换行符时,将另一个容器临时存储的数据转成字符串返回,就形成了readLine()功能。

  • <font color="blue">构造方法:</font>

  • BufferedInputStream(InputStream in) :创建一个新的缓冲输入流,注意参数类型为InputStream

  • BufferedOutputStream(OutputStream out):创建一个新的缓冲输出流,注意参数类型为OutputStream

  • public BufferedReader(Reader in) :创建一个新的缓冲输入流,注意参数类型为Reader

  • public BufferedWriter(Writer out):创建一个新的缓冲输出流,注意参数类型为Writer

    <font color="blue">常用方式:</font>

    public class BufferedTest {    public static void main(String[] args) throws IOException {                HashMap<String, String> map = new HashMap<>();
    // 创建流对象 源 BufferedReader br = new BufferedReader(new FileReader("a.txt")); //目标 BufferedWriter bw = new BufferedWriter(new FileWriter("b.txt"));
    // 读取数据 String line = null; while ((line = br.readLine())!=null) { // 解析文本 String[] split = line.split("\\."); // 保存到集合 map.put(split[0],split[1]); } // 释放资源 br.close();
    // 遍历map集合 for (int i = 1; i <= map.size(); i++) { String key = String.valueOf(i); // 获取map中文本 String value = map.get(key); // 写出拼接文本 bw.write(key+"."+value); // 写出换行 bw.newLine(); } // 释放资源 bw.close();    }}
  • 6.转换流

  • 先了解字符编码跟字符集这两个概念

  • 编码解码:计算机中储存的信息都是用二进制数表示的,而我们在屏幕上看到的数字、英文、标点符号、汉字等字符是二进制数转换之后的结果。按照某种规则,将字符存储到计算机中,称为编码 。同样的道理有编码就有解码,就是把这些二进制数据按照一定的规则解析成我们能看懂的东西。

  • 字符集:也叫编码表。是一个系统支持的所有字符的集合,包括各国家文字、标点符号、图形符号、数字等这些包含各种各样规则的集合。(万国语翻译器)

  • <font color="red">基本原理:</font>字符流=字节流+编码表

  • InputStreamReader类(字节流到字符流转换)

    <font color="blue">构造方法:</font>

    InputStreamReader(InputStream in): 创建一个使用默认字符集的字符流。

    InputStreamReader(InputStream in, String charsetName): 创建一个指定字符集的字符流。

  • <font color="blue">常用方式:</font>

    public class ReaderDemo2 {    public static void main(String[] args) throws IOException {        // 定义文件路径,文件为gbk编码        String FileName = "C:\\a.txt";        // 创建流对象,默认UTF8编码        InputStreamReader isr = new InputStreamReader(new FileInputStream(FileName));        // 创建流对象,指定GBK编码        InputStreamReader isr2 = new InputStreamReader(new FileInputStream(FileName) , "GBK");    // 定义变量,保存字符        int read;        // 使用默认编码字符流读取,乱码        while ((read = isr.read()) != -1) {            System.out.print((char)read); // �����ʺ              }        isr.close();              // 使用指定编码字符流读取,正常解析        while ((read = isr2.read()) != -1) {            System.out.print((char)read);        }        isr2.close();    }}
  • OutputStreamWriter类(字符流到字节流转换)
  • <font color="blue">构造方法:</font>

  • OutputStreamWriter(OutputStream in): 创建一个使用默认字符集的字符流。

  • OutputStreamWriter(OutputStream in, String charsetName): 创建一个指定字符集的字符流。

  • <font color="blue">常用方式:</font>


    public class OutputDemo {    public static void main(String[] args) throws IOException {        // 定义文件路径        String FileName = "C:\\s.txt";        // 创建流对象,默认UTF8编码        OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(FileName));        // 写出数据        osw.write("老六"); // 保存为6个字节        osw.close();            // 定义文件路径    String FileName2 = "C:\\a.txt";       // 创建流对象,指定GBK编码        OutputStreamWriter osw2 = new OutputStreamWriter(new FileOutputStream(FileName2),"GBK");        // 写出数据        osw2.write("受死");// 保存为4个字节        osw2.close();    }}

浏览 648
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报