【JavaSE】之IO流(下)

简介: 【JavaSE】之IO流(下)

3.字符输出流Writer


成员方法:


abstract void close() 关闭流,先刷新。

abstract void flush() 刷新流。

void write(char[] cbuf) 写入一个字符数组。

abstract void write(char[] cbuf, int off, int len) 写入字符数组的一部分。

void write(int c) 写一个字符。

void write(String str) 写一个字符串。

void write(String str, int off, int len) 写一个字符串的一部分。


4.FileWriter


  • FileWriter 继承 OutputStreamWriter 继承 Writer


构造方法:


FileWriter(File file) 给一个File对象构造一个FileWriter对象。

FileWriter(File file, boolean append) 给一个File对象构造一个FileWriter对象。

FileWriter(String fileName) 构造一个给定文件名的FileWriter对象。

FileWriter(String fileName, boolean append)构造一个FileWriter对象,给出一个带有布尔值的文件名,表示是否附加写入的数据。


件写入步骤


  • 创建此类对象,构造方法写文件路径,调用write方法把数据写入到内存缓存区中(此间会将字符转换为字节),然后使用flush方法把内存缓冲区中的数据刷新到文件中,之后释放资源(释放资源也会把缓冲区数据刷新到文件中)
import java.io.FileWriter;
import java.io.IOException;
public class J04 {
    public static void main(String[] args) throws IOException {
        FileWriter fw=new FileWriter("字符测试文件.txt");
        fw.write("知识点");
        fw.flush();//刷新缓冲区数据到文件中
        fw.close();
    }
}
// 结果:
//     文件中显示:知识点

续写和换行


  • 续写:用有追加写开关的构造方法,即可,和字节续写相同,换行也相同。


四、缓冲流(增强流对象)


1.字节输出缓冲流(BufferedOutputStream)


BufferedOutputStream(OutputStream out) 继承 OutputStream

相当于将要输入的全部字节存储到某个地方,一次性发送到指定的地方,使虚拟机和操作系统间交互尽可能少,以提高效率。

构造方法:

BufferedOutputStream(OutputStream out) 创建一个新的缓冲输出流,以将数据写入指定的底层输出流

BufferedOutputStream(OutputStream out,int size) 创建一个新的缓冲输出流,以将具有指定缓冲区大小的数据写入指定的底层输出流

当传递一个输出流对象后缓冲流会给这个对象增加一个缓冲区,提高FileOutputStream的写入效率,size可以指定也能默认。


使用:


创建FileOutputStream对象,构造方法中绑定输出地址,然后将创建的对象作为参数创建BufferedOutputStream类的对象,使用缓冲流的对象对文件进行写入操作,然后刷新缓冲区(flush),然后释放资源()


import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Io_06 {
    public static void main(String[] args) throws IOException {
        FileOutputStream fos=new FileOutputStream("缓冲流测试.txt");
        BufferedOutputStream bos=new BufferedOutputStream(fos);
        bos.write("测试缓冲流".getBytes());
        bos.flush();
        bos.close();
    }
}

2.字节输入缓冲流(BufferedInputStream)


  • 继承自InputStream


构造方法:


BufferedInputStream(InputStream in) 创建一个BufferedInputStream并保存其参数,输入流 in ,供以后使用。


BufferedInputStream(InputStream in, int size) 创建BufferedInputStream具有指定缓冲区大小,并保存其参数,输入流 in ,供以后使用。


代码示例:

import java.io.*;
public class Io_06 {
    public static void main(String[] args) throws IOException {
        FileInputStream fis=new FileInputStream("缓冲流测试.txt");
        BufferedInputStream bis=new BufferedInputStream(fis);
        //是显示字符串,所以先创建字节数组,将输入的字节存储到字节数组中,然后通过Sting的构造方法将字节数组转换为字符串输出
        int len;
        byte[] bytes=new byte[1024];
        while ((len=bis.read(bytes))!=-1){
            System.out.println(new String(bytes));
        }
        bis.close();
    }
}

3.字符缓冲输出流(BufferedWriter)


继承自Writer


构造方法:


BufferedWriter(Writer out) 创建使用默认大小的输出缓冲区的缓冲字符输出流。

BufferedWriter(Writer out, int sz) 创建一个新的缓冲字符输出流,使用给定大小的输出缓冲区。


成员方法(特有):


void newLine() 写一行行分隔符。


实现代码:

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
public class Io_07 {
    public static void main(String[] args) throws IOException {
        FileWriter fw=new FileWriter("缓冲流测试文件.txt");
        BufferedWriter bw=new BufferedWriter(fw);
        bw.write("zdhd");
        bw.newLine();
        bw.write("shd");
        bw.flush();
        bw.close();
    }
}
// 结果:
//     zdhd
//     shd


4.字符缓冲输入流(BufferedReader)


继承自Reader


