四、常用流对象

2021/6/30 23:31:04

本文主要是介绍四、常用流对象,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

四 常用流对象

1 文件字节流

​ FileInputStream 通过字节的方式读取文件,适合所有类型的文件(图像、视频、文本文件等)。Java也提供了FileReader专门读取文本文件。

​ FileOutputStream 通过字节的方式写数据到文件中,适合所有类型的文件。Java也提供了FileWrite专门写入文件。

1.1 文件字节输入流

package com.IO;

import jdk.nashorn.internal.ir.CatchNode;

import java.io.FileInputStream;
import java.util.Calendar;

public class FirstDome01 {
    public static void main(String[] args) {
        FileInputStream file = null;

        try {
            //创建字节输入流对象
            file = new FileInputStream("D:/tieam1/a.txt");
            int s1 = file.read();//打印输入字符a敌营的ascii码值97
            int s2 = file.read();//打印输入字符a敌营的ascii码值98
            int s3 = file.read();//打印输入字符a敌营的ascii码值99
            int s4 = file.read();//打印输入字符a敌营的ascii码值-1
            System.out.println(s1);
            System.out.println(s2);
            System.out.println(s3);
            System.out.println(s4);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if (file != null){
            }try {
                file.close();
            }catch (Exception e){
                e.printStackTrace();
            }

        }
    }
}

1.2文件字节输出流

package com.IO;

import java.io.FileInputStream;
import java.io.FileOutputStream;

