博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【Java】字节流与字符流,序列化与反序列化,文件编码,Properties集合
阅读量:4285 次
发布时间:2019-05-27

本文共 47198 字,大约阅读时间需要 157 分钟。

IO流的概念和分类

在这里插入图片描述

字节流

在这里插入图片描述

字节输出流OutputStream,一次写入文件一个字节

import java.io.FileOutputStream;import java.io.IOException;/*    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) :将指定的字节输出流。    java.io.FileOutputStream extends OutputStream    FileOutputStream:文件字节输出流    作用:把内存中的数据写入到硬盘的文件中    构造方法:        FileOutputStream(String name)创建一个向具有指定名称的文件中写入数据的输出文件流。        FileOutputStream(File file) 创建一个向指定 File 对象表示的文件中写入数据的文件输出流。        参数:写入数据的目的            String name:目的地是一个文件的路径            File file:目的地是一个文件        构造方法的作用:            1.创建一个FileOutputStream对象            2.会根据构造方法中传递的文件/文件路径,创建一个空的文件            3.会把FileOutputStream对象指向创建好的文件    写入数据的原理(内存-->硬盘)        java程序-->JVM(java虚拟机)-->OS(操作系统)-->OS调用写数据的方法-->把数据写入到文件中    字节输出流的使用步骤(重点):        1.创建一个FileOutputStream对象,构造方法中传递写入数据的目的地        2.调用FileOutputStream对象中的方法write,把数据写入到文件中        3.释放资源(流使用会占用一定的内存,使用完毕要把内存清空,提供程序的效率) */public class Demo01OutputStream {
public static void main(String[] args) throws IOException {
//1.创建一个FileOutputStream对象,构造方法中传递写入数据的目的地 FileOutputStream fos = new FileOutputStream("model1\\aaaabbb.txt"); //2.调用FileOutputStream对象中的方法write,把数据写入到文件中 //public abstract void write(int b) :将指定的字节输出流。 fos.write(97); //3.释放资源(流使用会占用一定的内存,使用完毕要把内存清空,提供程序的效率) //fos.close(); }}

一次写入文件多个字节

import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.util.Arrays;/*    一次写多个字节的方法:        - public void write(byte[] b):将 b.length字节从指定的字节数组写入此输出流。        - public void write(byte[] b, int off, int len) :从指定的字节数组写入 len字节,从偏移量 off开始输出到此输出流。 */public class Demo02OutputStream {
public static void main(String[] args) throws IOException {
//创建FileOutputStream对象,构造方法中绑定要写入数据的目的地 FileOutputStream fos = new FileOutputStream(new File("09_IOAndProperties\\b.txt")); //调用FileOutputStream对象中的方法write,把数据写入到文件中 //在文件中显示100,写个字节 fos.write(49); fos.write(48); fos.write(48); /* public void write(byte[] b):将 b.length字节从指定的字节数组写入此输出流。 一次写多个字节: 如果写的第一个字节是正数(0-127),那么显示的时候会查询ASCII表 如果写的第一个字节是负数,那第一个字节会和第二个字节,两个字节组成一个中文显示,查询系统默认码表(GBK) */ byte[] bytes = {
65,66,67,68,69};//ABCDE //byte[] bytes = {-65,-66,-67,68,69};//烤紻E fos.write(bytes); /* public void write(byte[] b, int off, int len) :把字节数组的一部分写入到文件中 int off:数组的开始索引 int len:写几个字节 */ fos.write(bytes,1,2);//BC /* 写入字符的方法:可以使用String类中的方法把字符串,转换为字节数组 byte[] getBytes() 把字符串转换为字节数组 */ byte[] bytes2 = "你好".getBytes(); System.out.println(Arrays.toString(bytes2));//[-28, -67, -96, -27, -91, -67] fos.write(bytes2); //释放资源 fos.close(); }}

追加模式

import java.io.FileOutputStream;import java.io.IOException;/*    追加写/续写:使用两个参数的构造方法        FileOutputStream(String name, boolean append)创建一个向具有指定 name 的文件中写入数据的输出文件流。        FileOutputStream(File file, boolean append) 创建一个向指定 File 对象表示的文件中写入数据的文件输出流。        参数:           String name,File file:写入数据的目的地           boolean append:追加写开关            true:创建对象不会覆盖源文件,继续在文件的末尾追加写数据            false:创建一个新文件,覆盖源文件    写换行:写换行符号        windows:\r\n        linux:/n        mac:/r */public class Demo03OutputStream {
public static void main(String[] args) throws IOException {
FileOutputStream fos = new FileOutputStream("09_IOAndProperties\\c.txt",true); for (int i = 1; i <=10 ; i++) {
fos.write("你好".getBytes()); fos.write("\r\n".getBytes()); } fos.close(); }}

字节输入流InputStream,一次读取一个字节

在这里插入图片描述

import java.io.FileInputStream;import java.io.IOException;/*    java.io.InputStream:字节输入流    此抽象类是表示字节输入流的所有类的超类。    定义了所有子类共性的方法:         int read()从输入流中读取数据的下一个字节。         int read(byte[] b) 从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。         void close() 关闭此输入流并释放与该流关联的所有系统资源。    java.io.FileInputStream extends InputStream    FileInputStream:文件字节输入流    作用:把硬盘文件中的数据,读取到内存中使用    构造方法:        FileInputStream(String name)        FileInputStream(File file)        参数:读取文件的数据源            String name:文件的路径            File file:文件        构造方法的作用:            1.会创建一个FileInputStream对象            2.会把FileInputStream对象指定构造方法中要读取的文件    读取数据的原理(硬盘-->内存)        java程序-->JVM-->OS-->OS读取数据的方法-->读取文件    字节输入流的使用步骤(重点):        1.创建FileInputStream对象,构造方法中绑定要读取的数据源        2.使用FileInputStream对象中的方法read,读取文件        3.释放资源 */public class Demo01InputStream {
public static void main(String[] args) throws IOException {
//1.创建FileInputStream对象,构造方法中绑定要读取的数据源 FileInputStream fis = new FileInputStream("./c.txt"); //2.使用FileInputStream对象中的方法read,读取文件 //int read()读取文件中的一个字节并返回,读取到文件的末尾返回-1 /*int len = fis.read(); System.out.println(len);//97 a len = fis.read(); System.out.println(len);// 98 b len = fis.read(); System.out.println(len);//99 c len = fis.read(); System.out.println(len);//-1 len = fis.read(); System.out.println(len);//-1*/ /* 发现以上读取文件是一个重复的过程,所以可以使用循环优化 不知道文件中有多少字节,使用while循环 while循环结束条件,读取到-1的时候结束 布尔表达式(len = fis.read())!=-1 1.fis.read():读取一个字节 2.len = fis.read():把读取到的字节赋值给变量len 3.(len = fis.read())!=-1:判断变量len是否不等于-1 */ int len = 0; //记录读取到的字节 while((len = fis.read())!=-1){
System.out.print(len);//abc } //3.释放资源 fis.close(); }}

一次读取多个字节

import java.io.FileInputStream;import java.io.IOException;/*    字节输入流一次读取多个字节的方法:        int read(byte[] b) 从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。    明确两件事情:        1.方法的参数byte[]的作用?            起到缓冲作用,存储每次读取到的多个字节            数组的长度一把定义为1024(1kb)或者1024的整数倍        2.方法的返回值int是什么?            每次读取的有效字节个数    String类的构造方法        String(byte[] bytes) :把字节数组转换为字符串        String(byte[] bytes, int offset, int length) 把字节数组的一部分转换为字符串 offset:数组的开始索引 length:转换的字节个数 */public class Demo02InputStream {
public static void main(String[] args) throws IOException {
//创建FileInputStream对象,构造方法中绑定要读取的数据源 FileInputStream fis = new FileInputStream("09_IOAndProperties\\b.txt"); //使用FileInputStream对象中的方法read读取文件 //int read(byte[] b) 从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。 /*byte[] bytes = new byte[2]; int len = fis.read(bytes); System.out.println(len);//2 //System.out.println(Arrays.toString(bytes));//[65, 66] System.out.println(new String(bytes));//AB len = fis.read(bytes); System.out.println(len);//2 System.out.println(new String(bytes));//CD len = fis.read(bytes); System.out.println(len);//1 System.out.println(new String(bytes));//ED len = fis.read(bytes); System.out.println(len);//-1 System.out.println(new String(bytes));//ED*/ /* 发现以上读取时一个重复的过程,可以使用循环优化 不知道文件中有多少字节,所以使用while循环 while循环结束的条件,读取到-1结束 */ byte[] bytes = new byte[1024];//存储读取到的多个字节 int len = 0; //记录每次读取的有效字节个数 while((len = fis.read(bytes))!=-1){
//String(byte[] bytes, int offset, int length) 把字节数组的一部分转换为字符串 offset:数组的开始索引 length:转换的字节个数 System.out.println(new String(bytes,0,len)); } //释放资源 fis.close(); }}

文件复制练习

在这里插入图片描述

import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;/*    文件复制练习:一读一写    明确:        数据源: c:\\1.jpg        数据的目的地: d:\\1.jpg    文件复制的步骤:        1.创建一个字节输入流对象,构造方法中绑定要读取的数据源        2.创建一个字节输出流对象,构造方法中绑定要写入的目的地        3.使用字节输入流对象中的方法read读取文件        4.使用字节输出流中的方法write,把读取到的字节写入到目的地的文件中        5.释放资源 */public class Demo01CopyFile {
public static void main(String[] args) throws IOException {
long s = System.currentTimeMillis(); //1.创建一个字节输入流对象,构造方法中绑定要读取的数据源 FileInputStream fis = new FileInputStream("c:\\1.jpg"); //2.创建一个字节输出流对象,构造方法中绑定要写入的目的地 FileOutputStream fos = new FileOutputStream("d:\\1.jpg"); //一次读取一个字节写入一个字节的方式 //3.使用字节输入流对象中的方法read读取文件 /*int len = 0; while((len = fis.read())!=-1){ //4.使用字节输出流中的方法write,把读取到的字节写入到目的地的文件中 fos.write(len); }*/ //使用数组缓冲读取多个字节,写入多个字节 byte[] bytes = new byte[1024]; //3.使用字节输入流对象中的方法read读取文件 int len = 0;//每次读取的有效字节个数 while((len = fis.read(bytes))!=-1){
//4.使用字节输出流中的方法write,把读取到的字节写入到目的地的文件中 fos.write(bytes,0,len); } //5.释放资源(先关写的,后关闭读的;如果写完了,肯定读取完毕了) fos.close(); fis.close(); long e = System.currentTimeMillis(); System.out.println("复制文件共耗时:"+(e-s)+"毫秒"); }}

字符流

字节流和字符流的区别,一个中文在GBK编码占两个字节,UTF-8占用3个字节。在字节流模式下如果中文字节读取不完整,那么就无法正常显示,可以使用字符流读取

import java.io.FileInputStream;import java.io.IOException;/*    使用字节流读取中文文件    1个中文        GBK:占用两个字节        UTF-8:占用3个字节 */public class Demo01InputStream {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("09_IOAndProperties\\c.txt"); int len = 0; while((len = fis.read())!=-1){
System.out.println((char)len); } fis.close(); }}

字符输入流Reader

import java.io.FileReader;import java.io.IOException;/*    java.io.Reader:字符输入流,是字符输入流的最顶层的父类,定义了一些共性的成员方法,是一个抽象类    共性的成员方法:        int read() 读取单个字符并返回。        int read(char[] cbuf)一次读取多个字符,将字符读入数组。        void close() 关闭该流并释放与之关联的所有资源。    java.io.FileReader extends InputStreamReader extends Reader    FileReader:文件字符输入流    作用:把硬盘文件中的数据以字符的方式读取到内存中    构造方法:        FileReader(String fileName)        FileReader(File file)        参数:读取文件的数据源            String fileName:文件的路径            File file:一个文件        FileReader构造方法的作用:            1.创建一个FileReader对象            2.会把FileReader对象指向要读取的文件    字符输入流的使用步骤:        1.创建FileReader对象,构造方法中绑定要读取的数据源        2.使用FileReader对象中的方法read读取文件        3.释放资源 */public class Demo02Reader {
public static void main(String[] args) throws IOException {
//1.创建FileReader对象,构造方法中绑定要读取的数据源 FileReader fr = new FileReader("1.txt"); //2.使用FileReader对象中的方法read读取文件 //int read() 读取单个字符并返回。 /*int len = 0; //while((len = fr.read())!=-1){ // System.out.print((char)len); //直接输出为整型数字,需要转换为字符型 } */ //int read(char[] cbuf)一次读取多个字符,将字符读入数组。 char[] cs = new char[1024];//存储读取到的多个字符 int len = 0;//记录的是每次读取的有效字符个数 while ((len = fr.read(cs)) != -1) {
/* String类的构造方法 String(char[] value) 把字符数组转换为字符串 String(char[] value, int offset, int count) 把字符数组的一部分转换为字符串 offset数组的开始索引 count转换的个数 */ System.out.println(new String(cs, 0, len)); } //3.释放资源 fr.close(); }}

字符输出流Writer

import java.io.FileWriter;import java.io.IOException;/*    java.io.Writer:字符输出流,是所有字符输出流的最顶层的父类,是一个抽象类    共性的成员方法:        - void write(int c) 写入单个字符。        - void write(char[] cbuf)写入字符数组。        - abstract  void write(char[] cbuf, int off, int len)写入字符数组的某一部分,off数组的开始索引,len写的字符个数。        - void write(String str)写入字符串。        - void write(String str, int off, int len) 写入字符串的某一部分,off字符串的开始索引,len写的字符个数。        - void flush()刷新该流的缓冲。        - void close() 关闭此流,但要先刷新它。    java.io.FileWriter extends OutputStreamWriter extends Writer    FileWriter:文件字符输出流    作用:把内存中字符数据写入到文件中    构造方法:        FileWriter(File file)根据给定的 File 对象构造一个 FileWriter 对象。        FileWriter(String fileName) 根据给定的文件名构造一个 FileWriter 对象。        参数:写入数据的目的地            String fileName:文件的路径            File file:是一个文件        构造方法的作用:            1.会创建一个FileWriter对象            2.会根据构造方法中传递的文件/文件的路径,创建文件            3.会把FileWriter对象指向创建好的文件    字符输出流的使用步骤(重点):        1.创建FileWriter对象,构造方法中绑定要写入数据的目的地        2.使用FileWriter中的方法write,把数据写入到内存缓冲区中(字符转换为字节的过程)        3.使用FileWriter中的方法flush,把内存缓冲区中的数据,刷新到文件中        4.释放资源(会先把内存缓冲区中的数据刷新到文件中) */public class Demo01Writer {
public static void main(String[] args) throws IOException {
//1.创建FileWriter对象,构造方法中绑定要写入数据的目的地 FileWriter fw = new FileWriter("09_IOAndProperties\\d.txt"); //2.使用FileWriter中的方法write,把数据写入到内存缓冲区中(字符转换为字节的过程) //void write(int c) 写入单个字符。 fw.write(97); //3.使用FileWriter中的方法flush,把内存缓冲区中的数据,刷新到文件中 //fw.flush(); //4.释放资源(会先把内存缓冲区中的数据刷新到文件中) fw.close(); }}

flush方法和close方法,对于字符流进行写操作,是写进内存,再写进硬盘,可用flush方法先将部分数据写进硬盘

import java.io.FileWriter;import java.io.IOException;/*    flush方法和close方法的区别        - flush :刷新缓冲区,流对象可以继续使用。        - close:  先刷新缓冲区,然后通知系统释放资源。流对象不可以再被使用了。 */public class Demo02CloseAndFlush {
public static void main(String[] args) throws IOException {
//1.创建FileWriter对象,构造方法中绑定要写入数据的目的地 FileWriter fw = new FileWriter("09_IOAndProperties\\e.txt"); //2.使用FileWriter中的方法write,把数据写入到内存缓冲区中(字符转换为字节的过程) //void write(int c) 写入单个字符。 fw.write(97); //3.使用FileWriter中的方法flush,把内存缓冲区中的数据,刷新到文件中 fw.flush(); //刷新之后流可以继续使用 fw.write(98); //4.释放资源(会先把内存缓冲区中的数据刷新到文件中) fw.close(); //close方法之后流已经关闭了,已经从内存中消失了,流就不能再使用了 fw.write(99);//IOException: Stream closed }}

字符输出流写数据的其他方法

import java.io.FileWriter;import java.io.IOException;/*    字符输出流写数据的其他方法        - void write(char[] cbuf)写入字符数组。        - abstract  void write(char[] cbuf, int off, int len)写入字符数组的某一部分,off数组的开始索引,len写的字符个数。        - void write(String str)写入字符串。        - void write(String str, int off, int len) 写入字符串的某一部分,off字符串的开始索引,len写的字符个数。 */public class Demo03Writer {
public static void main(String[] args) throws IOException {
FileWriter fw = new FileWriter("f.txt"); char[] cs = {
'a','b','c','d','e'}; //void write(char[] cbuf)写入字符数组。 fw.write(cs);//abcde //void write(char[] cbuf, int off, int len)写入字符数组的某一部分,off数组的开始索引,len写的字符个数。 fw.write(cs,1,3);//bcd //void write(String str)写入字符串。 fw.write("传智播客");//传智播客 //void write(String str, int off, int len) 写入字符串的某一部分,off字符串的开始索引,len写的字符个数。 fw.write("黑马程序员",2,3);//程序员 fw.close(); }}

字符流追加模式

import java.io.FileWriter;import java.io.IOException;/*    续写和换行    续写,追加写:使用两个参数的构造方法        FileWriter(String fileName, boolean append)        FileWriter(File file, boolean append)        参数:            String fileName,File file:写入数据的目的地            boolean append:续写开关 true:不会创建新的文件覆盖源文件,可以续写; false:创建新的文件覆盖源文件     换行:换行符号        windows:\r\n        linux:/n        mac:/r */public class Demo04Writer {
public static void main(String[] args) throws IOException {
FileWriter fw = new FileWriter("model1\\g.txt",true); for (int i = 0; i <10 ; i++) {
fw.write("HelloWorld"+i+"\n"); } fw.close(); }}

不同JDK版本下的读写异常处理

import java.io.FileWriter;import java.io.IOException;/*    在jdk1.7之前使用try catch finally 处理流中的异常    格式:        try{            可能会产出异常的代码        }catch(异常类变量 变量名){            异常的处理逻辑        }finally{            一定会指定的代码            资源释放        } */public class Demo01TryCatch {
public static void main(String[] args) {
//提高变量fw的作用域,让finally可以使用 //变量在定义的时候,可以没有值,但是使用的时候必须有值 //fw = new FileWriter("09_IOAndProperties\\g.txt",true); 执行失败,fw没有值,fw.close会报错 FileWriter fw = null; try{
//可能会产出异常的代码 fw = new FileWriter("w:\\09_IOAndProperties\\g.txt",true); for (int i = 0; i <10 ; i++) {
fw.write("HelloWorld"+i+"\r\n"); } }catch(IOException e){
//异常的处理逻辑 System.out.println(e); }finally {
//一定会指定的代码 //创建对象失败了,fw的默认值就是null,null是不能调用方法的,会抛出NullPointerException,需要增加一个判断,不是null在把资源释放 if(fw!=null){
try {
//fw.close方法声明抛出了IOException异常对象,所以我们就的处理这个异常对象,要么throws,要么try catch fw.close(); } catch (IOException e) {
e.printStackTrace(); } } } }}

JDK7的新特性

import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;/*    JDK7的新特性    在try的后边可以增加一个(),在括号中可以定义流对象    那么这个流对象的作用域就在try中有效    try中的代码执行完毕,会自动把流对象释放,不用写finally    格式:        try(定义流对象;定义流对象....){            可能会产出异常的代码        }catch(异常类变量 变量名){            异常的处理逻辑        } */public class Demo02JDK7 {
public static void main(String[] args) {
try(//1.创建一个字节输入流对象,构造方法中绑定要读取的数据源 FileInputStream fis = new FileInputStream("c:\\1.jpg"); //2.创建一个字节输出流对象,构造方法中绑定要写入的目的地 FileOutputStream fos = new FileOutputStream("d:\\1.jpg");){
//可能会产出异常的代码 //一次读取一个字节写入一个字节的方式 //3.使用字节输入流对象中的方法read读取文件 int len = 0; while((len = fis.read())!=-1){
//4.使用字节输出流中的方法write,把读取到的字节写入到目的地的文件中 fos.write(len); } }catch (IOException e){
//异常的处理逻辑 System.out.println(e); } }}

JDK9的新特性

import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;/*    JDK9新特性    try的前边可以定义流对象    在try后边的()中可以直接引入流对象的名称(变量名)    在try代码执行完毕之后,流对象也可以释放掉,不用写finally    格式:        A a = new A();        B b = new B();        try(a,b){            可能会产出异常的代码        }catch(异常类变量 变量名){            异常的处理逻辑        } */public class Demo03JDK9 {
public static void main(String[] args) throws IOException {
//1.创建一个字节输入流对象,构造方法中绑定要读取的数据源 FileInputStream fis = new FileInputStream("c:\\1.jpg"); //2.创建一个字节输出流对象,构造方法中绑定要写入的目的地 FileOutputStream fos = new FileOutputStream("d:\\1.jpg"); try(fis;fos){
//一次读取一个字节写入一个字节的方式 //3.使用字节输入流对象中的方法read读取文件 int len = 0; while((len = fis.read())!=-1){
//4.使用字节输出流中的方法write,把读取到的字节写入到目的地的文件中 fos.write(len); } }catch (IOException e){
System.out.println(e); } //fos.write(1);//Stream Closed }}

Properties集合

与IO流进行集合

import java.io.FileOutputStream;import java.io.FileReader;import java.io.IOException;import java.util.Properties;import java.util.Set;/*    java.util.Properties集合 extends Hashtable
implements Map
Properties 类表示了一个持久的属性集。Properties 可保存在流中或从流中加载。 Properties集合是一个唯一和IO流相结合的集合 可以使用Properties集合中的方法store,把集合中的临时数据,持久化写入到硬盘中存储 可以使用Properties集合中的方法load,把硬盘中保存的文件(键值对),读取到集合中使用 属性列表中每个键及其对应值都是一个字符串。 Properties集合是一个双列集合,key和value默认都是字符串 */public class Demo01Properties {
public static void main(String[] args) throws IOException {
show03(); } /* 可以使用Properties集合中的方法load,把硬盘中保存的文件(键值对),读取到集合中使用 void load(InputStream inStream) void load(Reader reader) 参数: InputStream inStream:字节输入流,不能读取含有中文的键值对 Reader reader:字符输入流,能读取含有中文的键值对 使用步骤: 1.创建Properties集合对象 2.使用Properties集合对象中的方法load读取保存键值对的文件 3.遍历Properties集合 注意: 1.存储键值对的文件中,键与值默认的连接符号可以使用=,空格(其他符号) 2.存储键值对的文件中,可以使用#进行注释,被注释的键值对不会再被读取 3.存储键值对的文件中,键与值默认都是字符串,不用再加引号 */ private static void show03() throws IOException {
//1.创建Properties集合对象 Properties prop = new Properties(); //2.使用Properties集合对象中的方法load读取保存键值对的文件 prop.load(new FileReader("09_IOAndProperties\\prop.txt")); //prop.load(new FileInputStream("09_IOAndProperties\\prop.txt")); //3.遍历Properties集合 Set
set = prop.stringPropertyNames(); for (String key : set) {
String value = prop.getProperty(key); System.out.println(key+"="+value); } } /* 可以使用Properties集合中的方法store,把集合中的临时数据,持久化写入到硬盘中存储 void store(OutputStream out, String comments) void store(Writer writer, String comments) 参数: OutputStream out:字节输出流,不能写入中文 Writer writer:字符输出流,可以写中文 String comments:注释,用来解释说明保存的文件是做什么用的 不能使用中文,会产生乱码,默认是Unicode编码 一般使用""空字符串 使用步骤: 1.创建Properties集合对象,添加数据 2.创建字节输出流/字符输出流对象,构造方法中绑定要输出的目的地 3.使用Properties集合中的方法store,把集合中的临时数据,持久化写入到硬盘中存储 4.释放资源 */ private static void show02() throws IOException {
//1.创建Properties集合对象,添加数据 Properties prop = new Properties(); prop.setProperty("赵丽颖","168"); prop.setProperty("迪丽热巴","165"); prop.setProperty("古力娜扎","160"); //2.创建字节输出流/字符输出流对象,构造方法中绑定要输出的目的地 //FileWriter fw = new FileWriter("09_IOAndProperties\\prop.txt"); //3.使用Properties集合中的方法store,把集合中的临时数据,持久化写入到硬盘中存储 //prop.store(fw,"save data"); //4.释放资源 //fw.close(); prop.store(new FileOutputStream("09_IOAndProperties\\prop2.txt"),""); //不能写中文 } /* 使用Properties集合存储数据,遍历取出Properties集合中的数据 Properties集合是一个双列集合,key和value默认都是字符串 Properties集合有一些操作字符串的特有方法 Object setProperty(String key, String value) 调用 Hashtable 的方法 put。 String getProperty(String key) 通过key找到value值,此方法相当于Map集合中的get(key)方法 Set
stringPropertyNames() 返回此属性列表中的键集,其中该键及其对应值是字符串,此方法相当于Map集合中的keySet方法 */ private static void show01() {
//创建Properties集合对象 Properties prop = new Properties(); //使用setProperty往集合中添加数据 prop.setProperty("赵丽颖","168"); prop.setProperty("迪丽热巴","165"); prop.setProperty("古力娜扎","160"); //prop.put(1,true); //使用stringPropertyNames把Properties集合中的键取出,存储到一个Set集合中 Set
set = prop.stringPropertyNames(); //遍历Set集合,取出Properties集合的每一个键 for (String key : set) {
//使用getProperty方法通过key获取value String value = prop.getProperty(key); System.out.println(key+"="+value); } }}

注意上述代码的prop.txt和prop2.txt内容如下

prop.txt

#save data#Sun Aug 08 07:39:28 CST 2088赵丽颖=168迪丽热巴 165#古力娜扎=160

prop2.txt

##Sun Aug 08 07:40:33 CST 2088\u8D75\u4E3D\u9896=168\u8FEA\u4E3D\u70ED\u5DF4=165\u53E4\u529B\u5A1C\u624E=160

字节缓冲输出流

在这里插入图片描述

import java.io.BufferedOutputStream;import java.io.FileOutputStream;import java.io.IOException;/*    java.io.BufferedOutputStream extends OutputStream    BufferedOutputStream:字节缓冲输出流    继承自父类的共性成员方法:        - 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) :将指定的字节输出流。     构造方法:        BufferedOutputStream(OutputStream out)  创建一个新的缓冲输出流,以将数据写入指定的底层输出流。        BufferedOutputStream(OutputStream out, int size)  创建一个新的缓冲输出流,以将具有指定缓冲区大小的数据写入指定的底层输出流。        参数:           OutputStream out:字节输出流                我们可以传递FileOutputStream,缓冲流会给FileOutputStream增加一个缓冲区,提高FileOutputStream的写入效率           int size:指定缓冲流内部缓冲区的大小,不指定默认     使用步骤(重点)        1.创建FileOutputStream对象,构造方法中绑定要输出的目的地        2.创建BufferedOutputStream对象,构造方法中传递FileOutputStream对象对象,提高FileOutputStream对象效率        3.使用BufferedOutputStream对象中的方法write,把数据写入到内部缓冲区中        4.使用BufferedOutputStream对象中的方法flush,把内部缓冲区中的数据,刷新到文件中        5.释放资源(会先调用flush方法刷新数据,第4部可以省略) */public class Demo01BufferedOutputStream {
public static void main(String[] args) throws IOException {
//1.创建FileOutputStream对象,构造方法中绑定要输出的目的地 FileOutputStream fos = new FileOutputStream("10_IO\\a.txt"); //2.创建BufferedOutputStream对象,构造方法中传递FileOutputStream对象对象,提高FileOutputStream对象效率 BufferedOutputStream bos = new BufferedOutputStream(fos); //3.使用BufferedOutputStream对象中的方法write,把数据写入到内部缓冲区中 bos.write("我把数据写入到内部缓冲区中".getBytes()); //4.使用BufferedOutputStream对象中的方法flush,把内部缓冲区中的数据,刷新到文件中 bos.flush(); //5.释放资源(会先调用flush方法刷新数据,第4部可以省略) bos.close(); }}

字节缓冲输入流

import java.io.BufferedInputStream;import java.io.FileInputStream;import java.io.IOException;/*    java.io.BufferedInputStream extends InputStream    BufferedInputStream:字节缓冲输入流    继承自父类的成员方法:        int read()从输入流中读取数据的下一个字节。        int read(byte[] b) 从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。        void close() 关闭此输入流并释放与该流关联的所有系统资源。    构造方法:        BufferedInputStream(InputStream in) 创建一个 BufferedInputStream 并保存其参数,即输入流 in,以便将来使用。        BufferedInputStream(InputStream in, int size) 创建具有指定缓冲区大小的 BufferedInputStream 并保存其参数,即输入流 in,以便将来使用。        参数:            InputStream in:字节输入流                我们可以传递FileInputStream,缓冲流会给FileInputStream增加一个缓冲区,提高FileInputStream的读取效率            int size:指定缓冲流内部缓冲区的大小,不指定默认    使用步骤(重点):        1.创建FileInputStream对象,构造方法中绑定要读取的数据源        2.创建BufferedInputStream对象,构造方法中传递FileInputStream对象,提高FileInputStream对象的读取效率        3.使用BufferedInputStream对象中的方法read,读取文件        4.释放资源 */public class Demo02BufferedInputStream {
public static void main(String[] args) throws IOException {
//1.创建FileInputStream对象,构造方法中绑定要读取的数据源 FileInputStream fis = new FileInputStream("10_IO\\a.txt"); //2.创建BufferedInputStream对象,构造方法中传递FileInputStream对象,提高FileInputStream对象的读取效率 BufferedInputStream bis = new BufferedInputStream(fis); //3.使用BufferedInputStream对象中的方法read,读取文件 //int read()从输入流中读取数据的下一个字节。 /*int len = 0;//记录每次读取到的字节 while((len = bis.read())!=-1){ System.out.println(len); }*/ //int read(byte[] b) 从输入流中读取一定数量的字节,并将其存储在缓冲区数组 b 中。 byte[] bytes =new byte[1024];//存储每次读取的数据 int len = 0; //记录每次读取的有效字节个数 while((len = bis.read(bytes))!=-1){
System.out.println(new String(bytes,0,len)); } //4.释放资源 bis.close(); }}

字符缓冲输出流

import java.io.BufferedWriter;import java.io.FileWriter;import java.io.IOException;/*    java.io.BufferedWriter extends Writer    BufferedWriter:字符缓冲输出流    继承自父类的共性成员方法:        - void write(int c) 写入单个字符。        - void write(char[] cbuf)写入字符数组。        - abstract  void write(char[] cbuf, int off, int len)写入字符数组的某一部分,off数组的开始索引,len写的字符个数。        - void write(String str)写入字符串。        - void write(String str, int off, int len) 写入字符串的某一部分,off字符串的开始索引,len写的字符个数。        - void flush()刷新该流的缓冲。        - void close() 关闭此流,但要先刷新它。    构造方法:        BufferedWriter(Writer out) 创建一个使用默认大小输出缓冲区的缓冲字符输出流。        BufferedWriter(Writer out, int sz) 创建一个使用给定大小输出缓冲区的新缓冲字符输出流。        参数:            Writer out:字符输出流                我们可以传递FileWriter,缓冲流会给FileWriter增加一个缓冲区,提高FileWriter的写入效率            int sz:指定缓冲区的大小,不写默认大小    特有的成员方法:        void newLine() 写入一个行分隔符。会根据不同的操作系统,获取不同的行分隔符        换行:换行符号        windows:\r\n        linux:/n        mac:/r     使用步骤:        1.创建字符缓冲输出流对象,构造方法中传递字符输出流        2.调用字符缓冲输出流中的方法write,把数据写入到内存缓冲区中        3.调用字符缓冲输出流中的方法flush,把内存缓冲区中的数据,刷新到文件中        4.释放资源 */public class Demo03BufferedWriter {
public static void main(String[] args) throws IOException {
//System.out.println(); //1.创建字符缓冲输出流对象,构造方法中传递字符输出流 BufferedWriter bw = new BufferedWriter(new FileWriter("10_IO\\c.txt")); //2.调用字符缓冲输出流中的方法write,把数据写入到内存缓冲区中 for (int i = 0; i <10 ; i++) {
bw.write("传智播客"); //bw.write("\r\n"); bw.newLine(); } //3.调用字符缓冲输出流中的方法flush,把内存缓冲区中的数据,刷新到文件中 bw.flush(); //4.释放资源 bw.close(); }}

字符缓冲输入流

import java.io.BufferedReader;import java.io.FileReader;import java.io.IOException;/*    java.io.BufferedReader extends Reader    BufferedReader:字符缓冲输入流    继承自父类的共性成员方法:        int read() 读取单个字符并返回。        int read(char[] cbuf)一次读取多个字符,将字符读入数组。        void close() 关闭该流并释放与之关联的所有资源。     构造方法:        BufferedReader(Reader in)  创建一个使用默认大小输入缓冲区的缓冲字符输入流。        BufferedReader(Reader in, int sz)     创建一个使用指定大小输入缓冲区的缓冲字符输入流。        参数:            Reader in:字符输入流                我们可以传递FileReader,缓冲流会给FileReader增加一个缓冲区,提高FileReader的读取效率     特有的成员方法:        String readLine() 读取一个文本行。读取一行数据            行的终止符号:通过下列字符之一即可认为某行已终止:换行 ('\n')、回车 ('\r') 或回车后直接跟着换行(\r\n)。        返回值:            包含该行内容的字符串,不包含任何行终止符,如果已到达流末尾,则返回 null     使用步骤:        1.创建字符缓冲输入流对象,构造方法中传递字符输入流        2.使用字符缓冲输入流对象中的方法read/readLine读取文本        3.释放资源 */public class Demo04BufferedReader {
public static void main(String[] args) throws IOException {
//1.创建字符缓冲输入流对象,构造方法中传递字符输入流 BufferedReader br = new BufferedReader(new FileReader("10_IO\\c.txt")); //2.使用字符缓冲输入流对象中的方法read/readLine读取文本 /*String line = br.readLine(); System.out.println(line); line = br.readLine(); System.out.println(line); line = br.readLine(); System.out.println(line); line = br.readLine(); System.out.println(line);*/ /* 发下以上读取是一个重复的过程,所以可以使用循环优化 不知道文件中有多少行数据,所以使用while循环 while的结束条件,读取到null结束 */ String line; while((line = br.readLine())!=null){
System.out.println(line); } //3.释放资源 br.close(); }}

练习:对文本内容进行排序

在这里插入图片描述

import java.io.*;import java.util.HashMap;/*    练习:        对文本的内容进行排序        按照(1,2,3....)顺序排序    分析:        1.创建一个HashMap集合对象,可以:存储每行文本的序号(1,2,3,..);value:存储每行的文本        2.创建字符缓冲输入流对象,构造方法中绑定字符输入流        3.创建字符缓冲输出流对象,构造方法中绑定字符输出流        4.使用字符缓冲输入流中的方法readline,逐行读取文本        5.对读取到的文本进行切割,获取行中的序号和文本内容        6.把切割好的序号和文本的内容存储到HashMap集合中(key序号是有序的,会自动排序1,2,3,4..)        7.遍历HashMap集合,获取每一个键值对        8.把每一个键值对,拼接为一个文本行        9.把拼接好的文本,使用字符缓冲输出流中的方法write,写入到文件中        10.释放资源 */public class Demo05Test {
public static void main(String[] args) throws IOException {
//1.创建一个HashMap集合对象,可以:存储每行文本的序号(1,2,3,..);value:存储每行的文本 HashMap
map = new HashMap<>(); //2.创建字符缓冲输入流对象,构造方法中绑定字符输入流 BufferedReader br = new BufferedReader(new FileReader("10_IO\\in.txt")); //3.创建字符缓冲输出流对象,构造方法中绑定字符输出流 BufferedWriter bw = new BufferedWriter(new FileWriter("10_IO\\out.txt")); //4.使用字符缓冲输入流中的方法readline,逐行读取文本 String line; while((line = br.readLine())!=null){
//5.对读取到的文本进行切割,获取行中的序号和文本内容 String[] arr = line.split("\\."); //6.把切割好的序号和文本的内容存储到HashMap集合中(key序号是有序的,会自动排序1,2,3,4..) map.put(arr[0],arr[1]); } //7.遍历HashMap集合,获取每一个键值对 for(String key : map.keySet()){
String value = map.get(key); //8.把每一个键值对,拼接为一个文本行 line = key + "." + value; //9.把拼接好的文本,使用字符缓冲输出流中的方法write,写入到文件中 bw.write(line); bw.newLine();//写换行 } //10.释放资源 bw.close(); br.close(); }}

文件复制

直接使用字节输入流

import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;/*    文件复制练习:一读一写    明确:        数据源: c:\\1.jpg        数据的目的地: d:\\1.jpg    文件复制的步骤:        1.创建一个字节输入流对象,构造方法中绑定要读取的数据源        2.创建一个字节输出流对象,构造方法中绑定要写入的目的地        3.使用字节输入流对象中的方法read读取文件        4.使用字节输出流中的方法write,把读取到的字节写入到目的地的文件中        5.释放资源    文件的大小:780,831 字节    一次读写一个字节:6043毫秒    使用数组缓冲读取多个字节,写入多个字节:10毫秒 */public class Demo01CopyFile {
public static void main(String[] args) throws IOException {
long s = System.currentTimeMillis(); //1.创建一个字节输入流对象,构造方法中绑定要读取的数据源 FileInputStream fis = new FileInputStream("c:\\1.jpg"); //2.创建一个字节输出流对象,构造方法中绑定要写入的目的地 FileOutputStream fos = new FileOutputStream("d:\\1.jpg"); //一次读取一个字节写入一个字节的方式 //3.使用字节输入流对象中的方法read读取文件 /*int len = 0; while((len = fis.read())!=-1){ //4.使用字节输出流中的方法write,把读取到的字节写入到目的地的文件中 fos.write(len); }*/ //使用数组缓冲读取多个字节,写入多个字节 byte[] bytes = new byte[1024]; //3.使用字节输入流对象中的方法read读取文件 int len = 0;//每次读取的有效字节个数 while((len = fis.read(bytes))!=-1){
//4.使用字节输出流中的方法write,把读取到的字节写入到目的地的文件中 fos.write(bytes,0,len); } //5.释放资源(先关写的,后关闭读的;如果写完了,肯定读取完毕了) fos.close(); fis.close(); long e = System.currentTimeMillis(); System.out.println("复制文件共耗时:"+(e-s)+"毫秒"); }}

使用字节缓冲输入流

import java.io.*;/*    文件复制练习:一读一写    明确:        数据源: c:\\1.jpg        数据的目的地: d:\\1.jpg    文件复制的步骤:        1.创建字节缓冲输入流对象,构造方法中传递字节输入流        2.创建字节缓冲输出流对象,构造方法中传递字节输出流        3.使用字节缓冲输入流对象中的方法read,读取文件        4.使用字节缓冲输出流中的方法write,把读取的数据写入到内部缓冲区中        5.释放资源(会先把缓冲区中的数据,刷新到文件中)    文件的大小:780,831 字节    一次读写一个字节:32毫秒    使用数组缓冲读取多个字节,写入多个字节:5毫秒 */public class Demo02CopyFile {
public static void main(String[] args) throws IOException {
long s = System.currentTimeMillis(); //1.创建字节缓冲输入流对象,构造方法中传递字节输入流 BufferedInputStream bis = new BufferedInputStream(new FileInputStream("c:\\1.jpg")); //2.创建字节缓冲输出流对象,构造方法中传递字节输出流 BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("d:\\1.jpg")); //3.使用字节缓冲输入流对象中的方法read,读取文件 //一次读取一个字节写入一个字节的方式 /*int len = 0; while((len = bis.read())!=-1){ bos.write(len); }*/ //使用数组缓冲读取多个字节,写入多个字节 byte[] bytes = new byte[1024]; int len = 0; while((len = bis.read(bytes))!=-1){
bos.write(bytes,0,len); } bos.close(); bis.close(); long e = System.currentTimeMillis(); System.out.println("复制文件共耗时:"+(e-s)+"毫秒"); }}

文件编码与解码

在这里插入图片描述

import java.io.FileReader;import java.io.IOException;/*    FileReader可以读取IDE默认编码格式(UTF-8)的文件    FileReader读取系统默认编码(中文GBK)会产生乱码��� */public class Demo01FileReader {
public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("10_IO\\我是GBK格式的文本.txt"); int len = 0; while((len = fr.read())!=-1){
System.out.print((char)len); } fr.close(); }}
import java.io.FileOutputStream;import java.io.IOException;import java.io.OutputStreamWriter;/*    java.io.OutputStreamWriter extends Writer    OutputStreamWriter: 是字符流通向字节流的桥梁:可使用指定的 charset 将要写入流中的字符编码成字节。(编码:把能看懂的变成看不懂)    继续自父类的共性成员方法:        - void write(int c) 写入单个字符。        - void write(char[] cbuf)写入字符数组。        - abstract  void write(char[] cbuf, int off, int len)写入字符数组的某一部分,off数组的开始索引,len写的字符个数。        - void write(String str)写入字符串。        - void write(String str, int off, int len) 写入字符串的某一部分,off字符串的开始索引,len写的字符个数。        - void flush()刷新该流的缓冲。        - void close() 关闭此流,但要先刷新它。    构造方法:        OutputStreamWriter(OutputStream out)创建使用默认字符编码的 OutputStreamWriter。        OutputStreamWriter(OutputStream out, String charsetName) 创建使用指定字符集的 OutputStreamWriter。        参数:            OutputStream out:字节输出流,可以用来写转换之后的字节到文件中            String charsetName:指定的编码表名称,不区分大小写,可以是utf-8/UTF-8,gbk/GBK,...不指定默认使用UTF-8    使用步骤:        1.创建OutputStreamWriter对象,构造方法中传递字节输出流和指定的编码表名称        2.使用OutputStreamWriter对象中的方法write,把字符转换为字节存储缓冲区中(编码)        3.使用OutputStreamWriter对象中的方法flush,把内存缓冲区中的字节刷新到文件中(使用字节流写字节的过程)        4.释放资源 */public class Demo02OutputStreamWriter {
public static void main(String[] args) throws IOException {
//write_utf_8(); write_gbk(); } /* 使用转换流OutputStreamWriter写GBK格式的文件 */ private static void write_gbk() throws IOException {
//1.创建OutputStreamWriter对象,构造方法中传递字节输出流和指定的编码表名称 OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("10_IO\\gbk.txt"),"GBK"); //2.使用OutputStreamWriter对象中的方法write,把字符转换为字节存储缓冲区中(编码) osw.write("你好"); //3.使用OutputStreamWriter对象中的方法flush,把内存缓冲区中的字节刷新到文件中(使用字节流写字节的过程) osw.flush(); //4.释放资源 osw.close(); } /* 使用转换流OutputStreamWriter写UTF-8格式的文件 */ private static void write_utf_8() throws IOException {
//1.创建OutputStreamWriter对象,构造方法中传递字节输出流和指定的编码表名称 //OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("10_IO\\utf_8.txt"),"utf-8"); OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("10_IO\\utf_8.txt"));//不指定默认使用UTF-8 //2.使用OutputStreamWriter对象中的方法write,把字符转换为字节存储缓冲区中(编码) osw.write("你好"); //3.使用OutputStreamWriter对象中的方法flush,把内存缓冲区中的字节刷新到文件中(使用字节流写字节的过程) osw.flush(); //4.释放资源 osw.close(); }}
import java.io.FileInputStream;import java.io.IOException;import java.io.InputStreamReader;/*    java.io.InputStreamReader extends Reader    InputStreamReader:是字节流通向字符流的桥梁:它使用指定的 charset 读取字节并将其解码为字符。(解码:把看不懂的变成能看懂的)    继承自父类的共性成员方法:        int read() 读取单个字符并返回。        int read(char[] cbuf)一次读取多个字符,将字符读入数组。        void close() 关闭该流并释放与之关联的所有资源。    构造方法:        InputStreamReader(InputStream in) 创建一个使用默认字符集的 InputStreamReader。        InputStreamReader(InputStream in, String charsetName) 创建使用指定字符集的 InputStreamReader。        参数:            InputStream in:字节输入流,用来读取文件中保存的字节            String charsetName:指定的编码表名称,不区分大小写,可以是utf-8/UTF-8,gbk/GBK,...不指定默认使用UTF-8     使用步骤:        1.创建InputStreamReader对象,构造方法中传递字节输入流和指定的编码表名称        2.使用InputStreamReader对象中的方法read读取文件        3.释放资源     注意事项:        构造方法中指定的编码表名称要和文件的编码相同,否则会发生乱码 */public class Demo03InputStreamReader {
public static void main(String[] args) throws IOException {
//read_utf_8(); read_gbk(); } /* 使用InputStreamReader读取GBK格式的文件 */ private static void read_gbk() throws IOException {
//1.创建InputStreamReader对象,构造方法中传递字节输入流和指定的编码表名称 //InputStreamReader isr = new InputStreamReader(new FileInputStream("10_IO\\gbk.txt"),"UTF-8");//??? InputStreamReader isr = new InputStreamReader(new FileInputStream("10_IO\\gbk.txt"),"GBK");//你好 //2.使用InputStreamReader对象中的方法read读取文件 int len = 0; while((len = isr.read())!=-1){
System.out.println((char)len); } //3.释放资源 isr.close(); } /* 使用InputStreamReader读取UTF-8格式的文件 */ private static void read_utf_8() throws IOException {
//1.创建InputStreamReader对象,构造方法中传递字节输入流和指定的编码表名称 //InputStreamReader isr = new InputStreamReader(new FileInputStream("10_IO\\utf_8.txt"),"UTF-8"); InputStreamReader isr = new InputStreamReader(new FileInputStream("10_IO\\utf_8.txt"));//不指定默认使用UTF-8 //2.使用InputStreamReader对象中的方法read读取文件 int len = 0; while((len = isr.read())!=-1){
System.out.println((char)len); } //3.释放资源 isr.close(); }}

转换文件编码

import java.io.*;/*    练习:转换文件编码        将GBK编码的文本文件,转换为UTF-8编码的文本文件。    分析:        1.创建InputStreamReader对象,构造方法中传递字节输入流和指定的编码表名称GBK        2.创建OutputStreamWriter对象,构造方法中传递字节输出流和指定的编码表名称UTF-8        3.使用InputStreamReader对象中的方法read读取文件        4.使用OutputStreamWriter对象中的方法write,把读取的数据写入到文件中        5.释放资源 */public class Demo04Test {
public static void main(String[] args) throws IOException {
//1.创建InputStreamReader对象,构造方法中传递字节输入流和指定的编码表名称GBK InputStreamReader isr = new InputStreamReader(new FileInputStream("10_IO\\我是GBK格式的文本.txt"),"GBK"); //2.创建OutputStreamWriter对象,构造方法中传递字节输出流和指定的编码表名称UTF-8 OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("10_IO\\我是utf_8格式的文件.txt"),"UTF-8"); //3.使用InputStreamReader对象中的方法read读取文件 int len = 0; while((len = isr.read())!=-1){
//4.使用OutputStreamWriter对象中的方法write,把读取的数据写入到文件中 osw.write(len); } //5.释放资源 osw.close(); isr.close(); }}

序列化与反序列化

在这里插入图片描述

import java.io.FileOutputStream;import java.io.IOException;import java.io.ObjectOutputStream;/*    java.io.ObjectOutputStream extends OutputStream    ObjectOutputStream:对象的序列化流    作用:把对象以流的方式写入到文件中保存    构造方法:        ObjectOutputStream(OutputStream out) 创建写入指定 OutputStream 的 ObjectOutputStream。        参数:            OutputStream out:字节输出流    特有的成员方法:        void writeObject(Object obj) 将指定的对象写入 ObjectOutputStream。    使用步骤:        1.创建ObjectOutputStream对象,构造方法中传递字节输出流        2.使用ObjectOutputStream对象中的方法writeObject,把对象写入到文件中        3.释放资源 */public class Demo01ObjectOutputStream {
public static void main(String[] args) throws IOException {
//1.创建ObjectOutputStream对象,构造方法中传递字节输出流 ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("10_IO\\person.txt")); //2.使用ObjectOutputStream对象中的方法writeObject,把对象写入到文件中 oos.writeObject(new Person("小美女",18)); //3.释放资源 oos.close(); }}
import java.io.FileInputStream;import java.io.IOException;import java.io.ObjectInputStream;/*    java.io.ObjectInputStream extends InputStream    ObjectInputStream:对象的反序列化流    作用:把文件中保存的对象,以流的方式读取出来使用    构造方法:        ObjectInputStream(InputStream in) 创建从指定 InputStream 读取的 ObjectInputStream。        参数:            InputStream in:字节输入流    特有的成员方法:        Object readObject() 从 ObjectInputStream 读取对象。    使用步骤:        1.创建ObjectInputStream对象,构造方法中传递字节输入流        2.使用ObjectInputStream对象中的方法readObject读取保存对象的文件        3.释放资源        4.使用读取出来的对象(打印)     readObject方法声明抛出了ClassNotFoundException(class文件找不到异常)     当不存在对象的class文件时抛出此异常     反序列化的前提:        1.类必须实现Serializable        2.必须存在类对应的class文件 */public class Demo02ObjectInputStream {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//1.创建ObjectInputStream对象,构造方法中传递字节输入流 ObjectInputStream ois = new ObjectInputStream(new FileInputStream("10_IO\\person.txt")); //2.使用ObjectInputStream对象中的方法readObject读取保存对象的文件 Object o = ois.readObject(); //3.释放资源 ois.close(); //4.使用读取出来的对象(打印) System.out.println(o); Person p = (Person)o; System.out.println(p.getName()+p.getAge()); }}

在这里插入图片描述

import java.io.Serializable;/*    序列化和反序列化的时候,会抛出NotSerializableException没有序列化异常    类通过实现 java.io.Serializable 接口以启用其序列化功能。未实现此接口的类将无法使其任何状态序列化或反序列化。    Serializable接口也叫标记型接口        要进行序列化和反序列化的类必须实现Serializable接口,就会给类添加一个标记        当我们进行序列化和反序列化的时候,就会检测类上是否有这个标记            有:就可以序列化和反序列化            没有:就会抛出 NotSerializableException异常    去市场买肉-->肉上有一个蓝色章(检测合格)-->放心购买-->买回来怎么吃随意    static关键字:静态关键字        静态优先于非静态加载到内存中(静态优先于对象进入到内存中)        被static修饰的成员变量不能被序列化的,序列化的都是对象        private static int age;        oos.writeObject(new Person("小美女",18));        Object o = ois.readObject();        Person{name='小美女', age=0}    transient关键字:瞬态关键字        被transient修饰成员变量,不能被序列化        private transient int age;        oos.writeObject(new Person("小美女",18));        Object o = ois.readObject();        Person{name='小美女', age=0} */public class Person implements Serializable{
private static final long serialVersionUID = 1L; private String name; //private static int age; //private transient int age; public int age; public Person() {
} public Person(String name, int age) {
this.name = name; this.age = age; } @Override public String toString() {
return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } 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; }}

序列化集合,即在集合中存放要序列化的对象

import java.io.*;import java.util.ArrayList;/*    练习:序列化集合        当我们想在文件中保存多个对象的时候        可以把多个对象存储到一个集合中        对集合进序列化和反序列化    分析:        1.定义一个存储Person对象的ArrayList集合        2.往ArrayList集合中存储Person对象        3.创建一个序列化流ObjectOutputStream对象        4.使用ObjectOutputStream对象中的方法writeObject,对集合进行序列化        5.创建一个反序列化ObjectInputStream对象        6.使用ObjectInputStream对象中的方法readObject读取文件中保存的集合        7.把Object类型的集合转换为ArrayList类型        8.遍历ArrayList集合        9.释放资源 */public class Demo03Test {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//1.定义一个存储Person对象的ArrayList集合 ArrayList
list = new ArrayList<>(); //2.往ArrayList集合中存储Person对象 list.add(new Person("张三",18)); list.add(new Person("李四",19)); list.add(new Person("王五",20)); //3.创建一个序列化流ObjectOutputStream对象 ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("10_IO\\list.txt")); //4.使用ObjectOutputStream对象中的方法writeObject,对集合进行序列化 oos.writeObject(list); //5.创建一个反序列化ObjectInputStream对象 ObjectInputStream ois = new ObjectInputStream(new FileInputStream("10_IO\\list.txt")); //6.使用ObjectInputStream对象中的方法readObject读取文件中保存的集合 Object o = ois.readObject(); //7.把Object类型的集合转换为ArrayList类型 ArrayList
list2 = (ArrayList
)o; //8.遍历ArrayList集合 for (Person p : list2) {
System.out.println(p); } //9.释放资源 ois.close(); oos.close(); }}

PrintStream

import java.io.FileNotFoundException;import java.io.PrintStream;/*    java.io.PrintStream:打印流        PrintStream 为其他输出流添加了功能,使它们能够方便地打印各种数据值表示形式。    PrintStream特点:        1.只负责数据的输出,不负责数据的读取        2.与其他输出流不同,PrintStream 永远不会抛出 IOException        3.有特有的方法,print,println            void print(任意类型的值)            void println(任意类型的值并换行)    构造方法:        PrintStream(File file):输出的目的地是一个文件        PrintStream(OutputStream out):输出的目的地是一个字节输出流        PrintStream(String fileName) :输出的目的地是一个文件路径    PrintStream extends 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) :将指定的字节输出流。    注意:        如果使用继承自父类的write方法写数据,那么查看数据的时候会查询编码表 97->a        如果使用自己特有的方法print/println方法写数据,写的数据原样输出 97->97 */public class Demo01PrintStream {
public static void main(String[] args) throws FileNotFoundException {
//System.out.println("HelloWorld"); //创建打印流PrintStream对象,构造方法中绑定要输出的目的地 PrintStream ps = new PrintStream("10_IO\\print.txt"); //如果使用继承自父类的write方法写数据,那么查看数据的时候会查询编码表 97->a ps.write(97); //如果使用自己特有的方法print/println方法写数据,写的数据原样输出 97->97 ps.println(97); ps.println(8.8); ps.println('a'); ps.println("HelloWorld"); ps.println(true); //释放资源 ps.close(); }}

使用System.setOut方法改变输出语句的目的地改为参数中传递的打印流的目的地

import java.io.FileNotFoundException;import java.io.PrintStream;/*    可以改变输出语句的目的地(打印流的流向)    输出语句,默认在控制台输出    使用System.setOut方法改变输出语句的目的地改为参数中传递的打印流的目的地        static void setOut(PrintStream out)          重新分配“标准”输出流。 */public class Demo02PrintStream {
public static void main(String[] args) throws FileNotFoundException {
System.out.println("我是在控制台输出"); PrintStream ps = new PrintStream("10_IO\\目的地是打印流.txt"); System.setOut(ps);//把输出语句的目的地改变为打印流的目的地 System.out.println("我在打印流的目的地中输出"); ps.close(); }}

转载地址:http://xdvgi.baihongyu.com/

你可能感兴趣的文章
论文笔记 | Transformer-XL:Attentive Language Models Beyond a Fixed-Length Context
查看>>
论文笔记 | An End-to-End Deep Framework for Answer Triggering with a Novel Group-Level Objective
查看>>
论文笔记:Exploiting WordNet Synset and Hypernym Representations for Answer Selection
查看>>
论文笔记|Overcoming the challenge for text classification in the open world
查看>>
论文笔记 | FLAT: Chinese NER Using Flat-Lattice Transformer
查看>>
论文笔记 | Multi-Grained Named Entity Recognition
查看>>
论文解读 | 百度 ERNIE: Enhanced Representation through Knowledge Integration
查看>>
论文笔记:Event Detection without Triggers
查看>>
论文笔记 | Attention Is All Y ou Need for Chinese Word Segmentation
查看>>
论文笔记|DOC: Deep Open Classification of Text Documents
查看>>
论文笔记|Undersensitivity in Neural Reading Comprehension
查看>>
论文笔记丨FewRel 2.0: Towards More Challenging Few-Shot Relation Classification
查看>>
论文笔记 _ Discourse-Aware Neural Extractive Text Summarization
查看>>
论文笔记 | Simple and Effective Text Matching with Richer Alignment Features
查看>>
论文笔记:A Gated Self-attention Memory Network for Answer Selection
查看>>
论文笔记 | Simplify the Usage of Lexicon in Chinese NER
查看>>
论文解读 | Unsupervised Data Augmentation for Consistency Training
查看>>
论文笔记|Distantly Supervised Named Entity Recognition using Positive-Unlabeled Learning
查看>>
论文笔记:Span-Based Event Coreference Resolution
查看>>
NAACL2021阅读理解论文整理
查看>>