构造方法:


BufferedReader(Reader in) 创建使用默认大小的输入缓冲区的缓冲字符输入流。

BufferedReader(Reader in, int sz) 创建使用指定大小的输入缓冲区的缓冲字符输入流


特有的成员方法


String readLine() 读一行文字。

以换行符(‘\n’),回传(‘\r’)或者回车后直接跟着换行(\r\n)作为结束行的标志

如果读取到的这一行无数据了,会返回null值,其他时候返回的是读取的数据(但是不会读取行的终止符合,即如果本来有换行,读取后是不会读取换行符)


代码示例:

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class Io_08 {
    public static void main(String[] args) throws IOException {
        BufferedReader br=new BufferedReader(new FileReader("缓冲流测试文件.txt"));
        //读的是一行,所以只有一字符串为类型接收数据
        String str;
        while ((str=br.readLine())!=null){
            System.out.println(str);
        }
    }
}
// 结果:
//     zdhd
//     shd

五、对文件内容进行排序


文件内容:

1.测试缓冲流10
9.测试缓冲流2
2.测试缓冲流9
3.测试缓冲流8
6.测试缓冲流5
4.测试缓冲流7
5.测试缓冲流6
8.测试缓冲流3
10.测试缓冲流1
7.测试缓冲流4

排序代码:

import java.io.*;
import java.util.HashMap;
public class IO_00 {
    public static void main(String[] args) throws IOException {
        /*
        目的:将无序的10段话有序的录入进其他文件中
        1.使用字符缓冲输入流,获取文件中的数据。
        2.对数据进行切割,分离序号和文本内容
        3.对文件数据用HashMap集合进行存储,K为序号,V为文本内容
        4.遍历集合,将K,V值存储到指定文件
         */
        HashMap<String,String> hashMap=new HashMap<>();
        BufferedReader br=new BufferedReader(new FileReader("缓冲流测试.txt"));
        BufferedWriter bw=new BufferedWriter(new FileWriter("缓冲流测试排序.txt"));
        String str;
        //每次获取一行数据,返回值为null表示获取完成
        while ((str=br.readLine())!=null){
            //'.'是转义字符,前面必须加\\来表示后面的 . 是普通字符
            String[] strings=str.split("\\.");
            //将分割后的数据存储到集合中,K存储序号,V存储内容(HashMap会对数据按照K的数字大小进行排序)
            hashMap.put(strings[0],strings[1]);
        }
        //利用keySet方法将所有k值转换成set数组,并用增强for循环获取每个k值,然后利用get方法和k值获取每个v值
        for (String k:hashMap.keySet()) {
            //分割后,分割符会取消,所以需要手动添加
            bw.write(k+"."+hashMap.get(k));
            //换行,同样换行符也会取消,也需要手动添加
            bw.newLine();
        }
        br.close();
        bw.flush();
        bw.close();
    }
}

结果:

1.测试缓冲流10
2.测试缓冲流9
3.测试缓冲流8
4.测试缓冲流7
5.测试缓冲流6
6.测试缓冲流5
7.测试缓冲流4
8.测试缓冲流3
9.测试缓冲流2
10.测试缓冲流1

六、转换流


作用:在文件进行写入或者读取操作时,文件是以字节形式存储在文件中,然后通过编码表对字节进行解码以呈现看得懂的文字,而就在在编码中,一般情况默认使用UTF-8编码,但是有的会使用GBK编码,如果编码录入,与解码读取所用的编码表不同,则会出现乱码情况,此时就可以使用转换流指定使用什么编码表进行读取或者写入操作。

OutputStreamWriter继承自Writer

InputStreamReader继承自Reader


构造方法:


输出的: OutputStreamWriter(OutputStream out)创建一个使用默认字符编码的OutputStreamWriter。 OutputStreamWriter(OutputStream out, String charsetName) 创建一个使用命名字符集的OutputStreamWriter。

输入的: InputStreamReader(InputStream in) 创建一个使用默认字符集的InputStreamReader 。InputStreamReader(InputStream in, String charsetName)创建一个使用命名字符集的InputStreamReader。

参数:OutputStream,InputStream:分别是字节输出流和字节输入流; charsetName:编码名称,不区分大小写,默认为UTF-8


使用步骤:


1.创建OutputStreamWriter对象,构造方法中new一个字节输出流,和指定编码。

2.用OutputStreamWriter对象,调用方法写入数据,然后刷新缓冲区,释放资源

3.创建InputStreamReader对象,构造方法new一个字节输入流,和指定编码。

4.调用方法读取文件,释放资源。


实现代码:

import java.io.*;
public class Io_11 {
    public static void main(String[] args) throws IOException {
        OutputStreamWriter osw=new OutputStreamWriter(new FileOutputStream("转换流测试.txt"),"gbk");
        osw.write("转换流");
        osw.flush();
        osw.close();
        InputStreamReader isr=new InputStreamReader(new FileInputStream("转换流测试.txt"),"gbk");
        int i;
        while ((i=isr.read())!=-1){
            System.out.print((char) i);
        }
        isr.close();
    }
}

