IO流概述

IO流的概述和分类

输入流:把硬盘上的数据读取到内存中

  • 字符输入流:读取字符
  • 字节输入流:读取字节

输出流:把内存中的数据写入到硬盘中

  • 字符输出流:写入字符

  • 字节输出流:写入字节

字符流和字节流的区别

  • 字节流读取的和写入都是字节字符流读取的和写入的都是字符

  • 使用字节流可以读写任意的文件,所有的数据(文本,音乐,视频,图片…),都是以字节的方式存储的

  • 使用字节流读取的文件中若包含中文,因一次只读写一个字节(1/2 GBK,1/3 UTF-8 个中文),使用起来不方便,可能会出现乱码

  • 使用字符流读取含有中文文本文件,一次读取一个字符(中文,英文,数字,符号…),使用起来很方便

    什么时候使用字符流:读写文本文件(使用记事本打开能看懂)

    什么时候使用字节流:读写非文本文件(图片,视频,音频…)

关闭和刷新的区别

  • flush:把内存缓冲区中的数据刷新到文件中,刷新完之后,流对象可以继续使用

  • close:释放资源(释放流相关的所有的系统资源和流对象),在释放资源之前,会把内存缓冲区中的数据刷新到文件中刷新完之后,流对象就已经关闭了,就不能在使用了