public class FileStreamDome {
    public static void main(String[] args) {

        FileInputStream fis = null;
        FileOutputStream fos = null;

        try{
            //创建文件字节输入流对象
            fis = new FileInputStream("C:/Users/188302228孙友路/jh/3.jpg");
            //创建文件字节输出流对象
            fos = new FileOutputStream("C:/Users/188302228孙友路/jh/6.jpg");
            int temp = 0;
            while ((temp = fis.read()) != -1){
                fos.write(temp);
            }
            //将数据从内存中写入到磁盘中
            fos.flush();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if (fis != null) {
                    fis.close();
                }
                if (fos != null){
                    fos.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

1.3 通过缓冲区提高读写效率

1.3.1 方式一

​ 通过创建一个指定长度的字节数组作为缓冲区,一次来提高IO流的读写效率。该方式使用于读取较大图片时的缓冲区定义。注意:缓冲区长度一定是2 的整数幂。一般情况下10242长度较为合适。

package com.IO;

import java.io.FileInputStream;
import java.io.FileOutputStream;

public class FileStreamBuffedDome {
    public static void main(String[] args) {
        FileInputStream fis = null;
        FileOutputStream fos = null;

        try{
            //创建文件字节输入流对象
            fis = new FileInputStream("C:/Users/188302228孙友路/jh/3.jpg");
            //创建文件字节输出流对象
            fos = new FileOutputStream("C:/Users/188302228孙友路/jh/6.jpg");
            //创建一个缓冲区,提高读写效率
            byte[] buff = new byte[1024];
            int temp = 0;
            while ((temp = fis.read(buff)) != -1){
                fos.write(buff,0,temp);
            }
            //将数据从内存中写入到磁盘中
            fos.flush();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if (fis != null) {
                    fis.close();
                }
                if (fos != null){
                    fos.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}
1.3.2 方式二

​ 通过创建一个字节数组作为缓冲区,数组长度是通过输入流对象的available()返回当前文件的预估长度来定义的。在读取文件时,是在文件时,是在一次读写操作中完成文件读写操作的。注意:如果文件过大,那么对内存的占用也是比较大的。所以大文件不建议使用该方法。

package com.IO;

import java.io.FileInputStream;
import java.io.FileOutputStream;

public class FileStreamBuffed2Dome {
        public static void main(String[] args) {
            FileInputStream fis = null;
            FileOutputStream fos = null;

            try{
                //创建文件字节输入流对象
                fis = new FileInputStream("D:/tieam1/01.jpg");
                //创建文件字节输出流对象
                fos = new FileOutputStream("D:/tieam1/01.jpg");
                //创建一个缓冲区,提高读写效率
                byte[] buff = new byte[fis.available()];
                fis.read(buff);
                fos.write(buff);
                //将数据从内存中写入到磁盘中
                fos.flush();
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                try {
                    if (fis != null) {
                        fis.close();
                    }
                    if (fos != null){
                        fos.close();
                    }
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }
    }

1.4 通过字节缓冲流提高读写效率

​ java缓冲流本身并不具有IO流的读取作用与写入功能,只是在别的流(节点流或其他处理流)上加上缓冲功能提高效率,就像是把别的流包装起来,因此缓冲流是一种处理流(包装流)。

​ 当对文件或者其他数据源进行频繁的读写操作时,效率比较低,这时如果使用缓冲流就能够更高效的读写信息。因为缓冲流是先将数据缓存起来,然后当缓存区存满后或者手动刷新时再一次性的读取到程序或写入目的地。

​ 因此,缓冲流还是很重要的,我们在IO操作时记得加上缓冲流来提升性能。

​ BufferedInputStream和BufferedOutputStream这两个流逝缓冲字节流,通过内部缓存数组来提高操作的效率。

package com.IO;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;

public class FileStreamBuffed3Dome {
    public static void main(String[] args) {
        FileInputStream fis = null;
        FileOutputStream fos = null;
        BufferedInputStream bis = null;
        BufferedOutputStream bos = null;
        try {
            fis = new FileInputStream("D:/tieam1/01.jpg");
            bis = new BufferedInputStream(fis);
            fos = new FileOutputStream("D:/tieam1/999.jpg");
            bos = new BufferedOutputStream(fos);
            //缓冲流中的byte数组默认长度是8192
            int temp = 0;
            while ((temp = bis.read()) != -1){
                bos.write(temp);
            }
            bos.flush();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if(bis != null){
                    bis.close();
                }
                if (fis != null){
                    fis.close();
                }
                if (bos != null){
                    bos.close();
                }
                if (fos != null){
                    fos.close();
                }
                //注意:关闭流顺序:”后开的先关闭“
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

1.5 定义文件拷贝工具类

package com.IO;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;

public class FileCopyTools {
    public static void main(String[] args) {
        copyFile("D:/tieam1/01.jpg","D:/tieam1/10086.jpg");
    }
    /*
    文件拷贝方法
     */
    public static void copyFile(String src,String des){
        FileInputStream fis = null;
        BufferedInputStream bis = null;
        FileOutputStream fos = null;
        BufferedOutputStream bos = null;

        try{
            fis = new FileInputStream(src);
            bis = new BufferedInputStream(fis);
            bos = new BufferedOutputStream(new FileOutputStream(des));
            int temp = 0;
            while ((temp = bis.read()) != -1){
                bos.write(temp);
            }
            bos.flush();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if (bis != null){
                    bis.close();
                }
                if (fis != null){
                    fis.close();
                }
                if (bos != null){
                    bos.close();
                }
                if (fos != null){
                    fos.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

2 文件字符流

​ 前面介绍的文件字节流可以处理所有的文件,如果我们处理的是文本文件,也可以使用文件字符流,它字符为单位进行操作。

2.1文件字符输入流
package com.IO;


import java.io.FileReader;

public class FileReaderDome {
    public static void main(String[] args) {
        FileReader frd = null;
        try {
            frd = new FileReader("D:/tieam1/a.txt");
            int temp = 0;
            while ((temp = frd.read()) != -1){
                System.out.println(temp);
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally{
            try{
                if (frd != null){
                    frd.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}
2.2 文件字符输出流
package com.IO;

import java.io.FileWriter;

public class FileWriteDome {
    public static void main(String[] args) {
        FileWriter fw = null;
        FileWriter fw2 = null;
        try {
            fw = new FileWriter("D:/tieam1/jh666.txt");
            fw.write("佳卉牛批\r\n");
            fw.flush();
            fw2 = new FileWriter("D:/tieam1/jh666.txt",true);
            fw2.write("何以解忧\r\n唯有牛牛");
            fw2.flush();
        }catch (Exception e){
            e.printStackTrace();
        }finally{
            try {
                if (fw != null){
                    fw.close();
                }
                if (fw2 != null){
                    fw2.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}
2.3 使用字符流实现文本文件的拷贝处理
package com.IO;

import java.io.FileReader;
import java.io.FileWriter;

public class FileCopyTools2 {
    public static void main(String[] args) {
        FileReader fr = null;
        FileWriter fw = null;
        try {
            fr = new FileReader("D:/tieam1/b.txt");
            fw = new FileWriter("D:/tieam1/c.txt");
            int temp = 0;
            char [] buff = new char[1024];
            while ((temp = fr.read(buff)) != -1){
                fw.write(buff,0,temp);
            }
            fw.flush();
        }catch (Exception e){
            e.printStackTrace();
        }finally{
            try {
                if (fr != null);{
                    fr.close();
                }
                if (fw != null){
                    fw.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}
/*
总结:
    1.字符输入流:FileReader
    2.字符输出流:FileWrite
    3.利用缓冲流进行快速读取写出,因为是字符,故采用char类型。char[] buffer = new char[1024];
 */

3 字符缓冲流

​ BufferedReader/BufferedWrite增加了缓存机制,大大提高了读写文本文件的效率

3.1 字符输入缓冲流

​ BufferedReader 是针对字符输入流的缓冲流对象,提供了更方便的按行读取的方法:readLine();在使用字符流读取文本文件时,我们可以使用该方法以行为单位进行读取。

package com.IO;

import com.sun.istack.internal.FinalArrayList;

import java.io.BufferedReader;
import java.io.FileReader;

public class BufferedReaderDome {
    public static void main(String[] args) {
        FileReader fr = null;
        BufferedReader br = null;

        try{
            fr = new FileReader("D:/tieam1/b.txt");
            br = new BufferedReader(fr);
            String temp = "";
            while ((temp = br.readLine()) != null){
                System.out.println(temp);
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally{
            try {
                if (br != null){
                    br.close();
                }
                if (fr != null){
                    fr.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}
/*
总结:
    1.字符输入缓冲流的创建
    2.BufferedReader是针对字符输入流的缓冲对象
    3.字符缓冲流的作用:提供了更方便的按行读取的方法:readline();使我们可以使用该方法以行为单位进行读取
 */

3.2 字符输出缓冲流

​ BufferedWrite 是针对字符输出流的缓冲流对象,在字符输出缓冲流中可以使用newLine();方法实现换行处理。

package com.IO;

import java.io.BufferedWriter;
import java.io.FileWriter;

public class BufferedWriterDome {
    public static void main(String[] args) {
        FileWriter fw = null;
        BufferedWriter bw = null;
        try {
            bw = new BufferedWriter(new FileWriter("D:/tieam1/e.txt"));
            bw.write("牛:你在干啥呢?");
            bw.newLine();
            bw.write("孙:我在想你啊~~~");
            bw.newLine();
            bw.write("牛:你蒙谁呢?大傻逼!!!");
            bw.newLine();
            bw.write("孙:你再骂一个试试!");
            bw.newLine();
            bw.write("牛:试试就试试,大傻逼! 大傻逼! 大傻逼!");
            bw.newLine();
            bw.write("孙:我亲死你!!!");
            bw.newLine();
            bw.write("牛:呜~~~~~~~");
        }catch (Exception e){
            e.printStackTrace();
        }finally{
            try {
                if (bw != null){
                    bw.close();
                }
                if (fw != null){
                    fw.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}
/*
总结:
    1.字符输出缓冲流的创建
    2.BufferedWriter是针对字符输出流的缓冲对象
    3.字符输出缓冲流的作用:提供更为方便的输出方法,提高输出效率
    4.在字符输出缓冲流中可以试用newLine()方法实现换行处理
 */

3.3 通过字符缓冲流实现文本文件的拷贝

package com.IO;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;

public class FileCopyTools3 {
    public static void main(String[] args) {
        copyFile("D:/tieam1/b.txt","D:/tieam1/f.txt");
    }
    /*
    基于字符缓冲流实现文件拷贝
     */
    public static void copyFile(String src,String des){
        BufferedReader br = null;
        BufferedWriter bw = null;
        try {
            br = new BufferedReader(new FileReader(src));
            bw = new BufferedWriter(new FileWriter(des));
            String temp = "";
            while ((temp = br.readLine()) != null){
                bw.write(temp);
                bw.newLine();
            }
            bw.flush();
        }catch (Exception e){
            e.printStackTrace();
        }finally{
            try {
                if (br != null){
                    br.close();
                }
                if (bw != null){
                    bw.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}
/*
总结:
    1.学习内容:通过字符缓冲流实现文本文件的拷贝
    2.利用输入缓冲流和输出缓冲流进行操作
    3.注意进行换行操作 利用newLine()方法进行操作
 */

3.4 通过字符缓冲流为文件中的内容添加行号

package com.IO;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;

public class LineNumberDome {
    public static void main(String[] args) {
        BufferedReader br = null;
        BufferedWriter bw = null;
        try {
            br = new BufferedReader(new FileReader("D:/tieam1/b.txt"));
            bw = new BufferedWriter(new FileWriter("D:/tieam1/g.txt"));
            String temp = "";
            int i = 1;
            while ((temp = br.readLine()) != null){
                bw.write(i+" "+temp);
                bw.newLine();
                i++;
            }
            bw.flush();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if (br != null){
                    br.close();
                }
                if (bw != null){
                    bw.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}
/*
总结:
    1.学习内容:通过字符缓冲流为文件中的内容添加行号
    2.利用字符输入流、字符输出流进行操作
    3.利用while循环进行操作
 */

4 转换流

​ InputStreamReader/OutputStreamWriter 用来实现将字节流转化成字符流。比如,如下场景:

​ System.in是字节流对象,代表键盘的输入,如果我们想按行接收用户的输入时,就必须用到缓冲字符流BufferedReader 特有的方法readLine(),但是经过观察会发现在创建BufferedReader 的构造方法的参数必须是一个Reader 对象,这时候我们的转换流 InputStreamReader 就派上用场了。

​ 而Sysetem.out也是字节流对象,代表输出到显示器,按行读取用户的输入后,并且要将读取的一行字符串直接显示到控制台,就需要用到字符流的write(String str)方法,所以我们要使用 OutputStreamWriter 将字节流转化为字符流。

4.1 通过转换流实现键盘输入屏幕输出

package com.IO;

import java.io.*;

public class ConvertStream {
    public static void main(String[] args) {
        BufferedReader br = null;
        BufferedWriter bw = null;

        try{
            br = new BufferedReader(new InputStreamReader(System.in));
            bw = new BufferedWriter(new OutputStreamWriter(System.out));
            while (true){
                bw.write("请输入: ");
                bw.flush();
                String input = br.readLine();
                if ("exit".equals(input)){
                    break;
                }
                bw.write("您输入的是"+input);
                bw.newLine();
                bw.flush();
            }
//            InputStream is = System.in;
//            int input = is.read();
//            System.out.println(input);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if (br != null){
                    br.close();
                }
                if (bw != null){
                    bw.close();
                }
            }catch (Exception e){

            }
        }
    }
}
/*
总结:
    1.学习目标:通过转换流实现键盘输入,屏幕输出
    2.接收用户输入内容的方法是System.in(字节流对象)  输出的方法是System.out
    3.实现例子:通过转换流实现键盘输入,屏幕输出
    4.实现方法:利用InputStreamReader和OutputStreamWriter来实现将字节流转化为字符流
    5.实现过程:
            1.创建字符缓冲输入流BufferedReader和字符缓冲输出流BufferedWriter
            2.捕捉处理异常try/catch
            3.利用循环语句while创建死循环直至输入exit
            4.在循环体中写出输出语句
 */

4.2 通过字节流读取文本文件并添加行号

/*
4.2 通过字节流读取文本文件并添加行号
 */
package com.IO;

import java.io.*;

public class LineNumberDome2 {
    public static void main(String[] args) {
        BufferedReader br = null;
        BufferedWriter bw = null;
        try {
            br = new BufferedReader(new InputStreamReader(new FileInputStream("D:/tieam1/java/b.txt")));
            bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("D:/tieam1/java/A.txt")));
            String temp = "";
            int i = 1;
            while ((temp = br.readLine()) != null){  //readLine()读取一行文本行。如果已经到达末尾,则返回null
                bw.write(i+"."+temp);
                bw.newLine();
                i++;
            }
            bw.flush();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if (br != null){
                    br.close();
                }
                if (bw != null){
                    bw.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}
/*
总结:
    1.熟悉了字节流转换为字符流的方法
 */

5 字符输出流

​ 在Java的IO流专门提供了用于字符输出的流对象PrintWriter。该对象具有自动行刷新缓冲字符输出流,特点是可以按行写出字符串,并且可以通过println();方法实现自动换行。

package com.IO;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;

public class LineNumberDome03 {
    public static void main(String[] args) {
        BufferedReader br = null;
        PrintWriter pw = null;
        try {
            br = new BufferedReader(new InputStreamReader(new FileInputStream("D:/tieam1/java/b.txt")));
            pw = new PrintWriter("D:/tieam1/java/c.txt");
            String temp = "";
            int i = 1;
            while ((temp = br.readLine()) != null){
                pw.println(i+"."+temp);
                i++;
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if (br != null){
                    br.close();
                }
                if (pw != null){
                    pw.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

6 字节数组流

​ ByteArrayInputStream和ByteArrayOutputStream经常用在需要流和数组之间转化的情况

6.1 字节数组输入流

​ 含义:FileInputStream是把文件当做数据源。ByteArrayInputStream是把内存中的字节数组对象当做数据源

package com.IO;

import java.io.ByteArrayInputStream;

public class ByteArrayInputDome {
    public static void main(String[] args) {
        byte[] arr = "qazswerfgvbnjuygtr".getBytes();
        ByteArrayInputStream bis = null;
        StringBuilder sb = new StringBuilder();
        try {
            bis = new ByteArrayInputStream(arr);
            int temp = 0;
            while ((temp = bis.read()) != -1){
                sb.append((char)temp);
            }
            System.out.println(sb.toString());
        }finally {
            try {
                bis.close();
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}
/*
总结:
    1.ByteArrayInputStream和ByteArrayOutputStream是处理字节数组的。
    2.toString()遍历方法的复习
    3.StringBuilder是一个类,可以用来处理字符串
问题:1.重载的复习

 */

6.2 字节数组输出流

​ ByteArrayOutputStream流对象是将流中的数据写入到字节数组中。

package com.IO;

import java.io.ByteArrayOutputStream;

public class ByteArrayOutputDome {
    public static void main(String[] args) {
        ByteArrayOutputStream bos = null;
        StringBuilder sb = new StringBuilder();
        try {
            bos = new ByteArrayOutputStream();
            bos.write('a');
            bos.write('b');
            bos.write('c');
            byte[] arr = bos.toByteArray();
            for (int i = 0;i < arr.length;i++){
                sb.append((char)arr[i]);
            }
            System.out.println(sb.toString());
        }
        finally {
            try {
                if (bos != null){
                    bos.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}
/*
总结:
    1.字节数组输出流ByteArrayOutputStream的学习
 */

7 数据流

​ 数据流将“基本数据类型与字符串类型”作为数据源,从而允许程序以与机器无关的方式从底层输入输出流中操作Java基本数据类型与字符串类型。

​ DataInputStream和DataOutputStream提供了可以存取与机器无关的所有Java基础类
型数据(如:int、double、String等)的方法

7.1 数据输出流

package com.IO;

import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.FileOutputStream;

public class DataOutputDome {
    public static void main(String[] args) {
        DataOutputStream dos = null;
        try {
            dos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream("D:/tieam1/java/d.txt")));
            dos.writeUTF("我们都是光");
            dos.writeUTF("我们都要加油");
            dos.writeUTF("我们都是迪迦!");
            dos.writeInt(666);
            dos.writeBoolean(false);
            dos.writeChar('d');
            dos.writeDouble(Math.random());
            dos.flush();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if (dos != null){
                    dos.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}
/*
总结:
    数据输出流DataOutputStream的学习
 */

7.2 数据输入流

package com.IO;

import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.FileInputStream;

public class DataInputDome {
    public static void main(String[] args) {
        DataInputStream dis = null;
        try{
            dis = new DataInputStream(new BufferedInputStream(new FileInputStream("D:/tieam1/java/d.txt")));
            System.out.println("readYTF:"+dis.readUTF());
            System.out.println("readYTF:"+dis.readUTF());
            System.out.println("readYTF:"+dis.readUTF());
            System.out.println("readInt:"+dis.readInt());
            System.out.println("readBoolean:"+dis.readBoolean());
            System.out.println("readChar:"+dis.readChar());
            System.out.println("readDouble:"+dis.readDouble());

        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if (dis != null){
                    dis.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}

8 对象流

​ 对象的本质是用来组织和存储数据的,对象本身也是数据。那么,能不能将对象存储到硬盘上的文件中呢?能不能将对象通过网络传输到另一个电脑呢?我们可以通过序列化和反序列化来实现这些需求。

8.1 Java对象的序列化和反序列化

8.1.1 序列化和反序列化是什么?

​ 当两个进程远程通信时,彼此可以发送各种类型的数据。但无论是何种类型的数据,都会以二进制序列的形式在网络上发送。比如,我们可以通过http协议发送字符串信息;我们也可以在网络上直接发送Java对象。发送方需要把这个Java对象转化为字节序列,才能在网络上传送;接收方则需要把字节序列恢复为Java对象才能正常读取。
​ 把Java对象转化为字节序列的过程称为对象的序列化。把字节序列恢复为Java对象的过程称为对象的反序列化。
序列化的作用有如下两种:
∷ 持久化: 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中
∷ 网络通信: 在网络上传送对象的字节序列。比如:服务器之间的数据通信、对象传递。

8.1.2 序列化涉及的类和接口

​ ObjectOutputStream代表对象输出流,它的writeObject(Object obj)方法可对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中。
​ ObjectOutputStream代表对象输入流,它的readObject()方法从一个源输入流中读取字节序列,再把它反序列化成一个对象,并将其返回。
​ 只有实现了Serializable接口的类的对象才能被序列化。Serializable接口是一个空接口,只起到标记的作用。

8.2 操作基本数据类型

​ 前面学习的数据流只能实现对基本数据类型和字符串类型的读写,并不能对java对象进行读写操作(字符串除外),但是在对象流中除了能实现对基本数据类型进行读写操作以外,还可以对java对象进行操作。

8.2.1 写出基本数据类型
package com.IO;

import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;

public class ObjectOutputStreamBasicTypeDomo {
    public static void main(String[] args) {
        ObjectOutputStream oos = null;
        try {
            oos = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream("D:/tieam1/java/1.txt")));
            oos.writeBoolean(false);
            oos.writeInt(666);
            oos.writeDouble(Math.random());
            oos.writeChar('t');
            oos.writeUTF("佳卉宝贝");
            oos.writeUTF("佳卉老婆");
            oos.writeUTF("佳卉宝");
            oos.flush();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if (oos != null){
                    oos.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}
/*
总结:
    利用对象流ObjectOutputStream写出基本数据类型
 */
8.2.2 使用对象流读取基本类型
package com.IO;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.ObjectInputStream;

public class ObjectInputStreamBasicTypeDome {
    public static void main(String[] args) {
        ObjectInputStream ois = null;
        try {
            ois = new ObjectInputStream(new BufferedInputStream(new FileInputStream("D:/tieam1/java/1.txt")));
            System.out.println("Boolean: "+ ois.readBoolean());
            System.out.println("Int: "+ ois.readInt());
            System.out.println("Double: "+ ois.readDouble());
            System.out.println("Char: "+ ois.readChar());
            System.out.println("UTF: "+ ois.readUTF());
            System.out.println("UTF: "+ ois.readUTF());
            System.out.println("UTF: "+ ois.readUTF());
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if (ois != null){
                    ois.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}
/*
总结:
    利用对象流读取基本数据类型
 */

8.3 操作对象

8.3.1 将对象序列化到文件

​ ObjectOutputStream可以将一个内存中的Java对象通过序列口的方式写入到磁盘的文件中。被序列化的对象必须要实现Serializable序列化接口,否则会出现异常。

8.3.3.1 创建对象
package com.IO;

import java.io.Serializable;

public class Users implements Serializable {
    private int userid;
    private String username;
    private String userage;

    public Users(int userid, String username, String userage) {
        this.userid = userid;
        this.username = username;
        this.userage = userage;
    }

    public Users() {
    }

    public int getUserid() {
        return userid;
    }

    public void setUserid(int userid) {
        this.userid = userid;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getUserage() {
        return userage;
    }

    public void setUserage(String userage) {
        this.userage = userage;
    }
}
8.3.1.2 序列化对象
package com.IO;

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;

public class ObjectOutputStreamObjectTypeDome {
    public static void main(String[] args) {
        ObjectOutputStream oos = null;
        try {
            oos = new ObjectOutputStream(new FileOutputStream("D:/tieam1/java/2.txt"));
            Users users = new Users(1,"佳卉","20");
            oos.writeObject(users);
            oos.flush();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if (oos != null){
                    oos.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}
/*
总结:
    1.创建对象的复习
    2.利用ObjectOutputStream将java对象将其序列化并写入到磁盘中
    3.必须要实现Serializable序列化接口
 */
8.3.2 讲对象反序列化到内存
package com.IO;

import java.io.FileInputStream;
import java.io.ObjectInputStream;

public class ObjectInputStreamObjectTypeDome {
    public static void main(String[] args) {
        ObjectInputStream ois = null;
        try {
            ois = new ObjectInputStream(new FileInputStream("D:/tieam1/java/2.txt"));
            Users users = (Users)ois.readObject();
            System.out.println(users.getUserid()+"\t"+users.getUsername()+"\t"+users.getUserage());
        }catch (Exception e){
            e.printStackTrace();
        }finally{
            try {
                if (ois != null){
                    ois.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}
/*
总结:
    1.利用ObjectInputStream将对象反序列化到内存中
    2.实现的方法为: Users users = (User)ois.readObject();
 */

9 随机访问流

​ RandomAccessFile可以实现两个作用:

​ 1.实现对一个文件读和写的操作

​ 2.可以访问任意一个位置。不像其他流只能按照先后顺序读取。

​ 在开发某些客户端软件时,经常用到这个功能强大的“可以操作文件内容”的类。比如,软件的使用次数和使用日期,可以通过本类访问文件中保存次数和日期的地方进行比对和修改。java中很少开发客户端软件,所以在java开发中这个类用的相对较少。
​ 学习这个流我们需要掌握三个核心方法:

​ 1.RandomAccessFile(String name,String mode)用来确定文件;mode取r(可读)或rw(可读写),通过mode可以确定对流的访问权限。

​ 2.seek(long a)用来确定流对象的读写位置,a来确定读写举例文件开头的字节个数

​ 3.getFilePointer() 获得流当前读写位置

package com.IO;

import java.io.RandomAccessFile;

public class RandomAccessFileDome {
    public static void main(String[] args) {
        RandomAccessFile raf = null;
        try {
            raf = new RandomAccessFile("D:/tieam1/java/3.txt","rw");
            int[] arr = new int[]{11,22,33,44,55,66,77,88,99,111};
            for (int i = 0;i < arr.length;i++){
                raf.writeInt(arr[i]);
            }
            raf.seek(4);
            System.out.println(raf.readInt());

            //隔一行读一个数据
            for (int i = 0; i < 10; i+=2) {
                raf.seek(i*4);
                System.out.print(raf.readInt()+"\t");
            }
            System.out.println();

            //在第8个字节位置插入一个新的数据38,替换之前的数据33
            raf.seek(8);
            raf.writeInt(45);
            for (int i = 0; i < 10; i++) {
                raf.seek(i*4);
                System.out.print(raf.readInt()+"\t");
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally{
            try {
                if (raf != null){
                    raf.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}
/*
总结:
    1.利用RandomAccessFile操作文件内容
    2.seek方法:seek(long a)用来确定流对象的读写位置,a来确定读写举例文件开头的字节个数
 */

10 File类在IO中的作用

​ 当以文件作为数据源或目标时除了可以使用字符串作为文件指定的位置之外,我们也可以使用File类指定

= null){
                    br.close();
                }
                if (bw != null){
                    bw.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}
/*
总结:学会了使用File类指定
 */


这篇关于四、常用流对象的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程