七、序列化与反序列化


  • 定义:用来将对象进行存储,将对象利用字节方式存储进文件为序列化,将对象从文件中读取叫反序列化。


1.ObjectInputStream和ObjectOutputStream


构造方法:


输出的:ObjectOutputStream(OutputStream out) 创建一个写入指定的OutputStream的ObjectOutputStream。参数是字节输出流

输入的:ObjectInputStream(InputStream in) 创建从指定的InputStream读取的ObjectInputStream。


特有方法:


输出的:void writeObject(Object obj) 将指定的对象写入ObjectOutputStream。

输入的:Object readObject() 从ObjectInputStream读取一个对象。


使用步骤:


1.先创建一个类及其对象a,并实现接口Serializable(不实现是会抛出异常的)


2.再创建ObjectOutputStream对象,调用writeObject方法,参数是a(即第一步创建的对象),把对象写入文件中

3.释放资源


4.创建ObjectInputStream对象,调用readObject方法,将对象读取出来,除了io异常外还有一个关于class文件的异常,即需要有这个文件,读取的对象用类型为Object的变量接收。


5.释放资源,打印对象。

实现代码:

import java.io.*;
public class Io_12 {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        A a=new A("邹飞鸣");
        ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("序列化测试.txt"));
        oos.writeObject(a);
        oos.close();
        ObjectInputStream ois=new ObjectInputStream(new FileInputStream("序列化测试.txt"));
        Object obj=ois.readObject();
        ois.close();
        System.out.println(obj);
    }
}
//实现接口
class A implements Serializable{
    private String str;
    //定义有参构造方法一定还要定义一个无参的
    public A(){}
    public A(String str){
        this.str=str;
    }
    public String getStr() {
        return str;
    }
    public void setStr(String str) {
        this.str = str;
    }
//为了输出具体的数值 
    @Override
    public String toString() {
        return "A{" +
                "str='" + str + '\'' +
                '}';
    }
}
// 结果:
// A{str='邹飞鸣'}


2.反序列化序列号异常问题


当类实现Serializable后类会有一个序列号,这个序列号会随着对象进行序列化存储进文件中,当进行反序列化时会比较文件中的和类中的是否一致,如果一致才会读取,否则会抛出异常,而当类中代码发生改变后(如变量修饰符)序列号也是会改变的,而此时再读取已经被序列化的文件时,就会产生异常,所以可以将序列号固定不变,可防止此类问题:需在类中添加代码:


static final long serialVersionUID = 42L;

3.transient(瞬态关键字)


  • 作用,使修饰的变量不能够被序列化,即不能将赋好值的这个变量将值随着对象一起被存储进去。
  • static修饰后也不能被序列化。


后记


Java全栈学习路线可参考:【Java全栈学习路线】最全的Java学习路线及知识清单,Java自学方向指引,内含最全Java全栈学习技术清单~

相关文章
|
存储 缓存 Java
JavaSE—IO流 ( 八千字带你快速深入理解IO流体系 )(二)
JavaSE—IO流 ( 八千字带你快速深入理解IO流体系 )(二)
150 7
|
存储 Java
JavaSE—IO流 ( 八千字带你快速深入理解IO流体系 )(一)
JavaSE—IO流 ( 八千字带你快速深入理解IO流体系 )(一)
128 5
|
存储 缓存 Java
JavaSE—IO流之字符流与字节流
JavaSE—IO流之字符流与字节流
134 0
|
存储 Java
JavaSE基础精选-IO流
JavaSE基础精选-IO流
149 0
|
存储 编解码 移动开发
【Java】JavaSE的IO流操作
【Java】JavaSE的IO流操作
187 0
|
存储 移动开发 Java
【JavaSE】Java基础语法(三十六):File & IO流
1. File java.io.File类是文件和目录路径名的抽象表示形式,主要用于文件和目录的创建、查找和删除等操作。
JavaSE:第十二章:IO流
JavaSE:第十二章:IO流
213 0
JavaSE:第十二章:IO流
|
存储 Java
【JavaSE】文件操作篇(一)文件基础操作与IO流原理及分类
文章目录 1 文件 1.1 文件流 1.2 常用的文件操作 2 IO流原理及流的分类 2.1 IO流原理 2.2 流的分类 写在最后
【JavaSE】文件操作篇(一)文件基础操作与IO流原理及分类
|
存储 Java
JavaSE—IO流(二)
JavaSE—IO流(二)
264 0
JavaSE—IO流(二)
|
存储 Java 数据处理
JavaSE—IO流(一)
JavaSE—IO流(一)
218 0
JavaSE—IO流(一)