import java.io.FileWriter;
import java.io.IOException;public class Demo02Writer {public static void main(String[] args) throws IOException {FileWriter fw = new FileWriter("day21\\e.txt");fw.write(66);    // Bfw.flush();     // 把内存缓冲区中的数据刷新到文件中,刷新完之后,流对象可以继续使用fw.write(67);  // Cfw.close();     // 在释放资源之前,把内存缓冲区中的数据刷新到文件中,刷新完之后,流对象就已经关闭了,就不能在使用了fw.write(68);   // IOException: Stream closed}
}

IO流的异常处理(JDK7后)

自动释放资源,不用再手动释放资源

格式:

try(// 定义流对象AAA aaa = new AAA();BBB bbb = new BBB();
){可能产生异常的代码aaa.read();bbb.write();
}catch(定义一个异常相关的变量,接收异常对象){异常的处理逻辑
}

注意:

  • 在 try 的后边增加一个(),在()中定义流对象那么这些流对象的作用域,就只在 try 中有效,执行完 try 中的代码,会自动释放流对象省略 finally

  • 注意 try 后边的小括号中,不是任意对象都可以放,只有实现了 Closeable 接口的对象才能放

import java.io.*;
import java.util.Date;public class Demo02JDK7After {public static void main(String[] args) {try(//定义流对象FileWriter fw = new FileWriter(new File("day21\\1.txt"), true);){for (int i = 1; i <= 10; i++) {fw.write("你猜猜,我能写入到文件中吗?\r\n");} catch(IOException e) {e.printStackTrace();}try(FileInputStream fis = new FileInputStream("c:\\2.jpg");FileOutputStream fos = new FileOutputStream("d:\\2.jpg");){byte[] bytes = new byte[1024];int len = 0;while ((len = fis.read(bytes)) != -1){fos.write(bytes, 0, len);}}catch (IOException e) {e.printStackTrace();}}
}

字节流

InputStream:字节输入流超类

java.io.InputStream:字节输入流(此抽象类是表示字节输入流的所有类的超类)

InputStream 里边定义了所有字节输入流中共性的成员方法,所有的字节输入流都可以使用这些方法共性的成员方法:

int read()           // 从输入流中读取数据的下一个字节。
int read(byte[] b)  // 从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。
/*  1.read方法的参数byte[]字节数组的作用:起到缓冲作用,把读取到的字节依次存储到数组中把数组一次性的由操作系统返回JVM,由JVM返回给java程序,效率高数组的长度一般都定义为1024或者1024的整数倍2.read方法的返回值int是什么?每次读取的有效字节个数。int=-1 表示读取结束。
*/
void close()        // 关闭此输入流并释放与该流关联的所有系统资源。

OutputStream:字节输出流超类

java.io.OutputStream:字节输出流(此抽象类是表示输出字节流的所有类的超类)

OutputStream 里边定义了所有字节输出流中共性的成员方法,所有的字节输出流都可以使用共性的成员方法:

public void close()          // 关闭此输出流并释放与此流相关联的任何系统资源。
public void flush()             // 刷新此输出流并强制任何缓冲的输出字节被写出。
public void write(int b)        // 将指定的字节输出流。
public void write(byte[] b)     // 将 b.length字节从指定的字节数组写入此输出流。
public void write(byte[] b, int off, int len)   // 从指定的字节数组写入 len个字节,从偏移量 off开始输出到此输出流。

FileInputStream:文件字节输入流

java.io.FileInputStream extends InputStream

作用:把文件中的数据,以字节的方式读取到内存中

构造方法:

public FileInputStream(String name)
public FileInputStream(File file)
/* 参数:传递要读取的数据源String name:要读取的数据源是一个文件的路径File file:要读取的数据源是一个文件
*/

构造方法的作用:

​ 1.会创建FileInputStream对象

​ 2.会把创建好的FileInputStream对象,指向要读取文件的第一个字节

注意:使用构造方法创建对象,如果要读取的文件不存在,不会创建文件,会抛出文件找不到异常

使用字节输入流读取文件到内存中底层原理:

​ java程序 ==> JVM ==> 操作系统 ==> 调用系统中读取文件的方法 ==> 读取文件

使用示例

字节输入流的使用步骤:

​ 1.创建FileInputStream对象,构造方法中绑定要读取的数据源

​ 2.使用FileInputStream对象中的方法read,以字节的方式读取文件

​ 3.释放资源

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Arrays;public class Demo01InputStream {public static void main(String[] args) throws IOException {/* 基本使用 *///1.创建FileInputStream对象,构造方法中绑定要读取的数据源FileInputStream fis = new FileInputStream("day21\\a.txt");//2.使用FileInputStream对象中的方法read,以字节的方式读取文件//int read() 从文件中一次读取一个字节并返回/*读取文件是一个重复的过程,所以可以使用循环优化不知道文件中有多少字节,不知道循环多少次,使用while循环循环结束的条件,read方法读取到-1的时候结束循环中的布尔表达式:((len=fis.read()) != -1)1.fis.read():读取文件中的一个字节2.len = fis.read():把读取到的字节赋值给变量len3.(len = fis.read()) != -1:判断变量len的值是否为-1len不是-1就执行循环体,打印len(读取到的字节)len是-1结束循环*/int len = 0;while ((len=fis.read()) != -1){System.out.print((char)len);}//3.释放资源fis.close();/* 使用字节输入流一次读取多个字节 */FileInputStream fis = new FileInputStream("day21\\b.txt");byte[] bytes = new byte[1024];int len = 0;while ((len = fis.read(bytes)) != -1){//System.out.println(Arrays.toString(bytes));//System.out.println(len);//5 读取的有效字节个数System.out.println(new String(bytes, 0, len));}fis.close();}
}

FileOutputStream:文件字节输出流

java.io.FileOutputStream extends OutputStream

作用:把内存中的字节写入到硬盘的文件中保存

构造方法:

public FileOutputStream(File file)
public FileOutputStream(String name)
/* 参数:输出的目的地String name:输出的目的地就是一个文件路径File file:输出的目的地就是一个文件
*/// 字节输出流的续写和换行
public FileOutputStream(File file, boolean append)
public FileOutputStream(String name, boolean append)
/* 参数:File file|String name:写入数据的目的地boolean append:续写的开关true:可以续写,使用构造方法创建对象,文件名相同,不会创建新的文件覆盖之前同名的文件,会继续往文件的末尾写数据false:不可以续写,使用构造方法创建对象,文件名相同,会创建一个新的空白文件覆盖之前同名的文件,在新的文件中写数据换行:使用换行符号Windows系统里,每行结尾是 回车+换行 ,即 \r\nlinux,Unix系统里,每行结尾只有 换行 ,即 \nMac系统里,每行结尾是 回车 ,即 \r 。从 Mac OS X开始与Linux统一。
*/

构造方法的作用:

​ 1.会创建FileOutputStream对象

​ 2.会根据构造方法中传递的文件路径|文件,创建一个新的空白文件

​ 3.会把FileOutputStream对象,指向创建好的文件,就可以往文件中写数据了

使用字节输出流往文件中写输出的底层过程:

​ java程序 ==> JVM ==> 操作系统(OS) ==> 调用系统中写数据的方法 ==> 把数据写入到文件中

使用示例

字节输出流的基本使用:

​ 1.创建FileOutputStream对象,构造方法绑定要输出的目的地

​ 2.使用FileOutputStream对象中的方法write,把数据写入到文件中

​ 3.释放资源(关闭此文件输出流并释放与此流有关的所有系统资源)

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;public class Demo01OutputStream {public static void main(String[] args) throws IOException {/* 基本使用*///1.创建FileOutputStream对象,构造方法绑定要输出的目的地FileOutputStream fos = new FileOutputStream("day20\\1.txt");//2.使用FileOutputStream对象中的方法write,把数据写入到文件中fos.write(97);//3.释放资源(关闭此文件输出流并释放与此流有关的所有系统资源)fos.close();/* 字节输出流中写多个字节的方法 */FileOutputStream fos = new FileOutputStream(new File("day20\\2.txt"));// public void write(byte[] b) 一次把字节数组中所有的字节写入到文件中byte[] bytes = {65, 66, 67, 68, 69, 70};fos.write(bytes);   //ABCDEF/*public void write(byte[] b, int off, int len) 一次把字节数组的一部分写入到文件中int off:数组的开始索引,从哪个索引开始写int len:写的字节个数*/fos.write(bytes, 2, 3);    //CDE// 把字符串转换为字节数组,写入到文件中byte[] bytes2 = "中国".getBytes();//IDEA默认使用UTF-8编码,1个中文占用3个字节 [-28, -72, -83, -27, -101, -67]System.out.println(Arrays.toString(bytes2));fos.write(bytes2);//中国fos.close();/* 字节输出流的续写和换行*/FileOutputStream fos = new FileOutputStream("day20\\3.txt", true);for (int i = 1; i <=10 ; i++) {fos.write(("你好" + i + "\r\n").getBytes());}fos.close();}
}

字符流

编码表

**编码:**把能看懂的文字,转换为看不懂的文字(字符 ==> 字节)

**解码:**把看不懂的文字,转换为能看懂的文字(字节 ==> 字符)

**编码表:**就是生活中的文字和计算机中文字的对应关系表

  • a ==> 97 ==> 01100001 ==> 存储到计算机中

  • 中 ==> 20013 ==> ‭0010000000001011‬ ==> 存储到计算机中

常用的编码表:

  • ASCII字符集 :英文,数字,标点符号和计算机中文字的对应关系

    0 ==> 48 A ==> 65 a ==> 97

  • ISO-8859-1字符集:拉丁码表

    拉丁码表,别名Latin-1,用于显示欧洲使用的语言,包括荷兰、丹麦、德语、意大利语、西班牙语等。

    • ISO-8859-1 使用单字节编码,兼容ASCII编码。不支持中文
  • GBxxx字符集:国标

    GB 就是国标的意思,是为了显示中文而设计的一套字符集。兼容ASCII表

    • GB2312:简体中文码表。 7000多个简体汉字

    • GBK目前操作系统默认中文码表(简体,繁体),存储一个中文使用2个字节,21003个汉字

    • GB18030:最新的中文码表。包含的文字最全(简体,繁体,少数民族,日韩文字)

  • Unicode字符集 :万国码

    • UTF-8:最常用的万国表,兼容所有国家的文字

      编码规则:

      • 128个US-ASCII字符,只需一个字节编码。
      • 拉丁文等字符,需要二个字节编码。
      • 大部分常用字(含中文),使用三个字节编码。
      • 其他极少使用的Unicode辅助字符,使用四字节编码。

Reader:字符输入流超类

java.io.Reader:字符输入流(用于读取字符流的抽象类)

是所有字符输入流最顶层的父类,里边定义了所有字符输入流共性的成员方法,所有的字符输入流都可以使用共性的成员方法:

int read()               // 读取单个字符。
int read(char[] cbuf)   // 将字符读入数组。
void close()            // 关闭该流并释放与之关联的所有资源。

Writer:字符输出流超类

java.io.Writer:字符输出流( 写入字符流的抽象类)

是所有字符输出流最顶层的父类,里边定义了所有字符输出流中共性的成员方法,所有字符输出流都可以使用共性的成员方法:

abstract void close()    // 关闭此输出流并释放与此流相关联的任何系统资源
abstract void flush()   // 刷新此输出流并强制任何缓冲的输出字符被写出void write(int c)       // 写出一个字符
void write(char[] cbuf)     // 将 b.length字符从指定的字符数组写出此输出流
void write(char[] b, int off, int len) // 从指定的字符数组写出len字符,从偏移量off开始输出到此输出流
void write(String str)  // 写出一个字符串
void write(String str, int off, int len)    // 写入字符串的某一部分

InputStreamReader:字符转换输入流

java.io.InputStreamReader extends Reader

作用:InputStreamReader 是字节流通向字符流的桥梁:它使用指定的 charset 读取字节并将其解码为字符。

解码:字节==>字符

构造方法:

public InputStreamReader(InputStream in) // 创建一个使用默认字符集的 InputStreamReader
public InputStreamReader(InputStream in, String charsetName) // 创建使用指定字符集的 InputStreamReader
/* 参数:InputStream in:传递字节输入流,可以传递InputStream的任意的子类对象(读取文件中的字节)String charsetName:传递编码表名称,不区分大小写的可以传递GBK(gbk),UTF-8(utf-8)...,不写默认使用IDEA设置的编码(UTF-8)
*/

继续自父类的共性成员方法:

int read()               // 读取单个字符。
int read(char[] cbuf)   // 将字符读入数组。
void close()            // 关闭该流并释放与之关联的所有资源。

OutputStreamWriter:字符转换输出流

java.io.OutputStreamWriter extends Writer

作用:OutputStreamWriter 是字符流通向字节流的桥梁:可使用指定的 charset 将要写入流中的字符编码成字节。

编码:字符 ==> 字节

构造方法:

public OutputStreamWriter(OutputStream out)      // 创建使用默认字符编码的 OutputStreamWriter。
public OutputStreamWriter(OutputStream out, String charsetName) // 创建使用指定字符集的 OutputStreamWriter。
/* 参数:OutputStream out:传递字节输出流,可以传递OutputStream的任意子类对象(把字符转换之后的字节写入到文件中)String charsetName:传递编码表名称,不区分大小写的可以传递GBK(gbk),UTF-8(utf-8)...,不写默认使用IDEA设置的编码(UTF-8)
*/

继承自父类共性的成员方法:

public abstract void close()     // 关闭此输出流并释放与此流相关联的任何系统资源。
public abstract void flush()    // 刷新此输出流并强制任何缓冲的输出字符被写出。public void write(int c)       // 写出一个字符。
public void write(char[] cbuf)  // 将 b.length字符从指定的字符数组写出此输出流。
public abstract void write(char[] b, int off, int len) // 从指定的字符数组写出len字符,从偏移量off开始输出到此输出流
public void write(String str)   // 写出一个字符串
public void write(String str, int off, int len)         // 写入字符串的某一部分。

FileReader:文件字符输入流便捷类

java.io.FileReader extends InputStreamReader(转换流) extends Reader

作用:把文件中的数据以字符的方式读取到内存中

构造方法:

public FileReader(String fileName)
public FileReader(File file)
/* 参数:传递要读取的数据源String fileName:数据源就是一个文件路径File file:数据源就是一个文件
*/

使用示例

使用字符输入流读取文件的步骤

​ 1.创建FileReader对象,构造方法中绑定要读取的数据源

​ 2.使用FileReader对象中的方法read,以字符的方式读取文件

​ 3.释放资源

Stirng类的构造方法:

public String(char[] value)      // 把字符数组转换为字符串
public String(char[] value, int offset, int count)      // 把字符数组的一部分转换为字符串
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;public class Demo02Reader {public static void main(String[] args) throws IOException {/* 基本使用 *///1.创建FileReader对象,构造方法中绑定要读取的数据源FileReader fr = new FileReader("day21\\c.txt");//2.使用FileReader对象中的方法read,以字符的方式读取文件//int read() 一次读取一个字符并返回/*int len = 0;while ((len = fr.read()) != -1){System.out.print((char)len);}*///int read(char[] cbuf) 使用数组缓冲一次读取多个字符char[] chars = new char[1024];int len =0;while ((len = fr.read(chars)) != -1){System.out.println(new String(chars, 0, len));}//3.释放资源fr.close();}
}

FileWriter:文件字符输出流便捷类

java.io.FileWriter extends OutputStreamWriter(转换流) extends Writer

作用:把内存中的数据,以字符的方式写入到文件中

构造方法:

public FileWriter(File file)
public FileWriter(String fileName)
/* 参数:传递写入的目的地String fileName:目的地是一个文件的路径File file:目的地是一个文件
*/public FileWriter(String fileName, boolean append)
public FileWriter(File file, boolean append)
/* 参数:File file|String fileName:写入数据的目的地boolean append:续写的开关true:可以续写,使用构造方法创建对象,文件名相同,不会创建新的文件覆盖之前同名的文件,会继续往文件的末尾写数据false:不可以续写,使用构造方法创建对象,文件名相同,会创建一个新的空白文件覆盖之前同名的文件,在新的文件中写数据换行:使用换行符号Windows系统里,每行结尾是 回车 + 换行 ,即 \r\nlinux,Unix系统里,每行结尾只有 换行 ,即 \nMac系统里,每行结尾是 回车 ,即 \r 。从 Mac OS X开始与Linux统一
*/

一个参数构造方法的作用:

​ 1.会创建FileWriter对象

​ 2.会根据构造方法中传递的文件|文件的路径,创建一个新的空白的文件

​ 3.会把FileWriter对象,执向空白的文件

使用示例

使用字符输出流基本步骤:

​ 1.创建FileWriter对象,构造方法中绑定要写入的目的地

​ 2.使用FileWriter对象中的方法write,把数据写入到内存缓冲区中

​ 3.使用FileWriter对象中的方法flush,把内存缓冲区中的数据刷新到文件中

​ 4.释放资源(close方法会自动调用flush,把内存缓冲区中的数据刷新到文件中,再释放资源)

import java.io.FileWriter;
import java.io.IOException;public class Demo01Writer {public static void main(String[] args) throws IOException {/* 基本使用 */// 1.创建FileWriter对象,构造方法中绑定要写入的目的地FileWriter fw = new FileWriter("day21\\d.txt");// 2.使用FileWriter对象中的方法write,把数据写入到内存缓冲区中// void write(int c):写出一个字符fw.write(100);fw.write('中'); // 中// void write(char[] cbuf) : 写字符数组中的多个字符char[] chars = {'a','b','c','1','2','3','中','国','@','#'};fw.write(chars); // abc123中国@#// abstract void write(char[] b, int off, int len):写字符数组的一部分字符;off数组的开始索引,len写的字符个数fw.write(chars, 6, 2); //中国// void write(String str) :写出一个字符串fw.write("到中午了,我们该吃饭了");// void write(String str, int off, int len):写入字符串的某一部分。off字符串的开始索引,len写的字符个数fw.write("到中午了,我们该吃饭了", 5, 6);//我们该吃饭了// 3.使用FileWriter对象中的方法flush,把内存缓冲区中的数据刷新到文件中//fw.flush();// 4.释放资源(close方法会自动调用flush,把内存缓冲区中的数据刷新到文件中,再释放资源)fw.close();/* 字符输出流的续写和换行 */FileWriter fw = new FileWriter(new File("day21\\g.txt"), true);for (int i = 1; i <= 10; i++) {fw.write("hello" + i + "\r\n");}fw.close();}
}

字符转换流和读写便捷类的区别

  • 字符转换流 InputStreamReader 和 OutputStreamWriter 可以指定编码,缺省 ufs-8 编码

  • 字符读写便捷类 FileReader 和 FileWriter 不能指定编码,默认 utf-8 编码

    使用 FileReader 读取 GBK 编码的文件:会出现乱码,编码和解码不一致导致。

    FileReader 只能读取默认编码(UTF-8 编码)的文件

    • GBK:采用的双字节编码,一个中文占用2个字节
    • UTF-8:采用多字节编码,一个中文占用3个字节

缓冲流

概述

文件字节流(FileInputStream、FileOutputStream)和文件字符流(FileReader、FileWriter)这些都是计算机与硬盘之间发生的I/O 操作,基于硬盘的读写相对比较慢,读写操作收到了硬盘读取速度的限制。为了能够提高读写速度,一定程度上绕过硬盘的限制,Java提供了一种缓冲流来实现。

缓冲字节流(BufferedInputStream、BufferedOutputStream)和缓冲字符流(BufferedReader、BufferedWriter)就是先把数据缓冲在内存里,在内存中去做 IO 操作。基于内存的 IO 操作比基于硬盘的 IO 操作快很多。

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

BufferedInputStream:字节缓冲输入流

java.io.BufferedInputStream extends InputStream

构造方法:

public BufferedInputStream(InputStream in)               // 创建一个具有默认缓冲区大小的BufferedInputStream对象
public BufferedInputStream(InputStream in, int size)    // 创建具有指定缓冲区大小的 BufferedInputStream对象
/*参数:InputStream in:传递字节输入流,可以传递InputStream的任意子类对象可以传递FileInputStream对象,缓冲流就会给FileInputStream对象增加一个缓冲区(字节数组)提高FileInputStream读取文件的效率int size:指定缓冲区的大小(数组的长度),不写使用默认值(KB)private static int DEFAULT_BUFFER_SIZE = 8192;

继承自父类共性的成员方法:

int read()           // 一次读取一个字节并返回
int read(byte[] b)  // 使用数组缓冲,一次读取多个字节
void close()        // 关闭此输入流并释放与该流关联的所有系统资源。

使用示例

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;public class Demo01BufferedInputStream {public static void main(String[] args) throws IOException {try(//1.创建BufferedInputStream对象,构造方法中传递FileInputStream对象BufferedInputStream bis = new BufferedInputStream(new FileInputStream("day22\\1.txt"));){//2.使用BufferedInputStream对象中的方法read,以字节的方式读取文件//int read(byte[] b) 使用数组缓冲,一次读取多个字节byte[] bytes = new byte[1024];int len = 0;while ((len = bis.read(bytes)) ! =-1){System.out.println(new String(bytes, 0, len));}} catch (IOException e) {e.printStackTrace();}}
}

BufferedOutputStream:字节缓冲输出流

java.io.BufferedOutputStream extends OutputStream

构造方法:

public BufferedOutputStream(OutputStream out)                // 创建一个新的缓冲输出流,具有默认缓冲区大小
public BufferedOutputStream(OutputStream out, int size)     // 创建一个新的缓冲输出流,具有指定缓冲区大小
/* 参数:OutputStream out:传递字节输出流,可以传递OutputStream的任意子类对象我们可以传递FileOutputStream对象,缓冲流就会给FileOutputStream对象增加一个缓冲区(字节数组)提高FileOutputStream读取文件的效率int size:指定缓冲区的大小(数组的长度),不写使用默认值
*/

继承自父类的共性成员方法:

public void close()          // 关闭此输出流并释放与此流相关联的任何系统资源
public void flush()             // 刷新此输出流并强制任何缓冲的输出字节被写出public void write(byte[] b)     // 将 b.length字节从指定的字节数组写入此输出流
public void write(byte[] b, int off, int len)   // 从指定的字节数组写入 len字节,从偏移量 off开始输出到此输出流
public abstract void write(int b)               // 将指定的字节输出流

使用示例

import java.io.BufferedOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;public class Demo02BufferedOutputStream {public static void main(String[] args) throws IOException {      try(//1.创建BufferedOutputStream对象,构造方法中传递FileOutputStream对象BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("day22\\2.txt"));){//2.使用BufferedOutputStream对象中的方法write,把数据写入到内存缓冲区中bos.write("你好".getBytes());//3.使用BufferedOutputStream对象中的方法flush,把内存缓冲区中数据刷新到文件bos.flush();//4.释放资源(会先调用flush方法刷新数据到文件)} catch (IOException e) {e.printStackTrace();}}
}

BufferedReader:字符缓冲输入流

java.io.BufferedReader extends Reader

构造方法:

public BufferedReader(Reader in)             // 创建一个使用默认大小输入缓冲区的缓冲字符输入流。
public BufferedReader(Reader in, int sz)    // 创建一个使用指定大小输入缓冲区的缓冲字符输入流。
/* 参数:Reader in:传递字符输入流,可以传递Reader的任意的子类对象我们可以FileReader,缓冲流就会给FileReader增加一个缓冲区提高FileReader读取文件的效率int sz:指定缓冲区的大小(数组长度),不指定使用默认值
*/

继承自父类的共性成员方法:

int read()               // 读取单个字符。
int read(char[] cbuf)   // 将字符读入数组。
void close()            // 关闭该流并释放与之关联的所有资源。

特有的成员方法:

String readLine()        // 读取一个文本行。一次可以读取一行数据
/*  通过下列字符之一即可认为某行已终止:换行 ('\n')、回车 ('\r') 或回车后直接跟着换行(\r\n)。返回:包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回 null

使用示例

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;public class Demo04BufferedReader {public static void main(String[] args) throws IOException {try(//1.创建BufferedReader对象,构造方法中传递FileReader对象BufferedReader br = new BufferedReader(new FileReader("day22\\3.txt"));){//2.使用BufferedReader对象中的方法read|readLine,以字符的方式读取文件//String readLine() 读取一个文本行。一次可以读取一行数据//注意:读取的文件中有null,仅仅是一个字符串"null",不是默认值nullString line;while ((line = br.readLine()) != null){System.out.println(line);    //你好1你好2你好3 不会读取每行结尾的回车换行符号(行的终止符号)}} catch (IOException e) {e.printStackTrace();}}
}

BufferedWriter:字符缓冲输出流

java.io.BufferedWriter extends Writer

构造方法:

public BufferedWriter(Writer out)            // 创建一个使用默认大小输出缓冲区的缓冲字符输出流。
public BufferedWriter(Writer out, int sz)  // 创建一个使用给定大小输出缓冲区的新缓冲字符输出流
/* 参数:Writer out:传递字符输出流,可以传递Writer的任意的子类对象我们可以传FileWriter,缓冲流就会给FileWriter增加一个缓冲区提高FileWriter写入文件的效率int sz:指定缓冲区的大小(数组长度),不指定使用默认值
*/

继承自父类共性的成员方法:

abstract void close()        // 关闭此输出流并释放与此流相关联的任何系统资源
abstract void flush()       // 刷新此输出流并强制任何缓冲的输出字符被写出void write(int c)           // 写出一个字符
void write(char[] cbuf)     // 将 b.length字符从指定的字符数组写出此输出流
abstract void write(char[] b, int off, int len) // 从指定的字符数组写出 len字符,从偏移量 off开始输出到此输出流
void write(String str)  // 写出一个字符串
void write(String str, int off, int len)        // 写入字符串的某一部分

特有的成员方法:

void newLine()   // 写入一个行分隔符。写一个换行符号,根据系统不同,而写不同的换行符号
/* Windows系统里,每行结尾是 回车+换行 ,即 \r\nlinux,Unix系统里,每行结尾只有 换行 ,即 \nMac系统里,每行结尾是 回车 ,即 \r 。从 Mac OS X开始与Linux统一。
*/

使用示例

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;public class Demo05BufferedWriter {public static void main(String[] args) throws IOException {try(//1.创建BufferedWriter对象,构造方法中传递FileWriter对象BufferedWriter bw = new BufferedWriter(new FileWriter("day22\\4.txt",true));){//2.使用BufferedWriter对象中的方法write,把数据写入到内存缓冲区中for (int i = 1; i <= 10; i++) {bw.write("你好"+i);bw.newLine();//写换行}//3.使用BufferedWriter对象中的方法flush,把内存缓冲区中的数据刷新到文件中bw.flush();} catch (IOException e) {e.printStackTrace();}}
}

打印流

概述、异同

虽然像 FileOutputStream、OutputStreamWriter 这些输出流可以输出信息,但是其会要求把数据先处理为字符串或字节数组,使用不便。为此在 Java IO 体系专门提供了两个打印流——PrintStream 字节打印流 、PrintWriter 字符打印流。二者均重载了print、println 等函数,方便开发者直接输出打印其它类型的数据

PrintStream 类和 PrintWriter 类的功能基本相同,PrintStream 能做的 PrintWriter 也都能实现,并且 PrintWriter 的功能更为强大。但由于 PrintWriter 出现的比较晚,较早的 System.out 使用的是 PrintStream 来实现的,所以为了兼容就没有废弃 PrintStream。

PrintStream 类和 PrintWriter 类最大的差别是:

  • PrintStream 在输出字符,将字符转换为字节时采用的是系统默认的编码格式,这样当数据传输另一个平台,而另一个平台使用另外一个编码格式解码时就会出现问题,存在不可控因素。
  • PrintWriter 可以在传入 Writer【OutputStreamWriter(OutputStream out, String charsetName)】时可由程序员指定字符转换为字节时的编码格式,兼容性和可控性会更好。

PrintStream:字节打印流

java.io.PrintStream extends OutputStream

特点:

  • PrintStream 为其他输出流添加了功能,使它们能够方便地打印各种数据值表示形式。

    PrintStream流中有两个特有的方法:print,println

  • 与其他输出流不同,PrintStream 永远不会抛出 IOException,创建对象的时候,传递路径不存在,可能会抛出文件找不到异常

  • PrintStream叫打印流,只负责输出(打印),不能读取

构造方法:

public PrintStream(File file)            // 打印流的目的地是一个文件
public PrintStream(OutputStream out)    // 打印流的目的地是一个字节输出流
public PrintStream(String fileName)     // 打印流的目的地是一个文件路径

成员方法:

void close()             // 关闭此输出流并释放与此流相关联的任何系统资源
void flush()            // 刷新此输出流并强制任何缓冲的输出字节被写出
void write(byte[] b)    // 将 b.length字节从指定的字节数组写入此输出流
void write(byte[] b, int off, int len)  // 从指定的字节数组写入 len字节,从偏移量 off开始输出到此输出流
void write(int b)       // 将指定的字节输出流

自己特有的成员方法:

void print(Object x)     // 可以写任意类型数据,不换行
void println(Object x)      // 可以写任意类型的数据,换行

修改输出语句的目的地为打印流的目的地

使用System类中的方法setOut,修改输出语句的目的地(控制台)为打印流的目的地

static void setOut(PrintStream out)  // 重新分配“标准”输出流。

作用:不让输出语句在控制台输出了,在打印流的目的地文件中输出

使用示例

import java.io.FileNotFoundException;
import java.io.PrintStream;public class Demo01PrintStream {public static void main(String[] args) throws FileNotFoundException {/*基本使用*///1.创建PrintStream对象,构造方法中绑定要输出的目的地PrintStream ps = new PrintStream("day22\\print1.txt");//2.使用PrintStream对象中的方法write,print,println,把数据写入到文件中//继承自父类OutputStream的共性的成员方法write:使用write写数据,查看的时候,会查询编码表ps.write(97);//a//自己特有的成员方法:print,println写数据,原样输出ps.println(97);//97ps.println('@');//@ps.println(true);//trueps.println(1.1);//1.1ps.println("aaa");//aaa//3.释放资源ps.close();//打印字符数组不是地址值,是数组中的元素 void println(char[] x) 打印字符数组(字符串底层就是字符数组)char[] chars = {'a','b','c'};System.out.println(chars);//abcSystem.out.println("abc");//abc/*修改输出语句的目的地为打印流的目的地*/System.out.println("输出语句的目的地默认是在控制台输出!");PrintStream ps = new PrintStream("day22\\print2.txt");System.setOut(ps);//修改输出语句的目的地(控制台)为打印流的目的地System.out.println(1);System.out.println(2);System.out.println(3);System.out.println("输出语句的目的地不是控制台了,是print2.txt文件中");}
}

PrintWriter:字符打印流

java.io.PrintWriter extends Writer

构造方法:

public PrintWriter(Writer out)
public PrintWriter(Writer out, boolean autoFlush)
public PrintWriter(OutputStream out)
public PrintWriter(OutputStream out, boolean autoFlush)
public PrintWriter(String fileName)
public PrintWriter(String fileName, String charsetName)
public PrintWriter(File file)
public PrintWriter(File file, String charsetName)

成员方法:

public void close()          // 关闭此输出流并释放与此流相关联的任何系统资源
public void flush()             // 刷新此输出流并强制任何缓冲的输出字节被写出
public void write(int c)
public void write(char buf[])
public void write(char buf[], int off, int len)
public void write(String s)
public void write(String s, int off, int len)
public PrintWriter append(CharSequence csq)
public PrintWriter append(CharSequence csq, int start, int end)
public PrintWriter append(char c)

特有的成员方法:

public void print(Object x)      // 可以写任意类型的数据,不换行
public void println(Object x)   // 可以写任意类型的数据,换行
// 使用指定的格式字符串和参数将格式化的字符串写入到这个写入器的便捷方法。如果启用了自动刷新,则对该方法的调用将刷新输出缓冲区
public PrintWriter printf(String format, Object ... args)

使用示例

import java.io.*;
import java.util.Locale;public class PrintWriterDemo {public static void main(String[] args) {String s = "Hello World";try {PrintWriter pw = new PrintWriter(System.out);// %s 表示将在那里放置一个字符串,即spw.printf(Locale.UK, "This is a %s program", s);// 换行pw.println();// %d 表示将放置一个整数,即100pw.printf(Locale.UK, "This is a %s program with %d", s, 100);pw.flush();} catch (Exception ex) {ex.printStackTrace();}}
}

序列化流

ObjectOutputStream:对象的序列化流

java.io.ObjectOutputStream extends OutputStream

作用:把对象以流的方式写入到文件中保存

构造方法:

public ObjectOutputStream(OutputStream out)  // 创建写入指定 OutputStream 的 ObjectOutputStream。
/* 参数:OutputStream out:传递字节输出流,可以传递OutputStream的任意子类对象
*/

特有的成员方法:

void writeObject(Object obj)         // 将指定的对象写入 ObjectOutputStream

ObjectInputStream:对象的反序列化流

java.io.ObjectInputStream extends InputStream

作用:把文件中保存的对象以流的方式读取出来使用

构造方法:

public ObjectInputStream(InputStream in)     // 创建从指定 InputStream 读取的 ObjectInputStream。
/* 参数:InputStream in:传递字节输入流,我们可以传递InputStream的任意子类对象
*/

特有的成员方法:

 Object readObject()     // 从 ObjectInputStream 读取对象

不能被序列化的情况

transient:瞬态关键字

被 transient 关键字修饰的变量不能被序列化

private transient int age;oos.writeObject(new Person("小美女", 18));  // 不会把18写入到文件中
Object obj = ois.readObject();           // Person{name='小美女', age=0}

static:静态关键字

被static修饰的成员属于类,不属于某一个对象,被所有的对象所共享使用

被static修饰的成员,也不能序列化,序列化的是对象

private static int age;oos.writeObject(new Person("小美女",18));  // 不会把18写入到文件中
Object obj = ois.readObject();           // Person{name='小美女', age=0}

可能抛出的异常

NotSerializableException

  • 在进行序列化|反序列化时,抛出 NotSerializableException:没有序列化异常

  • 实体类通过实现 java.io.Serializable 接口以启用其序列化功能。未实现此接口的类将无法使其任何状态序列化或反序列化。

    Serializable接口是一个标记型接口,类实现了 Serializable 接口,接口就会给类添加上一个标记。

    当进行序列化和反序列化的时候,JVM会检查类上是否有标记,有则序列化反序列化成功,没有会抛出异常

    实体类 ==> 添加上了标记 ==> 放心进行序列化和反序列化了 ==> 类做不做其他的用途没有影响

ClassNotFoundException

public final Object readObject() throws IOException, ClassNotFoundException
/*  readObject方法声明抛出了两个异常对象ClassNotFoundException:找不到class文件异常
*/

反序列化有两个前提:

  • 类实现 Serializable 接口
  • 类有对应的 class 文件(Person.class)

序列号冲突异常

可序列化类可以通过声明名为 “serialVersionUID” 的字段(该字段必须是静态 (static)、最终 (final) 的 long 型字段)

显式声明其自己的 serialVersionUID:

private static final long serialVersionUID = xxL;

在类中手动添加了一个序列号,无论类是否修改,序列号都是固定写死的常量值,值是不会改变的,也就不会抛出异常了

例如:

public final class MyString implements java.io.Serializableprivate static final long serialVersionUID = -6849794470754667710L;

示例:

public class Person implements Serializable{private static final long serialVersionUID = 1L;private String name;public int age;
}

案例

文件复制(缓冲流)

import java.io.*;@slf4j
public class Demo03CopyFile {public static void main(String[] args) {/*字节缓冲流*/long s = System.currentTimeMillis();try(BufferedInputStream bis = new BufferedInputStream(new FileInputStream("c:\\全球通史.txt"));BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("d:\\全球通史.txt"));){//一读一写复制文件byte[] bytes = new byte[1024 * 500];int len = 0;while ((len = bis.read(bytes)) != -1){bos.write(bytes, 0, len);   //写有效字节个数(最后一次读取不一定是1024个)bos.flush();}} catch (IOException e) {e.printStackTrace();}long e = System.currentTimeMillis();log.info("复制文件共耗时:" + (e-s) + "毫秒");/*字符缓冲流*/try(BufferedReader br = new BufferedReader(new FileReader("day22\\csb.txt"));BufferedWriter bw = new BufferedWriter(new FileWriter("day22\\出师表.txt"));){//一读一写复制文件String line;while ((line = br.readLine()) != null){//5.把读取的每行数据,存储到ArrayList集合中bw.write(s);bw.newLine();bw.flush();}} catch (IOException e) {e.printStackTrace();}}
}

转换文件编码

将 GBK 编码的文本文件,转换为 UTF-8 编码的文本文件。

基本步骤:

​ 1.创建InputStreamReader对象,构造方法中传递FileInputStream对象和GBK编码名称

​ 2.创建OutputStreamWriter对象,构造方法中传递FIleOutputStream对象和UTF-8编码名称

​ 3.使用InputStreamReader对象中的方法read,读取GBK编码的文件

​ 4.使用OutputStreamWriter对象中的方法write,把读取到的数据,以UTF-8编码,写入到内存缓冲区中

​ 5.释放资源(会先调用flush方法刷新数据到文件中)

import java.io.*;public class Demo04Test {public static void main(String[] args) throws IOException {try (//1.创建InputStreamReader对象,构造方法中传递FileInputStream对象和指定的编码表名称InputStreamReader isr = new InputStreamReader(new FileInputStream("day22\\utf-8.txt"),"GBK");){//2.创建OutputStreamWriter对象,构造方法中传递FIleOutputStream对象和UTF-8编码名称//OutputStreamWriter osw = new OutputStreamWriter(//     new FileOutputStream("day22\\utf-82.txt"),"UTF-8");//不写编码名称默认UTF-8//OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("day22\\utf-83.txt"));FileWriter osw = new FileWriter("day22\\utf-84.txt");//3.使用InputStreamReader对象中的方法read,读取GBK编码的文件int len = 0;while ((len = isr.read()) != -1){//4.使用OutputStreamWriter对象中的方法write,把读取到的数据,以UTF-8编码,写入到内存缓冲区中osw.write(len);}} catch (IOException e) {e.printStackTrace();}}
}

IO工具类

java.io.File

参考:https://www.runoob.com/java/java-file.html

描述:文件和目录路径名的抽象表示形式

常用静态变量:

// 与系统有关的路径分隔符。 windows中分号";",Linux中冒号":"
static String pathSeparator
static char pathSeparatorChar// 与系统有关的默认名称(文件夹名称)分隔符。windows中右斜杠"\",Linux中左斜杠"/"
static String separator
static char separatorChar

构造方法:

public File(String pathname)
public File(String parent, String child)
public File(File parent, String child)

常用方法:

/* 判断功能 */
// 此File表示的文件或目录是否实际存在
boolean exists()
// 是否为目录(文件夹)   // 需先判断路径是否实际存在
boolean isDirectory()
// 是否为文件          // 需先判断路径是否实际存在
boolean isFile()
// 测试此抽象路径名是否为绝对路径名
boolean isAbsolute()
// 测试此抽象路径名与给定对象是否相等
boolean equals(Object obj)
// 测试应用程序是否可以读取此抽象路径名表示的文件
boolean canRead()
// 测试应用程序是否可以修改此抽象路径名表示的文件
boolean canWrite()/* 创建删除功能 */
// 当且仅当具有该名称的文件尚不存在时,创建一个新的空文件。// 路径必须是存在的和有权访问的,否则会抛出异常。路径必须是存在的和有权访问的,否则会抛出异常。// 文件存在,不会创建返回false;构造方法中传递路径不存在,返回false
boolean createNewFile() throws IOException
// 创建单级文件夹 // 文件夹存在,不会创建返回false;构造方法中传递路径不存在,返回false
boolean mkdir()
// 即可以创建单级文件夹,又可以创建多级文件夹 // 文件夹存在,不会创建返回false;构造方法中传递路径不存在,返回false
boolean mkdirs()
// 删除文件或文件夹,不走回收站 // 路径不存在或者文件夹中有内容,不会删除,返回false
boolean delete()/* 目录遍历 */
// 返回一个String数组,表示该File目录中的所有子文件或目录      // 路径必须是目录,否则会抛异常
String[] list()
// 返回一个File数组,表示该File目录中的所有的子文件或目录       // 路径必须是目录,否则会抛异常
File[] listFiles()// 返回由此抽象路径名表示的文件或目录的名称(末尾部分)
String getName()
// 返回抽象路径名的绝对路径名字符串
String getAbsolutePath()
// 获取文件的大小,单位是字节
long length()
// 重新命名此抽象路径名表示的文件
boolean renameTo(File dest)

commons-io 工具包

<dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.4</version>
</dependency

commons-io是apache开源基金组织提供的一组有关IO操作的类库,可以挺提高IO功能开发的效率。commons-io工具包提供了很多有关io操作的类

IOUtils 工具类

包路径:org.apache.commons.io.IOUtils;

处理输入 - 输出流。所有成员字段和方法都是静态的

链接:https://blog.csdn.net/l2580258/article/details/89227761

常用静态变量:

static String LINE_SEPARATOR;                        // 行分隔符
static String LINE_SEPARATOR_UNIX = "\n";            // Unix系统的行分隔符
static String LINE_SEPARATOR_WINDOWS = "\r\n";       // Windows系统的行分隔符

常用静态方法:

注:类中的所有处理InputStream的方法都带有内部的缓冲区,所以不需要再使用 BufferedReader或者 BufferedInputStream,默认的缓冲区大小为4K,不过也可以自定义它的大小。

// 把input输入流中的内容拷贝到output输出流中,返回拷贝的字节个数(适合文件大小为2GB以下)
static int copy(Reader input, Writer output)                            // 字符流
static int copy(InputStream input, OutputStream output)                 // 字节流
static void copy(InputStream input, Writer output, Charset encoding)
// 把input输入流中的内容拷贝到output输出流中,返回拷贝的字节个数(适合文件大小为2GB以上)
static long copyLarge(InputStream input, OutputStream output)
static long copyLarge(Reader input, Writer output)// 从流中读取内容,并转换为String的list
static List<String> readLines(InputStream input)
static List<String> readLines(InputStream input, String encoding)// input 的类型可以为 InputStream,Reader// encoding 的类型可以为 Charset,String// 把数据写入到输出流中
static void write(String data, OutputStream output)
static void write(String data, OutputStream output, String encoding)
// 把string的List写入到输出流中
static void writeLines(Collection<?> lines, String lineEnding, OutputStream output)
static void writeLines(Collection<?> lines, String lineEnding, OutputStream output, String encoding)// data 的类型可以为 byte[],CharSequence,StringBuffer,String// output 的类型可以为 OutputStream,Writer// encoding 的类型可以为 Charset,String// 无条件的关闭一个可被关闭的对象而不抛出任何异常。
// 重载支持关闭所有的InputStream、OutputStream、Reader和Writer。
static void closeQuietly(Closeable closeable)// 比较两个Reader对象的内容是否相同,相同返回true,否则返回false
static boolean contentEquals(Reader input1, Reader input2)
static boolean contentEquals(InputStream input1, InputStream input2)
// 比较两个Reader对象的内容是否相同,忽略行结束符而比较内容
static boolean contentEqualsIgnoreEOL(Reader input1, Reader input2)// 从InputStream中返回一个行迭代器。行迭代器将持有一个打开的InputStream的引用。迭代结束后,应当关闭stream来释放内部资源。
static LineIterator lineIterator(InputStream input, String encoding)// input 的类型可以为 InputStream,Reader// encoding 的类型可以为 Charset,String。传null则使用默认的// 返回字符输入流缓冲流
static BufferedReader toBufferedReader(Reader reader)
static BufferedReader toBufferedReader(Reader reader, int size)
// 返回字节输入流缓冲流
static InputStream toInputStream(CharSequence input)
static InputStream toInputStream(CharSequence input, String encoding)// 返回字符串
static String toString(Reader input)
static String toString(InputStream input, String encoding)
static String toString(URI uri)
static String toString(URI uri, Charset encoding)
static String toString(URL url, Charset encoding)
static String toString(URL url, String encoding)// input 的类型可以为 InputStream,Reader,byte[]

FileUtils 工具类

包路径:org.apache.commons.io.FileUtils;

操作文件的工具类

常见工具类:

// 读取一个文件以字符串形式返回
static String readFileToString(File file)
static String readFileToString(File file, String encoding)// 文件复制
static void copyFile(File srcFile, File destFile)
// 复制整个文件夹到另外一个地方
static void copyDirectory(File source, File destination)
// 复制整个文件夹到另外一个地方,过滤一些指定的文件(比如名字,修改时时间等等)
static void copyDirectory(File source, File destination, FileFilter filter)
// 把一个文件复制到一个文件夹中
static void copyFileToDirectory(File srcFile, File destDir)
// 文件夹复制
static void copyDirectoryToDirectory(File srcDir, File destDir)// 使用指定的编码将CharSequence写入文件中
static void write(File file, CharSequence data)
// 将集合按行写入到文件中
static void writeLines(File file, Collection<?> lines)
// 把字符串写入到一个文件中
static void writeStringToFile(File file, String data)// 返回一个File对象
static File getFile(String... names)
// 返回表示系统临时目录的File对象
static String getTempDirectory()
// 返回表示用户目录的File对象
static String getUserDirectory()
// 创建了一个迭代器,可以按行遍历给定的文件
static LineIterator lineIterator(File file)
// 返回目录内容的大小
static long sizeOfDirectory(File directory)// 比较两个文件的内容,返回比较的结果
static boolean contentEquals(File file1, File file2)// 递归的删除一个文件夹
static void deleteDirectory(File directory)

FilenameUtils 工具类

参考:https://www.cnblogs.com/xwb583312435/p/9014868.html

路径:org.apache.commons.io.FilenameUtils;

常用方法:

// 获取当前系统格式化路径
static String normalize(String filename)
// 获取当前系统无结尾分隔符的路径
static String normalizeNoEndSeparator(String filename)// 合并目录和文件名为文件全路径
static String concat(String basePath, String fullFilenameToAdd)// 获取文件名称,包含后缀
static String getName(String filename)
// 获取文件路径去除目录和后缀后的文件名
static String getBaseName(String filename)
// 获取文件的后缀
static String getExtension(String filename)
// 获取文件的完整目录(示例:/D:/aa/bb/cc/)
static String getFullPath(String filename)
// 获取文件的目录不包含结束符(示例:/D:/aa/bb/cc)
static String getFullPathNoEndSeparator(String filename)
// 获取去除前缀的路径(示例:D:/aa/bb/cc/)
static String getPath(String filename)
// 获取去除前缀并结尾去除分隔符的路径(示例:D:/aa/bb/cc)
static String getPathNoEndSeparator(String filename)
// 获取前缀
static String getPrefix(String filename)
// 获取最后一个.(文件名与拓展名的分隔符)的位置
static int indexOfExtension(String filename)
// 获取最后一个分隔符的位置
static int indexOfLastSeparator(String filename)// 转换分隔符为当前系统分隔符
static String separatorsToSystem(String path)
// 转换分隔符为linux系统分隔符
static String separatorsToUnix(String path)
// 转换分隔符为windows系统分隔符
static String separatorsToWindows(String path)// 判断文件路径是否相同
static boolean equals(String filename1, String filename2)
// 判断文件路径是否相同,格式化并大小写不敏感 // IOCase.INSENSITIVE
static boolean equals(String filename1, String filename2, boolean normalized, IOCase caseSensitivity)
// 判断文件路径是否相同,格式化并大小写敏感
static boolean equalsNormalized(String filename1, String filename2)
// 判断文件路径是否相同,不格式化,大小写敏感根据系统规则:windows:敏感;linux:不敏感
static boolean equalsOnSystem(String filename1, String filename2)// 判断文件扩展名是否等于指定扩展名
static boolean isExtension(String filename, String extension)
// 判断文件扩展名是否包含在指定字符串数组中
static boolean isExtension(String filename, String[] extensions)
// 判断文件扩展名是否包含在指定集合中
static boolean isExtension(String filename, Collection<String> extensions)// 判断文件扩展名是否和指定规则匹配,大小写敏感
static boolean wildcardMatch(String filename, String wildcardMatcher)
// 判断文件扩展名是否和指定规则匹配,大小写不敏感       // IOCase.INSENSITIVE
static boolean wildcardMatch(String filename, String wildcardMatcher, IOCase caseSensitivity)
// 判断文件扩展名是否和指定规则匹配,根据系统判断敏感型:windows:不敏感;linux:敏感
static boolean wildcardMatchOnSystem(String filename, String wildcardMatcher)// 移除文件的扩展名
static String removeExtension(String filename)
// 判断目录下是否包含指定文件或目录
static boolean directoryContains(String canonicalParent, String canonicalChild)

拓展

Properties 集合

java.util.Properties extends Hashtable<k,v> implements Map<k,v>

  • Properties(属性) 类表示了一个持久的属性集。Properties 可保存在流中或从流中加载。

  • Properties 集合是一个唯一和 IO 流相结合的集合:

    • 可以使用 Properties 集合中的方法 store(),把集合中的临时数据 持久化到 硬盘中存储(内存 ==> 硬盘)
    • 可以使用 Properties 集合中的方法 load(),把硬盘文件中保存的键值对 读取到 内存中集合里边使用(硬盘 ==> 内存)
  • 属性列表中每个键及其对应值都是一个字符串。

    Properties 是一个双列集合,不需要写泛型,key 和 value 默认都是字符串String类型

常用方法:

Object setProperty(String key, String value)  // 往Properties集合中添加键值对,相当于Map集合的put方法
String getProperty(String key)          // 根据key获取value,相当于Map集合的get(key)方法
Set<String> stringPropertyNames()         // 返回此属性列表中的键集,相当于Map集合的keySet方法// 把集合中的临时数据,持久化到硬盘中存储(内存-->硬盘)
void store(OutputStream out, String comments)
void store(Writer writer, String comments)
/* 方法的参数:OutputStream out:传递字节输出流,不能写中文,会出现乱码,可以传递OutputStream的任意子类对象Writer writer:传递字符输出流,能写中文,不会出现乱码,可以传递Writer的任意的子类对象String comments:注释解释说明我们保存文件是做什么用的,一般传递""注释不能写中文,默认使用Unicode编码,写中文会出现乱码
*/// 把硬盘文件中保存的键值对,读取到内存中集合里边使用(硬盘-->内存)
void load(InputStream inStream)     // 传递字节输入流,不能读取含有中文的文件,可以传递InputStream的任意子类对象
void load(Reader reader)            // 传递字符输入流,可以读取含有中文的文件,可以传递Reader的任意子类对象
/* 注意:1.在Properties集合的配置文件中,可以使用 # 进行注释,被注释的键值对不会被读取2.在Properties集合的配置文件中,健和值之间可以使用 =,空格,冒号 等一些符号作为键与值的分割符号3.在Properties集合的配置文件中,健和值默认都是String类型,不需要添加引号,否则会画蛇添足
*/

使用示例

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Iterator;
import java.util.Properties;
import java.util.Set;public class Demo01Properties {public static void main(String[] args) {/*基本使用:使用Properties集合存储数据,遍历集合获取集合中的元素*/Properties prop = new Properties();//使用Properties集合中的方法setProperty往集合中添加键值对prop.setProperty("迪丽热巴","168");prop.setProperty("古力娜扎","165");//使用Properties集合中的方法stringPropertyNames,获取集合中所有的key,把key存储到一个Set集合中返回Set<String> set = prop.stringPropertyNames();//遍历Set集合,获取Properties集合的每一个keyfor (String key : set) {//使用Properties集合中的方法getProperty根据key获取valueString value = prop.getProperty(key);System.out.println(key + "=" + value);}/*把集合中的临时数据,持久化到硬盘中存储(内存-->硬盘)*//*FileOutputStream fos = new FileOutputStream("day21\\prop1.txt");prop.store(fos, "save data");fos.close();*/// 如果对象只使用一次,可以使用匿名对象(会自动关闭)prop.store(new FileOutputStream("day21\\prop1.txt"), "save data");prop.store(new FileWriter("day21\\prop2.txt"), "save data");// 一般存储键值对的文件,叫配置文件,文件的后缀名一般都使用.propertiesprop.store(new FileWriter("day21\\prop.properties"), "save data");/*把硬盘文件中保存的键值对,读取到内存中集合里边使用(硬盘-->内存)*/Properties prop = new Properties();// 使用Properties集合中的方法load,把硬盘文件中保存的键值对,读取到内存中集合里边使用//prop.load(new FileInputStream("day21\\prop.properties"));prop.load(new FileReader("day21\\prop.properties"));// 遍历Properties集合Set<String> set = prop.stringPropertyNames();Iterator<String> it = set.iterator();while (it.hasNext()){String key = it.next();String value = prop.getProperty(key);System.out.println(key+"\t"+value);}}
}

prop.properties

#save data
#Fri Jul 10 14:51:47 CST 2020
赵丽颖 160
杨幂:172
#古力娜扎=165
"迪丽热巴"=168
#马尔扎哈=180

ResourceBundle 工具类

java.util.ResourceBundle:操作资源的工具类

作用:我们可以使用ResourceBundle类中的方法读取以 .properties 结尾的文件

注意:

  • ResourceBundle是一个抽象类,我们无法直接创建对象使用,我们可以使用ResourceBundle类中的静态方法获取ResourceBundle的子类对象

    static ResourceBundle getBundle(String baseName)
    /* 参数:String baseName:传递以.properties结尾的文件名称data.properties ==> 传递data
    */
    
  • 以properties结尾的文件必须放在当前模块的src下边,否则获取对象找不到配置文件,会抛出异常MissingResourceException: Can't find bundle for base name data, locale zh_CN

常用方法:

 // 用于读取配置文件(存储的都是键值对)
String getString(String key)    // 根据配置文件中key,读取配置文件中的value
/* 注意:配置文件中的key和value不要使用中文
*/

使用示例

import java.util.ResourceBundle;public class Demo02ResourceBundle {public static void main(String[] args) {//获取ResourceBundle对象ResourceBundle bundle = ResourceBundle.getBundle("data");//使用ResourceBundle对象中的方法getString,根据配置文件中key,读取配置文件中的valueString username = bundle.getString("username");System.out.println(username);//jackString password = bundle.getString("password");System.out.println(password);//1234String sex = bundle.getString("sex");System.out.println(sex);//Å®(sex=女)//String age = bundle.getString("年龄");//java.util.MissingResourceException: Can't find resource for bundle java.util.PropertyResourceBundle, key 年龄//System.out.println(age);}
}

data.properties(放在src的下边)

username=jack
password=1234
sex=女
年龄=18

IO流常用类使用详解相关推荐

  1. IO流输入输出流入门详解

    IO流输入输出流入门详解 1.Java中以流的形式处理数据 2.流是一种有序的数据序列,分为输入输出流 3.Java是面向对象的程序设计语言,每个数据都是一个对象 4.Java中的输入输出功能来自ja ...

  2. 【Java网络编程与IO流】Http协议详解以及面试有关问题

    HTTP协议详解以及面试有关题目 1 HTTP请求 一个HTTP请求报文由请求行.请求头部.空行和请求数据四个部分组成. 1.1 请求行 请求行中有请求方法字段.URL字段和HTTP协议版本3个字段组 ...

  3. java中的IO流(超全)(超详解)结合实例轻松掌握

    java进阶之IO流 IO流的概念(大纲): 1.InputStream和OutputStream的继承关系图 2.Reader和Writer的继承关系图 3.文件专属流(加※为重点掌握) ※File ...

  4. Java实现文件写入——IO流(输入输出流详解)

    输入输出的重要性: 输入和输出功能是Java对程序处理数据能力的提高,Java以流的形式处理数据.流是一组有序的数据序列,根据操作的类型,分为输入流和输出流. 程序从输入流读取数据,向输出流写入数据. ...

  5. java中object类型_Java常用类object详解

    1.Object概述: 类Object是类层次结构的根类.每个类都使用Object作为超类.所有对象(包括数组)都实现这个类的方法. 2.构造方法详细信息: Object只有一个无参构造方法,因为ob ...

  6. java stringbuffer详解_Java常用类StringBuffer详解

    内容多为最近学习的自我总结,可能有些地方写的不严谨,甚至会有错误的地方,仅供参考,如发现错误敬请指出,谢谢! 灰色字体为补充扩展内容,多为帮助自己理解. StringBuffer概述: 线程安全的可变 ...

  7. Java常用类StringBuffer详解

    内容多为最近学习的自我总结,可能有些地方写的不严谨,甚至会有错误的地方,仅供参考,如发现错误敬请指出,谢谢! 灰色字体为补充扩展内容,多为帮助自己理解. StringBuffer概述: 线程安全的可变 ...

  8. Java学习-IO流-read()和write()详解

    read方法包括: read(),此方法一个字节一个字节的读取,从输入流中读取数据的下一个字节.返回 0 到 255 范围内的 int 字节值.如果因为已经到达流末尾而没有可用的字节,则返回值 -1 ...

  9. Java常用工具类(六):文件、资源、IO流工具类

    1. 文件工具类 1.1 FileCopyUtils 输入 // 从文件中读入到字节数组中 byte[] copyToByteArray(File in) // 从输入流中读入到字节数组中 byte[ ...

最新文章

  1. Jetty 9.0.0 首个里程碑出现
  2. ege函数库_基于c++ ege图形库实现五子棋游戏
  3. Spring模块化设计:Spring功能特性如何在不同模块中组织?
  4. SQL 中 left join 的底层原理(各种JOIN的复杂度探究)
  5. 曲苑杂坛--修改数据库名和文件组名
  6. 1.4)深度学习笔记------深层神经网络
  7. 新建maven的pom.xml第一行出错的解决思路
  8. RMAN报错:ORA-19573: 无法获得 exclusive 入队
  9. VS系列IDE(2005、2008等)下使用cppunit的方法及使用示例
  10. JQuery实现radio、select、checkbox禁用
  11. 左移寄存器vhdl_VHDL实验代码:8位移位寄存器
  12. 云计算、人工智能、大数据等当前火热的技术,都离不开它!
  13. 小D课堂 - 新版本微服务springcloud+Docker教程_2_03常见的微服务框架
  14. NYOJ Dinner
  15. JSONObject.fromObject()方法报错解决方法
  16. Java--汽车之家论坛反爬虫破解
  17. MRP存在的七大缺陷,你造吗?
  18. 计算机程序班搞笑口号,二班班级霸气押韵口号(精选50句)
  19. 小程序苹果手机底部出现横杠处理
  20. TensorFlow简单实例(二):logistic regression

热门文章

  1. 【W5500】STM32 H743驱动W5500进行UDP收发
  2. 2021免费大容量OneDrive + office 365桌面版 (a1 a1p)
  3. OpenCV | 直线拟合fitline函数
  4. jQuery 中ajax回调函数获得的数据格式问题
  5. 我在阿里做数据分析师,一位阿里数据分析师的日常
  6. 2020腾讯、百度、华为Android面试题校招汇总(已拿offer
  7. 美团新用户0.99充10元话费,秒到账,不实名不绑卡,超简单!
  8. [04]Web前端进阶—JS伪数组
  9. App地推活动怎么做才能事半功倍
  10. 一文简单理解反向代理和正向代理模型