IO流

1、IO概述

生活中,你肯定经历过这样的场景。当你编辑一个文本文件,忘记了ctrl+s ,可能文件就白编了。当你电脑上插入一个U盘,可以把一个视频,拷贝到你的电脑硬盘里。那么数据都是在哪些设备上的呢?键盘、内存、硬盘、外接设备等等。【系统内存存储的数据,只要关机,系统内存的数据就会被释放!】

我们把这种数据的传输,可以看做是一种数据的流动,按照流动的方向,以内存为基准,分为输入input 和输出output ,即流向内存是输入流,流出内存的输出流

Java中I/O操作主要是指使用java.io包下的内容,进行输入、输出操作。输入也叫做读取数据,输出也叫做作写出数据。
注意:流的关闭原则为,先开后关,后开先关。

2、IO的分类

  • 根据数据的流向分为:输入流和输出流。
    输入流 :把数据从其他设备上读取到内存中的流。
    输出流 :把数据从内存 中写出到其他设备上的流。
  • 根据数据的类型分为:字节流和字符流。
    字节流 :以字节为单位,读写数据的流。
    字符流 :以字符为单位,读写数据的流。
  • 顶级父类(均为抽象类)
    字节输入流:InputStream
    字节输出流:OutputStream
    字符输入流:Reader
    字符输出流:Writer

3、IO资源处理

3.1 JDK7之前的处理方式

将关闭流资源的代码写在finally语句体中,需要将流对象提到try…cath…finally的外部 【麻烦!】

