JAVA IO菜鸟速成 | 技术创作特训营第一期

2023-08-27 23:28:15 浏览数 (2)

选题思路

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

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

创作提纲

1.玩转IO四条基本原则

2.File类是什么

3.什么是IO

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

5.缓冲流

6.转换流

正文

1.四条基本原则

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

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

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

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

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

2.File类是什么

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

要注意的点:

代码语言:txt复制
               1.一个File对象代表硬盘中实际存在的一个文件或者目录。
代码语言:txt复制
               2.File类构造方法不会给你检验这个文件或文件夹是否真实存在,因此无论该路径下是否存在文件或者                         目录,都不影响File对象的创建。
代码语言:public class FileIs {复制
 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>

代码语言:java复制
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>

代码语言:java复制
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>

代码语言:java复制
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>

代码语言:java复制
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>

代码语言:java复制
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>

代码语言:java复制
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>

代码语言:java复制
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();
    }
}

0 人点赞