IO流 输入流、输出流、字节流、字符流、转换流、及Properties类
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类相关推荐
- IO流1(字节流+字符流+输入流+输出流+节点流+处理流)
一(IO流简介) 大多数应用程序都需要实现与设备间的数据传输,如键盘输入数据.显示器显示程序运行的结果等.在Java中,将这种通过不同输入输出设备之间的数据传输抽象表述为"流",程 ...
- 【学习日记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 ...
- day22【Properties、ResourceBundle工具类、缓冲流、转换流、序列化】课上
1.属性集(掌握,很重要) 概念介绍 1.Properties,属于双列集合,他的父类Hashtable,jdk1.0就存在了. 2.该集合没有泛型,因为该集合中的存放数据类型都是String类型 3 ...
- java基础 io流 字节流 字符流 节点流 包装流 转换流 缓冲流 对象流 打印流 Properties类
目录 1.概念 2.常用的文件操作 2.1 创建文件 2.2 获取文件相关信息 2.3 目录的操作和文件删除 3. IO流原理及流的分类 3.1 流的分类 4.InputStream 字节输入流 4. ...
- io包下 文件类 字节流 字符流 缓冲流 转换流 序列化流 打印流
第一章 File类 1.1 概述 java.io.File 类是文件和目录路径名的抽象表示,主要用于文件和目录的创建.查找和删除等操作. 1.2 构造方法 public File(String pat ...
- Java笔记整理六(File类,递归,字节流IO,字符流IO,流中的异常处理,属性集Properties,缓冲流,转换流,序列化,打印流)
1.File类 java.io.File 类是文件和目录路径名的抽象表示,主要用于文件和目录的创建.查找和删除等操作. 文件和目录路径名的抽象表示 java把文件和文件夹封装位为一个File类,我们可 ...
- 让你的数据和对象有源有出路,一文打尽,Java常用IO流处理流(处理字节流文件流)缓冲流、转换流、对象流等
文章目录 缓冲流 转换流 标准输入输出流 打印流 数据流 对象流 随机存取文件流 Java NIO 缓冲流 为了提高数据读写的速度,Java API提供了带缓冲功能的流类,在使用这些流类时,会创建一个 ...
- 一文读懂Java中File类、字节流、字符流、转换流
一文读懂Java中File类.字节流.字符流.转换流 第一章 递归:File类: 1.1:概述 java.io.File 类是文件和目录路径名的抽象表示,主要用于文件和目录的创建.查找和删除等操作. ...
- JavaSE(字符流、IO资源的处理、属性集、ResourceBundle工具类、缓冲流、转换流、序列化、打印流、装饰设计模式、commons-io工具包)
JavaSE 字符流 字符输入流[Reader] 字符输入流Reader类的概述 字符输入流Reader类的常用方法 FileReader类 FileReader类的概述 FileReader类的构造 ...
- Java - io输入输出流 --转换流
转换流 转换输出流 OutputStreamWriter: 说明: /* * OutputStreamWriter 这个类的作用 * 就是指定输出流的编码格式 * 这个类的构造方法 需要传递 一个输 ...
最新文章
- python地图热力图是什么意思_python实现输入的数据在地图上生成热力图效果
- 谈谈密码学的数学原理
- 初始DDD(领域驱动设计)
- 参加平安的笔试+喜欢古天乐的坚持+想拍自己的电影+人生的无奈
- PDF电子发票解析免费版
- c语言什么意思000094,Hello World 背后的真实故事
- 基于Java的qq截图工具(毕业设计含源码)
- c++11后面引入的新特性(三)
- heic格式怎么改成jpg?
- php 时间转时辰,Powershell小技巧之获取当前的时间并转换为时辰
- 计算机专业英语中tour的意思,计算机专业英语自我介绍
- 小白带你学---排序算法1
- Java进击框架:Spring(一)
- android支持的视频音频硬解码器
- 计算机辅助培训定义,《多媒体计算机辅助教学Powerpoint课件制作培训》PPT.ppt
- 看恒大集团用大数据如何精准扶贫
- 小明买12瓶汽水,喝完后3个空瓶可以换1瓶汽水,问小明一共可以喝多少瓶汽水?
- 【数据压缩(五)】LZW编解码c语言实现和分析
- [培训-无线通信基础-9]:扩频通信(跳频、码分多址、脉冲调制)
- goland安装教程