/*以字符输出流为例!说明JDK7之前的处理io资源的问题!*/
public class Test01BeforeJDK7 {public static void main(String[] args) {// 创建一个字符输出流对象FileWriter fw = null;try {fw = new FileWriter("day11_io/src/fw.txt");fw.write("黑马程序员");} catch (IOException e) {e.printStackTrace();}finally {try {fw.close();} catch (IOException e) {e.printStackTrace();}}}}
3.2 JDK7之后的处理方式

为了代码的操作方便,采取了新的语法措施!

* 语法:try(io流资源的创建操作) {  // 意味着后面不用写finally,它会关闭! 【多个io流资源之间使用“;”隔开!】// io流读取操作的代码!} catch (IOException e) {// 异常处理的代码!}
/*以字符输出流为例!说明JDK7之后的处理io资源的问题!*/
public class Test02AfterJDK7 {public static void main(String[] args) {// 创建一个字符输出流对象try (FileWriter fw = new FileWriter("day11_io/src/fw.txt");//FileReader fr = new FileReader("day11_io/src/fr.txt");) {fw.write("黑马程序员");} catch (IOException e) {e.printStackTrace();}}}

测试结果发现fw.txt文件中有数据,说明流关闭了(没有关闭,数据在缓冲区)

Properties类

1、 Properties类的概述

java.util.Properties 继承于Hashtable ,来表示一个持久的属性集。它使用键值结构存储数据,每个键及其对应值都是一个字符串。该类也被许多Java类使用,比如获取系统属性时,System.getProperties 方法就是返回一个Properties对象。【更多时候用于读取配置文件】

Properties的底层是一个Map结构

2、 构造方法

Properties()  //创建一个没有默认值的空属性列表。

3、 基本存取功能方法

public Object setProperty(String key, String value)  : // 保存一对属性。   =====>>>map.put(key,value);
public String getProperty(String key)  : // 使用此属性列表中指定的键搜索属性值。======>>> map.get(key);
public Set<String> stringPropertyNames()  : // 所有键的名称的集合。 ======>>map.keySet();
/*Properties类的构造方法和基本存取功能方法【就是将其当做Map(Hashtable类型的)功能来使用】*/
public class Test01 {public static void main(String[] args) {// 创建Properties类的对象Properties pp = new Properties();// 存数据pp.setProperty("driverClass","com.mysql.jdbc.Driver");pp.setProperty("url","http://localhost:3306/day11_db");pp.setProperty("username","root");pp.setProperty("password","root");// 取数据(所有的key)Set<String> set = pp.stringPropertyNames();// 非空判断if(!set.isEmpty()){// 遍历for (String key : set) {System.out.println("key:" + key + ", value:"+ pp.getProperty(key));}}}}

4、 Properties类读取配置文件

Properties类除了能够当做Map使用,还可以与文件(可以是txt文件、可以是properties)进行关联,获得文件里面的数据!

void load(InputStream inStream)  // 从输入字节流读取属性列表(键和元素对)。

要求:将文件放在src目录(类的根路径)下面!

src下的资源文件fis.properties内容:

driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/day11_db
password=root
username=root
/*读取配置文件(text类型的)*/
public class Test02 {public static void main(String[] args) {// 创建Properties类的对象Properties prop = new Properties();// 创建资源文件对应的字节输入流try (//FileInputStream fis = new FileInputStream("day11_io/src/fis.txt");FileInputStream fis = new FileInputStream("day11_io/src/fis.properties");) {// 让文件对应的的输入流与prop关联prop.load(fis);// 获得所有的keySet<String> set = prop.stringPropertyNames();// 判断if (!set.isEmpty()) {// 遍历for (String key : set) {// 获得值String value = prop.getProperty(key);// 打印输出System.out.println(key + "对应的值是:" + value);}}} catch (Exception e) {e.printStackTrace();}}}

扩展:使用ResourceBundle类读取properties配置文件

核心方法:

static ResourceBundle getBundle(String baseName) // 通过读取在src下面的properties文件的名称(不要扩展名),得到一个ResourceBundle对象!
String getString(String key) // 获得指定key对应的value值 【driverClass=com.mysql.jdbc.Driver,只要将driverClass作为参数,就可以得到值!】
/*ResourceBundle类:读取properties配置文件!*/
public class Test03 {public static void main(String[] args) {// 通过ResourceBundle类的静态方法,得到ResourceBundle类的对象ResourceBundle bundle = ResourceBundle.getBundle("fis"); // 只要给定properties配置文件的名称,不要扩展名!// 获得指定参数的值String driverClass = bundle.getString("driverClass");String url = bundle.getString("url");String username = bundle.getString("username");String password = bundle.getString("password");System.out.println(driverClass);System.out.println(url);System.out.println(username);System.out.println(password);}}

一、字节流

1.1 一切皆为字节

 一切文件数据(文本、图片、视频等)在存储时,都是以二进制数字的形式保存,都一个一个的字节,那么传输时一样如此。所以,字节流可以传输任意文件数据。在操作流的时候,我们要时刻明确,无论使用什么样的流对象,底层传输的始终为二进制数据。

1.2 字节输出流FileOutputStream

1.2.1 抽象父类

java.io.OutputStream抽象类是表示字节输出流的所有类的超类,将指定的字节信息写出到目的地(外置设备)。它定义了字节输出流的基本共性功能方法。

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)  :// 将指定的字节输出流。

close方法,当完成流的操作时,必须调用此方法,释放系统资源。

OutputStream有很多子类,我们从最简单的一个子类开始。

1.2.2 构造方法

java.io.FileOutputStream类是文件输出流,用于将数据从内存写出到文件。

* 构造方法:
public FileOutputStream(File file):创建文件输出流以写入由指定的 File对象表示的文件。
public FileOutputStream(String name): 创建文件输出流以指定的名称写入文件。

当你创建一个流对象时,必须传入一个文件路径。该路径下,如果没有这个文件,会创建该文件。如果有这个文件,会清空这个文件的数据。

public class Test01 {public static void main(String[] args) throws FileNotFoundException {// 创建File对象File file = new File("day10_io/src/a.txt"); // a.txt文件目前是不存在的,但是不影响file对象的创建// 创建字节输出流对象(通过File对象构建的)FileOutputStream fos =  new FileOutputStream(file);System.out.println(fos);// 创建字节输出流对象(通过字符串路径构建的)FileOutputStream fos1 = new FileOutputStream("day10_io/src/b.txt");System.out.println(fos1);}}

1.2.3 写出字节数据

① 写出字节:write(int b) 方法,每次可以写出一个字节数据 [97 98 99]

1. 虽然参数为int类型四个字节,但是只会保留一个字节的信息写出。
2. 流操作完毕后,必须释放系统资源,调用close方法,千万记得。
public class Test02 {public static void main(String[] args){FileOutputStream fos = null;try {// 创建字节输出流的对象fos = new FileOutputStream("day10_io/src/os.txt");// 写出字节数据fos.write(97);fos.write(98);fos.write(99);}catch (FileNotFoundException e){e.printStackTrace();}catch (IOException e){e.printStackTrace();}finally {// 关闭流(释放资源)try {fos.close();} catch (IOException e) {e.printStackTrace();}}}}

② 写出字节数组:write(byte[] b),每次可以写出数组中的数据[黑马程序员]

public class Test03 {public static void main(String[] args) throws IOException {// 创建字节输出流对象FileOutputStream fos = new FileOutputStream("day10_io/src/os.txt");// 准备字节数组//byte[] b = {97, 98, 99, 100};byte[] b = "黑马程序员".getBytes(); // 每次新写出数据,都会将文件中原来的数据给清空!// 调用write方法,将字节数组的数据从内存中写出到指定文件。fos.write(b);// 关闭资源fos.close();}}

③ 写出指定长度字节数组:write(byte[] b, int off, int len) ,每次写出从off索引开始,len个字节[abcde]

/*FileOutputStream字节输出流写出字节数组中指定的数据:void write(byte[] b, int off, int len) 将 len字节从指定的字节数组开始,从偏移量 off开始写入此文件输出流。off:指定起始位置!len:指定个数!*/
public class Test04 {public static void main(String[] args) throws IOException {// 创建字节输出流对象FileOutputStream fos = new FileOutputStream("day10_io/src/os.txt");// 准备字节数组byte[] b = "abcde".getBytes(); // 每次新写出数据,都会将文件中原来的数据给清空!// 调用write方法,将字节数组的数据从内存中写出到指定文件。fos.write(b,0,b.length); // abcde// 关闭资源fos.close();}}

1.2.4 数据追加续写

经过以上的演示,每次程序运行,创建输出流对象,都会清空目标文件中的数据。如何保留目标文件中数据,还能继续添加新数据呢?

public FileOutputStream(File file, boolean append): // 创建文件输出流以写入由指定的File对象表示的文件。
public FileOutputStream(String name, boolean append): // 创建文件输出流以指定的名称写入文件。

这两个构造方法,参数中都需要传入一个boolean类型的值,true 表示追加数据,false 表示清空原有数据。这样创建的输出流对象,就可以指定是否追加续写了

/*FileOutputStream字节输出流追加续写!在FileOutputStream构造方法的参数位置再添加一个boolean类型的值true即可!【默认为false,不追加续写,清掉之前的数据,写入新数据】*/
public class Test05 {public static void main(String[] args) throws IOException {// 创建字节输出流对象FileOutputStream fos = new FileOutputStream("day10_io/src/os.txt",true);// 准备字节数组byte[] b = "黑马程序员".getBytes(); // 每次新写出数据,都会将文件中原来的数据给清空!// 调用write方法,将字节数组的数据从内存中写出到指定文件。fos.write(b,0,b.length); // abcde// 关闭资源fos.close();}}

1.2.5 写出换行

* 系统中的换行:Windows系统里,每行结尾是  回车+换行  ,即\r\n; 【win10里面换行 \n 也行!】Unix系统里,每行结尾只有  换行  ,即\n;Mac系统里,每行结尾是  回车  ,即\r。从 Mac OS X开始与Linux统一。
* 回车符\r和换行符\n  :回车符:回到一行的开头(return)。换行符:下一行(newline)。

需求:写出字节数组byte[] words = {97,98,99,100,101},写出单个字节数据后换行

public class Test06 {public static void main(String[] args) throws IOException {// 创建字节输出流对象FileOutputStream fos = new FileOutputStream("day10_io/src/os.txt",true);// 准备字节数组byte[] words = {97,98,99,100,101};// 遍历for (byte word : words) {// 先写出单个字节数据fos.write(word);// 再换行fos.write("\r\n".getBytes()); // 在win10系统中 \n也可以完成换行!}// 关闭资源fos.close();}}

1.3 字节输入流FileInputStream

1.3.1 抽象父类

java.io.InputStream抽象类是表示字节输入流的所有类的超类,可以读取字节信息到内存中。它定义了字节输入流的基本共性功能方法。

public void close()  :// 关闭此输入流并释放与此流相关联的任何系统资源。
public abstract int read(): // 从输入流读取数据的下一个字节。
public int read(byte[] b): // 从输入流中读取一些字节数,并将它们存储到字节数组 b中 。

注意:close方法,当完成流的操作时,必须调用此方法,释放系统资源。

1.3.2 构造方法

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

注意:当你创建一个流对象时,必须传入一个文件路径。该路径下,如果没有该文件,会抛出FileNotFoundException

/*FileInputStream字节输入流的构造方法:FileInputStream(File file): // 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的 File对象 file命名。FileInputStream(String name): // 通过打开与实际文件的连接来创建一个 FileInputStream ,该文件由文件系统中的路径名 name命名。注意:给定路径的文件不存在,报错!FileNotFoundException*/
public class Test01 {public static void main(String[] args) throws FileNotFoundException {// FileInputStream(File file):File file = new File("day10_io/src/os.txt");// 创建字节输入流(file对象作为参数的构造方法)FileInputStream fis1 = new FileInputStream(file);System.out.println(fis1);// 创建字节输入流(文件路径作为参数的构造方法)FileInputStream fis2 = new FileInputStream("day10_io/src/is.txt");System.out.println(fis2);}}

1.3.3 读取字节数据

① 读取字节:read方法,每次可以读取一个字节的数据,提升为int类型,读取到文件末尾,返回-1

/*FileInputStream字节输入流读单个字节数据int read() 从该输入流读取一个字节的数据。*/
public class Test02 {public static void main(String[] args) throws IOException {// 创建字节输入流(文件路径作为参数的构造方法)FileInputStream fis = new FileInputStream("day10_io/src/is.txt"); // 数据为abcdef// 读单个字节数据int r1 = fis.read();System.out.println((char)r1); // aint r2 = fis.read();System.out.println((char)r2); // bint r3 = fis.read();System.out.println((char)r3); // cint r4 = fis.read();System.out.println((char)r4); // dint r5 = fis.read();System.out.println((char)r5); // eint r6 = fis.read();System.out.println((char)r6); // fint r7 = fis.read();System.out.println(r7); // 读到文件末尾是-1// 释放资源fis.close();}}

循环改进:

/*FileInputStream字节输入流读单个字节数据使用循环改进!*/
public class Test03 {public static void main(String[] args) throws IOException {// 创建字节输入流(文件路径作为参数的构造方法)FileInputStream fis = new FileInputStream("day10_io/src/is.txt"); // 数据为abcdef// 记录每次读取的单个字节数据!int r;// 使用循环改进while((r = fis.read())!=-1){System.out.println((char)r); // abcdef}// 释放资源fis.close();}}
* 注意:1. 虽然读取了一个字节,但是会自动提升为int类型。2. 流操作完毕后,必须释放系统资源,调用close方法,千万记得。

② 使用字节数组读取:read(byte[] b),每次读取b的长度个字节到数组中,返回读取到的有效字节个数,读取到末尾时,返回-1 [abcde]

public class Test05 {public static void main(String[] args) throws IOException {// 创建字节输入流(文件路径作为参数的构造方法)FileInputStream fis = new FileInputStream("day10_io/src/is.txt"); // 数据为abcde// 定义字节数组byte[] bytes = new byte[2];// 读取到字节数组数据的长度!int len;while((len=fis.read(bytes))!=-1){ // 只要没有读到文件末尾就一直读!// 每次读取的数据都放在字节数组System.out.print(new String(bytes));}// 释放资源fis.close();}
}
// 结果数据: abcded

错误数据d,是由于最后一次读取时,只读取一个字节e,数组中,上次读取的数据cd没有被完全替换,所以要通过len ,获取有效的字节

public class Test05 {public static void main(String[] args) throws IOException {// 创建字节输入流(文件路径作为参数的构造方法)FileInputStream fis = new FileInputStream("day10_io/src/is.txt"); // 数据为abcde// 定义字节数组byte[] bytes = new byte[2];// 读取到字节数组数据的长度!int len;while((len=fis.read(bytes))!=-1){ // 只要没有读到文件末尾就一直读!// 每次读取的数据都放在字节数组System.out.print(new String(bytes,0,len)); // 从数组0索引位置到指定长度(读取的数据的长度,并不是数组的长度!)}// 释放资源fis.close();}
}

二、字符流

当使用字节流读取文本文件时,可能会有一个小问题。就是遇到中文字符时,可能不会显示完整的字符,那是因为一个中文字符可能占用多个字节存储。所以Java提供一些字符流类,以字符为单位读写数据,专门用于处理文本文件。

2.1 字符输入流FileReader

2.1.1 抽象父类

java.io.Reader抽象类是表示用于读取字符流的所有类的超类,可以读取字符信息到内存中。它定义了字符输入流的基本共性功能方法。

public void close()  :// 关闭此流并释放与此流相关联的任何系统资源。
public int read(): // 从输入流读取一个字符。
public int read(char[] cbuf): // 从输入流中读取一些字符,并将它们存储到字符数组 cbuf中 。

2.1.2 构造方法

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

1. 字符编码:字节与字符的对应规则。Windows系统的中文编码默认是GBK编码表。idea中UTF-8
2. 字节缓冲区:一个字节数组,用来临时存储字节数据。
FileReader(File file): 创建一个新的 FileReader ,给定要读取的File对象。
FileReader(String fileName): 创建一个新的 FileReader ,给定要读取的文件的名称。

当你创建一个流对象时,必须传入一个文件路径。类似于FileInputStream 。【传入的文件不存在,出现异常:FileNotFoundException】

/*字符输入流FileReader的构造方法:FileReader(File file): 创建一个新的 FileReader ,给定要读取的File对象。FileReader(String fileName): 创建一个新的 FileReader ,给定要读取的文件的名称。注意:文件路径字符串构建FileReader对象是,文件不存在,报错!FileNotFoundException*/
public class Test01 {public static void main(String[] args) throws FileNotFoundException {// 创建File对象File file = new File("day10_io/src/is.txt");FileReader fr = new FileReader(file);System.out.println(fr);// 文件路径的字符串构建字符输入流FileReader fileReader = new FileReader("day10_io/src/is.txt"); // 若文件不存在,异常!System.out.println(fileReader);}}

2.1.3 读取字符数据

① 读取字符:read方法,每次可以读取一个字符的数据,提升为int类型,读取到文件末尾,返回-1,循环读取[黑马程序员]

/*字符输入流FileReader读单个字符数据:int read() 读一个字符*/
public class Test02 {public static void main(String[] args) throws IOException {// 文件路径的字符串构建字符输入流FileReader fr = new FileReader("day10_io/src/is.txt");int r;while((r = fr.read())!=-1){System.out.println((char) r);}// 关闭资源fr.close();}}

② 使用字符数组读取:read(char[] cbuf),每次读取b的长度个字符到数组中,返回读取到的有效字符个数,读取到末尾时,返回-1

/*字符输入流FileReader读字符数组数据:int read​(char[] cbuf) 将字符读入数组。*/
public class Test03 {public static void main(String[] args) throws IOException {// 文件路径的字符串构建字符输入流FileReader fr = new FileReader("day10_io/src/is.txt"); // 黑马程序员// 定义字符数组char[] chars = new char[2];// 读取到字符数组中有效的字符数据的个数int len;while((len = fr.read(chars))!=-1){// 包含了无效的数据!System.out.println(new String(chars));}// 关闭资源fr.close();}}
// 运行结果:
//黑马
//程序
//员序

获得有效字符改进:

public class Test04 {public static void main(String[] args) throws IOException {// 文件路径的字符串构建字符输入流FileReader fr = new FileReader("day10_io/src/is.txt");// 定义字符数组char[] chars = new char[2];// 读取到字符数组中有效的字符数据的个数int len;while((len = fr.read(chars))!=-1){// 每次都是从数组的0索引位置到你读取到数组中有效长度的数据来构建字符串数据System.out.println(new String(chars,0,len));}// 关闭资源fr.close();}}

2.2 字符输出流FileWriter

2.2.1 抽象父类

java.io.Writer抽象类是表示用于写出字符流的所有类的超类,将指定的字符信息写出到目的地。它定义了字节输出流的基本共性功能方法。

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)  :// 写出一个字符串。

2.2.2 构造方法

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

FileWriter(File file): // 创建一个新的 FileWriter,给定要读取的File对象。
FileWriter(String fileName): // 创建一个新的 FileWriter,给定要读取的文件的名称。

当你创建一个流对象时,必须传入一个文件路径,类似于FileOutputStream。

/*字符输出流FileWriter的构造方法:FileWriter(File file): // 创建一个新的 FileWriter,给定要读取的File对象。FileWriter(String fileName): // 创建一个新的 FileWriter,给定要读取的文件的名称。注意:文件路径字符串构建FileWriter对象时,若路径中的文件不存在,不会报错,它会自动创建!*/
public class Test01 {public static void main(String[] args) throws IOException {// 创建File对象File file = new File("day10_io/src/fw.txt");FileWriter fw = new FileWriter(file);System.out.println(fw);// 路径文件字符串构建FileWriter对象FileWriter fw1 = new FileWriter("day10_io/src/fw1.txt");System.out.println(fw1);}}

2.2.3 写出字符数据

① 写出字符:write(int b) 方法,每次可以写出一个字符数据[97,b,c,30000]

/*FileWriter写出单个字符数据 【97,b,c,30000】*/
public class Test02 {public static void main(String[] args) throws IOException {// 创建对象FileWriter fw = new FileWriter("day10_io/src/fw.txt");// 写出单个字符数据fw.write(97);fw.write('b');fw.write('c');fw.write(22269);// 释放资源fw.close(); // 没有这行代码,那么数据不会到文件中!(还在内存的缓冲区!)}}
1. 虽然参数为int类型四个字节,但是只会保留一个字符的信息写出。
2. 未调用close方法,数据只是保存到了缓冲区,并未写出到文件中。

② 关闭和刷新

因为内置缓冲区的原因,如果不关闭输出流,无法写出字符到文件中。但是关闭的流对象,是无法继续写出数据的。如果我们既想写出数据,又想继续使用流,就需要flush 方法了。

flush  :// 刷新缓冲区,流对象可以继续使用。
close  :// 关闭流,释放系统资源。关闭前会刷新缓冲区。
public class Test02 {public static void main(String[] args) throws IOException {// 创建对象FileWriter fw = new FileWriter("day10_io/src/fw.txt");// 写出单个字符数据fw.write(97);fw.write('b');fw.write('c');fw.write(22269);// 先刷新内存中缓冲区的数据,然后关闭!后面不能再使用这个流对象,否则报错!Stream closed//fw.close();// 只刷新缓冲区数据,不关闭流!后面可以继续使用流对象!fw.flush();fw.write(100);fw.flush();}}

③ 写出字符数组 :write(char[] cbuf) 和 write(char[] cbuf, int off, int len) ,每次可以写出字符数组中的数据

/*FileWriter写出字符数组数据void write​(char[] cbuf) 写入一个字符数组。*/
public class Test03 {public static void main(String[] args) throws IOException {// 创建对象FileWriter fw = new FileWriter("day10_io/src/fw.txt");// 创建字符数组char[] chars = {'a','b','c','d'};// 写出字符数组数据fw.write(chars); // abcd// 释放资源!fw.close();}}
/*FileWriter写出字符数组指定数据void write​(char[] cbuf, int off, int len) 写入字符数组的一部分。  */
public class Test04 {public static void main(String[] args) throws IOException {// 创建对象FileWriter fw = new FileWriter("day10_io/src/fw.txt");// 创建字符数组char[] chars = {'a','b','c','d'};// 写出字符数组数据fw.write(chars,2,2); // cd// 释放资源!fw.close();}
}

2.2.4 写出字符串

write(String str) 和 write(String str, int off, int len) ,每次可以写出字符串中的数据

/*FileWriter写出字符串数据,以及字符串指定数据void write​(String str) 写一个字符串void write​(String str, int off, int len) 写一个字符串的一部分。*/
public class Test05 {public static void main(String[] args) throws IOException {// 创建对象FileWriter fw = new FileWriter("day10_io/src/fw.txt");// 直接写出字符串数据fw.write("黑马程序员!");// 已经具备续写能力!fw.write("666么么哒!",0,3);// 释放资源!fw.close();}
}

2.2.5 续写和换行

操作类似于FileOutputStream,在构造方法后面加一个boolean类型的参数,取值为true即可!

/*FileWriter写出字符串数据,以及字符串指定数据void write​(String str) 写一个字符串void write​(String str, int off, int len) 写一个字符串的一部分。*/
public class Test05 {public static void main(String[] args) throws IOException {// 创建对象FileWriter fw = new FileWriter("day10_io/src/fw.txt",true);// 直接写出字符串数据fw.write("\r\n");fw.write("黑马程序员!");fw.write("\r\n");// 已经具备续写能力!fw.write("666么么哒!",0,3);// 释放资源!fw.close();}}

三、缓冲流

3.1 缓冲流概述

缓冲流,也叫高效流,是对4个基本的FileXxx 流的增强,所以也是4个流,按照数据类型分类:

* 4个基本流:字节输入流:FileInputStream字节输出流:FileOutputStream字符输入流:FileReader字符输出流:FileWriter
* 4个高效流 字节缓冲流:字节输入缓冲流:BufferedInputStream字节输出缓冲流:BufferedOutputStream字符缓冲流:字符输入缓冲流:BufferedReader字符输出缓冲流:BufferedWriter

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

3.2 字节缓冲流

构造方法:

public BufferedInputStream(InputStream in)  :// 创建一个 新的缓冲输入流。【通过一个基本的字节流得到一个缓冲流】
public BufferedOutputStream(OutputStream out)://  创建一个新的缓冲输出流。

功能方法与普通的字节流一致!

测试1:使用普通字节流复制文件!

/*普通字节流复制文件!将D盘io目录下面的 jdk8.exe文件拷贝到day11_io/src/copy.exe 【文件大小为202MB】*/
public class Test01 {public static void main(String[] args) {// 创建2个流对象try (FileInputStream fis = new FileInputStream("D:/io/jdk8.exe");FileOutputStream fos = new FileOutputStream("day11_io/src/copy.exe");) {long start = System.currentTimeMillis();// 创建字节数组byte[] bt = new byte[1024];int len;while ((len = fis.read(bt)) != -1) {// 写出去fos.write(bt, 0, len);}long end = System.currentTimeMillis();System.out.println("复制完毕,消耗时间为:" + (end - start) + "毫秒!");} catch (IOException e) {e.printStackTrace();}}}// 测试结果:1723毫秒!

测试2:使用缓冲流复制文件!

/*高效字节流复制文件!将D盘io目录下面的 jdk8.exe文件拷贝到day11_io/src/copy.exe 【文件大小为202MB】*/
public class Test02 {public static void main(String[] args) {// 创建2个流对象try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D:/io/jdk8.exe"));BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("day11_io/src/copy.exe"));) {long start = System.currentTimeMillis();// 创建字节数组byte[] bt = new byte[1024];int len;while ((len = bis.read(bt)) != -1) {// 写出去bos.write(bt, 0, len);}long end = System.currentTimeMillis();System.out.println("复制完毕,消耗时间为:" + (end - start) + "毫秒!");} catch (IOException e) {e.printStackTrace();}}}
// 测试结果:413毫秒!

3.3 字符缓冲流

① 构造方法

public BufferedReader(Reader in)  :// 创建一个 新的缓冲输入流。
public BufferedWriter(Writer out): // 创建一个新的缓冲输出流。

② 额外功能方法

BufferedReader:public String readLine() : // 读一行文字。
BufferedWriter:public void newLine() : // 写一行行分隔符,由系统属性定义符号。
/*高效字符流构造方法:public BufferedReader(Reader in)  :// 创建一个 新的缓冲输入流。public BufferedWriter(Writer out): // 创建一个新的缓冲输出流。高效字符流读一行、写一行(到下一行)操作:BufferedReader:public String readLine() : // 读一行文字。BufferedWriter:public void newLine() : // 写一行行分隔符,由系统属性定义符号。*/
public class Test03 {public static void main(String[] args) {// 创建2个流对象try (BufferedReader br = new BufferedReader(new FileReader("day11_io/src/br.txt"));BufferedWriter bw = new BufferedWriter(new FileWriter("day11_io/src/bw.txt"));) {// 读到的具体某行数据!String line;while((line = br.readLine())!=null){//System.out.println(line);// 将读到的一行数据写到bw.txt文件中bw.write(line);// 写一行就换行!bw.newLine();  // 等价于:bw.write("\r\n");}} catch (IOException e) {e.printStackTrace();}}}

四、打印流

4.1 打印流概述

平时我们在控制台打印输出,是调用print方法和println方法完成的,这两个方法都来自于java.io.PrintStream类,该类能够方便地打印各种数据类型的值,是一种便捷的输出方式。

4.2 相关方法

* 构造方法:【System.out得到的这个对象,默认打印到控制台,但是可以通过构造方法的参数指定打印到指定的某个文件中去(开发基本不用的!)】public PrintStream(String fileName): 使用指定的文件名创建一个新的打印流。
* 功能方法:void print(Object obj) 打印一个对象。  void println(Object x) 打印一个对象,然后终止该行。
public class Test01 {public static void main(String[] args) throws IOException {// 通过System类的属性获得对象PrintStream ps = System.out;// 调用方法打印数据到控制台ps.print("黑马"); // 不换行!// 调用方法打印数据到控制台ps.println("666"); // 换行!// 通过PrintStream的构造方法来指定打印数据的位置PrintStream psm = new PrintStream("day11_io/src/ps.txt");// 向指定位置的文件中写出数据!psm.write("黑马666".getBytes());}}

五、装饰者设计模式

5.1 装饰者设计模式介绍

在我们今天所学的缓冲流中涉及到java的一种设计模式,叫做装饰者模式,我们来认识并学习一下这个设计模式。

装饰模式指的是在不改变原类, 不使用继承的基础上,动态地扩展一个对象的功能。

* 装饰模式遵循原则:①装饰类和被装饰类必须实现相同的接口或者继承同一个父类!②在装饰类中必须传入被装饰类的引用【构造方法】③在装饰类中对需要扩展的方法进行扩展④在装饰类中对不需要扩展的方法调用被装饰类中的同名方法

① 装饰类和被装饰类必须实现相同的接口或者继承同一个父类!

装饰类:BufferedInputStream

被装饰类:FileInputStream

② 在装饰类中必须传入被装饰类的引用【构造方法】源码分析如下:

③ 在装饰类中对需要扩展的方法进行扩展

可以使用被装饰类的对象,调用原有的方法,完成一些基础性的功能,然后再添加额外的代码完成增强的功能!

④ 在装饰类中对不需要扩展的方法调用被装饰类中的同名方法

5.2 装饰者代码演示

5.2.1 定义父接口

/*明星接口![类似于InputStream]*/
public interface Star {// 定义抽象方法void sing();// 定义默认方法default public void method(){System.out.println("不老男神!");}}

5.2.2 定义被装饰类

/*明星:歌手刘德华  【类似于FileInputStream】 被包装的类!*/
public class LiuDeHua implements Star {// 重写接口的抽象方法@Overridepublic void sing() {System.out.println("啊哈,给我一杯忘情水~");}// 重写覆盖父接口的默认方法@Overridepublic void method() {System.out.println("华仔人真好!");}}

5.2.3 定义装饰类

/*装饰类:类似于BufferedInputStream1. 装饰类与被装饰类需要实现同一个父接口或者继承同一个父类!2. 在装饰类中需要有被装饰类对象的引用3. 在需要增强的方法内部,添加新增的代码4. 在不需要增强的方法内部,直接调用被装饰类原有功能的方法即可!*/
public class LiuDeHuaWrapper implements Star{// 拥有了被装饰类对象的引用private LiuDeHua liuDeHua;// 通过装饰类的构造方法为被装饰类对象的引用赋值!public LiuDeHuaWrapper(LiuDeHua liuDeHua) {this.liuDeHua = liuDeHua;}// 要增强的方法!@Overridepublic void sing() {// 通过被装饰类对象的引用,调用原有功能!liuDeHua.sing();// 添加增强功能的代码System.out.println("换我一夜不流泪~");}// 不需要增强!@Overridepublic void method() {// 对于不需要增强的方法,直接调用被装饰类原有功能即可liuDeHua.method();}
}

5.2.4 测试类

public class Test {public static void main(String[] args) {// 创建歌手刘德华对象(被装饰类)LiuDeHua ldh = new LiuDeHua();// 调用功能//ldh.sing();// 创建装饰类的对象(需要传入被装饰类的对象)LiuDeHuaWrapper ldhw = new LiuDeHuaWrapper(ldh);// 调用方法(增强了的方法)ldhw.sing();// 调用被装饰类原有功能的方法ldhw.method();}}

总结:对于一个类中的方法进行增强,可以使用继承,还可以使用装饰者设计模式。

六、转换流

6.1 字符编码和字符集

* 字符编码Character Encoding  : 就是一套自然语言的字符与二进制数之间的对应规则。计算机中储存的信息都是用二进制数表示的,而我们在屏幕上看到的数字、英文、标点符号、汉字等字符是二进制数转换之后的结果。按照某种规则,将字符存储到计算机中,称为编码 。反之,将存储在计算机中的二进制数按照某种规则解析显示出来,称为解码 。比如说,按照A规则存储,同样按照A规则解析,那么就能显示正确的文本f符号。反之,按照A规则存储,再按照B规则解析,就会导致乱码现象。【只要编码和解码的码表一致就不会出现乱码问题!】* 字符集  Charset:也叫编码表。是一个系统支持的所有字符的集合,包括各国家文字、标点符号、图形符号、数字等。计算机要准确的存储和识别各种字符集符号,需要进行字符编码,一套字符集必然至少有一套字符编码。常见字符集有ASCII字符集、GBK字符集、Unicode字符集等。

可见,当指定了编码,它所对应的字符集自然就指定了,所以编码才是我们最终要关心的

1. ASCII字符集 :ASCII(American Standard Code for Information Interchange,美国信息交换标准代码)是基于拉丁字母的一套电脑编码系统,用于显示现代英语,主要包括控制字符(回车键、退格、换行键等)和可显示字符(英文大小写字符、阿拉伯数字和西文符号)。基本的ASCII字符集,使用7位(bits)表示一个字符,共128字符。ASCII的扩展字符集使用8位(bits)表示一个字符,共256字符,方便支持欧洲常用字符。2. ISO-8859-1字符集:拉丁码表,别名Latin-1,用于显示欧洲使用的语言,包括荷兰、丹麦、德语、意大利语、西班牙语等。ISO-5559-1使用单字节编码,兼容ASCII编码。3. GBxxx字符集:GB就是国标的意思,是为了显示中文而设计的一套字符集。①GB2312:简体中文码表。一个小于127的字符的意义与原来相同。但两个大于127的字符连在一起时,就表示一个汉字,这样大约可以组合了包含7000多个简体汉字,此外数学符号、罗马希腊的字母、日文的假名们都编进去了,连在ASCII里本来就有的数字、标点、字母都统统重新编了两个字节长的编码,这就是常说的"全角"字符,而原来在127号以下的那些就叫"半角"字符了。②GBK:最常用的中文码表。是在GB2312标准基础上的扩展规范,使用了双字节编码方案,共收录了21003个汉字,完全兼容GB2312标准,同时支持繁体汉字以及日韩汉字等。③GB18030:最新的中文码表。收录汉字70244个,采用多字节编码,每个字可以由1个、2个或4个字节组成。支持中国国内少数民族的文字,同时支持繁体汉字以及日韩汉字等。4. Unicode字符集 :Unicode编码系统为表达任意语言的任意字符而设计,是业界的一种标准,也称为统一码、标准万国码。它最多使用4个字节的数字来表达每个字母、符号,或者文字。有三种编码方案,UTF-8、UTF-16和UTF-32。最为常用的UTF-8编码。UTF-8编码,可以用来表示Unicode标准中任何字符,它是电子邮件、网页及其他存储或传送文字的应用中,优先采用的编码。互联网工程工作小组(IETF)要求所有互联网协议都必须支持UTF-8编码。所以,我们开发Web应用,也要使用UTF-8编码。它使用一至四个字节为每个字符编码,编码规则:①128个US-ASCII字符,只需一个字节编码。②拉丁文等字符,需要二个字节编码。③大部分常用字(含中文),使用三个字节编码。④其他极少使用的Unicode辅助字符,使用四字节编码。
小结:①字符集里面包含了字符编码![一套字符集至少包含了一种字符编码!] 【字符集:不同的字符集规定了里面能够出现的字符(文字)】拉丁字符集:只能存储欧美国家的文字字符!GBK字符集:只能存中国(日韩)等国家的文字字符!Unicode字符集:可以存储全世界各国文字字符!②每种字符集里面出现的字符数据最终是要存储到计算机!【它会使用对应的规则来存储: 将文字字符====>>> 二进制数据】gbk字符集将文字数据弄到计算机中!后面取出数据要保证不乱吗,要么解码就需要使用gbk!每一种存取的方式就是一种字符编码!

要想开发中能够存储所有的文字,使用utf-8编码!要想开发不出现乱码,保证编码和解码的码表一致就行!

6.2 编码引出的问题

在IDEA中,使用FileReader 读取项目中的文本文件。由于IDEA的设置,都是默认的UTF-8编码,所以没有任何问题。但是,当读取Windows系统中创建的文本文件时,由于Windows系统的默认是GBK编码,就会出现乱码。

/*读取数据gbk.txt产生中文乱码:文件编码码表:使用的是gbk程序读取码表:使用的是utf-8*/
public class Test01 {public static void main(String[] args) {try (FileReader fr = new FileReader("day11_io/src/gbk.txt");) {char[] ch = new char[1024];int len;while ((len = fr.read(ch)) != -1) {System.out.println(new String(ch, 0, len));}} catch (IOException e) {e.printStackTrace();}}}

得到的结果数据:

6.3 InputStreamReader类

转换流java.io.InputStreamReader,是Reader的子类,是从字节流到字符流的桥梁。它读取字节,并使用指定的字符集将其解码为字符。它的字符集可以由名称指定,也可以接受平台的默认字符集。

* 构造方法:InputStreamReader(InputStream in) : // 创建一个使用默认字符集的字符流。InputStreamReader(InputStream in, String charsetName) :  // 创建一个指定字符集的字符  【能够处理中文乱码问题】

指定编码读取

/*读取数据gbk.txt产生中文乱码:文件编码码表:使用的是gbk程序读取码表:使用的是utf-8我们使用转换流对象:InputStreamReader*/
public class Test02 {public static void main(String[] args) {try (// 没有指定解码的码表,默认使用utf-8的!//InputStreamReader isr = new InputStreamReader(new FileInputStream("day11_io/src/gbk.txt"));// 指定解码码表为utf-8,依旧会出现乱码!【gbk.txt文件里面使用的是gbk码表来编码的!】InputStreamReader isr = new InputStreamReader(new FileInputStream("day11_io/src/gbk.txt"),"gbk");) {char[] ch = new char[1024];int len;while ((len = isr.read(ch)) != -1) {System.out.println(new String(ch, 0, len));}} catch (IOException e) {e.printStackTrace();}}}

6.4 OutputStreamWriter类

转换流java.io.OutputStreamWriter ,是Writer的子类,是从字符流到字节流的桥梁。使用指定的字符集将字符编码为字节。它的字符集可以由名称指定,也可以接受平台的默认字符集。

* 构造方法:OutputStreamWriter(OutputStream in) : 创建一个使用默认字符集的字符流。OutputStreamWriter(OutputStream in, String charsetName) : 创建一个指定字符集的字符流。

指定编码写出

public class Test03 {public static void main(String[] args) {try (// 文件默认给定的码表是gbk,idea使用的是utf-8. 将代码写出数据的码表指定为gbk即可!OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("day11_io/src/gbk.txt"),"gbk")) {osw.write("中国Niubility");} catch (IOException e) {e.printStackTrace();}}}

默认我们在idea中使用FileReader和FileWriter操作数据是没有乱码的(代码和文件的码表都是utf-8),讲解上面的前提(文件采用的是gbk)

七、序列化流

7.1 序列化与反序列化

Java 提供了一种对象序列化的机制。用一个字节序列可以表示一个对象,该字节序列包含该对象的数据、对象的类型和对象中存储的属性等信息。字节序列写出到文件之后,相当于文件中持久保存了一个对象的信息。反之,该字节序列还可以从文件中读取回来,重构对象,对它进行反序列化。对象的数据、对象的类型和对象中存储的数据信息,都可以用来在内存中创建对象。

简言之:内存的数据到硬盘就是序列化!硬盘的数据到内存就是反序列化!

7.2 ObjectOutputStream类

java.io.ObjectOutputStream 类,将Java对象的原始数据类型写出到文件,实现对象的持久存储。

* 构造方法:public ObjectOutputStream(OutputStream out): // 创建一个指定OutputStream的ObjectOutputStream。
* 功能方法:public final void writeObject (Object obj)  : //将指定的对象写出。

要想保证对象从内存正常的序列化到硬盘中,需要确保2点:

1. 必须实现Serializable接口!【Serializable接口里面啥也没有!它是一个标记接口!能生成一个序列号出来!】
2. 要序列的数据(成员变量)不能被transient(瞬时)修饰!

/*要想这个类的对象能够正常完成序列化操作,那么:1. 必须实现Serializable接口!【Serializable接口里面啥也没有!它是一个标记接口!能生成一个序列号出来!】2. 要序列的数据(成员变量)不能被transient(瞬时)修饰!*/
public class Student implements Serializable {private static final long serialVersionUID = -2519870842411754342L;private String name;private int age;private transient String address;public Student(String name, int age, String address) {this.name = name;this.age = age;this.address = address;}public Student() {}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}
}
/*序列化测试类:*/
public class StudentDemo {public static void main(String[] args) throws IOException {// 创建对象Student student = new Student();student.setName("jack");student.setAge(38);student.setAddress("tianjin");// 创建序列化流对象ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:/io/student.txt"));oos.writeObject(student);// 关闭oos.close();}}

若类没有实现Serializable接口,会出现异常:NotSerializableException

7.3 ObjectInputStream类

ObjectInputStream反序列化流,将之前使用ObjectOutputStream序列化的原始数据恢复为对象。

* 构造方法:public ObjectInputStream(InputStream in): 创建一个指定InputStream的ObjectInputStream。
* 功能方法:public final Object readObject ()  : 读取一个对象。
/*反序列化测试类:*/
public class StudentTest {public static void main(String[] args) throws IOException, ClassNotFoundException {// 创建反序列化对象ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:/io/student.txt"));// 读数据Student s = (Student) ois.readObject();// 测试数据System.out.println(s.getName());System.out.println(s.getAge());System.out.println(s.getAddress());// 释放资源ois.close();}}

测试结果:

反序列化不成功,可能出现的问题!

* 字节码文件不存在(可能被删除了)! 【反序列化是需要根据对应的字节码文件来完成的】:出现异常: ClassNotFoundException
* 在序列化成功之后,你又修改了原来的字节码文件的数据(修改字节码对应的java文件,然后重新编译) 出现异常:InvalidClassException
* 有字节码,但是不是反序列化需要的那个字节码文件!出现异常: ClassNotFoundException* 对应的异常名称:① ClassNotFoundException② InvalidClassException

八、commons-io工具包

目前我们接触的IO流对象有:

1. inputStream
2. outputStream
3. reader
4. writer5. FileInputStream
6. FileOutputStream
7. FileReader
8. FileWriter9.  BufferedInputStream
10. BufferedOutputStream
11. BufferedReader
12. BufferedWriter13. PrintWriter14. InputStreamReader
15. OutputStreamWriter16. ObjectOutputStream
17. ObjectInputStream

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

8.1基本使用

8.1.1 使用步骤

1. 下载commons-io相关jar包;http://commons.apache.org/proper/commons-io/
2. 把commons-io-2.6.jar包复制到指定的Module的lib目录中
3. 将commons-io-2.6.jar加入到classpath中

8.1.2 常用API

commons-io提供了一个工具类 org.apache.commons.io.IOUtils,封装了大量IO读写操作的代码。其中有两个常用方法:

//  把input输入流中的内容拷贝到output输出流中,返回拷贝的字节个数(适合文件大小为2GB以下)
public static int copy(InputStream in, OutputStream out)// 把input输入流中的内容拷贝到output输出流中,返回拷贝的字节个数(适合文件大小为2GB以上)
public static long copyLarge(InputStream in, OutputStream out)

代码演示:

public class Test01 {public static void main(String[] args) {try(// 创建2个字节流对象InputStream is = new FileInputStream("D:/io/jdk8.exe");OutputStream os = new FileOutputStream("D:/io/xxx/copy.exe");){long start = System.currentTimeMillis();// 复制文件IOUtils.copy(is,os);long end = System.currentTimeMillis();System.out.println("消耗时间:" + (end-start) +"毫秒!");}catch (IOException e){e.printStackTrace();}}}

commons-io还提供了一个工具类org.apache.commons.io.FileUtils,封装了一些对文件操作的方法:

// 复制文件到另外一个目录下。
public static void copyFileToDirectory(final File srcFile, final File destFile)
// 复制file1目录到file2位置。
public static void copyDirectoryToDirectory( file1 , file2 );

代码演示:

public class Test02 {public static void main(String[] args) throws IOException {//FileUtils.copyFileToDirectory(new File("day11_io/src/fis.properties"),new File("d:/io/xxx"));FileUtils.copyDirectoryToDirectory(new File("D:/video"),new File("d:/io/xxx"));}}

IO流 输入流、输出流、字节流、字符流、转换流、及Properties类相关推荐

  1. IO流1(字节流+字符流+输入流+输出流+节点流+处理流)

    一(IO流简介) 大多数应用程序都需要实现与设备间的数据传输,如键盘输入数据.显示器显示程序运行的结果等.在Java中,将这种通过不同输入输出设备之间的数据传输抽象表述为"流",程 ...

  2. 【学习日记2023.4.9】之释放资源的方式_编解码_字符流(Reader/Writer)及其子类_转换流( [In/Out]putStreamReader)

    文章目录 1. 释放资源的方式 1.1 try-catch-finally 1.1.1 finally 格式 特点 执行时机 1.1.2 处理IO流中的异常 1.2 try-with-resource ...

  3. day22【Properties、ResourceBundle工具类、缓冲流、转换流、序列化】课上

    1.属性集(掌握,很重要) 概念介绍 1.Properties,属于双列集合,他的父类Hashtable,jdk1.0就存在了. 2.该集合没有泛型,因为该集合中的存放数据类型都是String类型 3 ...

  4. java基础 io流 字节流 字符流 节点流 包装流 转换流 缓冲流 对象流 打印流 Properties类

    目录 1.概念 2.常用的文件操作 2.1 创建文件 2.2 获取文件相关信息 2.3 目录的操作和文件删除 3. IO流原理及流的分类 3.1 流的分类 4.InputStream 字节输入流 4. ...

  5. io包下 文件类 字节流 字符流 缓冲流 转换流 序列化流 打印流

    第一章 File类 1.1 概述 java.io.File 类是文件和目录路径名的抽象表示,主要用于文件和目录的创建.查找和删除等操作. 1.2 构造方法 public File(String pat ...

  6. Java笔记整理六(File类,递归,字节流IO,字符流IO,流中的异常处理,属性集Properties,缓冲流,转换流,序列化,打印流)

    1.File类 java.io.File 类是文件和目录路径名的抽象表示,主要用于文件和目录的创建.查找和删除等操作. 文件和目录路径名的抽象表示 java把文件和文件夹封装位为一个File类,我们可 ...

  7. 让你的数据和对象有源有出路,一文打尽,Java常用IO流处理流(处理字节流文件流)缓冲流、转换流、对象流等

    文章目录 缓冲流 转换流 标准输入输出流 打印流 数据流 对象流 随机存取文件流 Java NIO 缓冲流 为了提高数据读写的速度,Java API提供了带缓冲功能的流类,在使用这些流类时,会创建一个 ...

  8. 一文读懂Java中File类、字节流、字符流、转换流

    一文读懂Java中File类.字节流.字符流.转换流 第一章 递归:File类: 1.1:概述 java.io.File 类是文件和目录路径名的抽象表示,主要用于文件和目录的创建.查找和删除等操作. ...

  9. JavaSE(字符流、IO资源的处理、属性集、ResourceBundle工具类、缓冲流、转换流、序列化、打印流、装饰设计模式、commons-io工具包)

    JavaSE 字符流 字符输入流[Reader] 字符输入流Reader类的概述 字符输入流Reader类的常用方法 FileReader类 FileReader类的概述 FileReader类的构造 ...

  10. Java - io输入输出流 --转换流

    转换流  转换输出流 OutputStreamWriter: 说明: /* * OutputStreamWriter 这个类的作用 * 就是指定输出流的编码格式 * 这个类的构造方法 需要传递 一个输 ...

最新文章

  1. python地图热力图是什么意思_python实现输入的数据在地图上生成热力图效果
  2. 谈谈密码学的数学原理
  3. 初始DDD(领域驱动设计)
  4. 参加平安的笔试+喜欢古天乐的坚持+想拍自己的电影+人生的无奈
  5. PDF电子发票解析免费版
  6. c语言什么意思000094,Hello World 背后的真实故事
  7. 基于Java的qq截图工具(毕业设计含源码)
  8. c++11后面引入的新特性(三)
  9. heic格式怎么改成jpg?
  10. php 时间转时辰,Powershell小技巧之获取当前的时间并转换为时辰
  11. 计算机专业英语中tour的意思,计算机专业英语自我介绍
  12. 小白带你学---排序算法1
  13. Java进击框架:Spring(一)
  14. android支持的视频音频硬解码器
  15. 计算机辅助培训定义,《多媒体计算机辅助教学Powerpoint课件制作培训》PPT.ppt
  16. 看恒大集团用大数据如何精准扶贫
  17. 小明买12瓶汽水,喝完后3个空瓶可以换1瓶汽水,问小明一共可以喝多少瓶汽水?
  18. 【数据压缩(五)】LZW编解码c语言实现和分析
  19. [培训-无线通信基础-9]:扩频通信(跳频、码分多址、脉冲调制)
  20. goland安装教程

热门文章

  1. C++洛谷题解(28)——P5717
  2. java虚拟机笔记—运行时数据区域
  3. IP通信中音频编解码技术与抗丢包技术概要
  4. 无聊到能吓死一湾人的鬼畜代码
  5. 福建2013年度翻译专业资格考试工作通知
  6. 压缩软件不同,如何删除压缩包密码
  7. 【毕业设计】基于springboot的小区智慧物业管理系统
  8. WebGL加载地图临时图层解决方法
  9. 招商银行信用卡卡号识别项目(第一篇),Python OpenCV 图像处理取经之旅第 53 篇
  10. edge浏览器显示无法访问此页面?(网络正常版)详细解决措施,亲测有用!