IO总结之ByteArray,DataOutput,Object(序列化),PrintStream

目录

  • 缓冲流用于读入
  • 字节数组,结点流
  • DataStream(数据类型处理流 )流,主要处理基本类型和String
  • 序列化,反序列化,就是对象存到文件,实现Serilizable
  • PrintStream
  • System中的三个常量 : err,in,out

缓冲流用于读入

可以用缓冲流加快读取速度

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
/**
 * @author 郑鑫
 */
public class TestBufferdIn {
    /**
     * 通过BufferedReader来方便读取
     * @param args
     * @throws IOException
     */
    public static void main(String[] args) throws IOException {
        InputStream is = System.in;  //平时的Scanner in = new Scanner(System.in)也是这样的
        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        String msg = br.readLine();
        System.out.println(msg);
    }
}

字节数组,结点流

就是将内容写到字节数组中(使用ByteArrayOutputStream),然后用ByteArrayInputStream读取字节数组中的内容。
注意输出流和文件输出流有点不同,而且当子类有新增的方法的时候不要使用多态,且可以用缓冲流提高访问速度。
注意输出流中的toByteArray()方法,将输出流中的内容读到字节数组中

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;

/**
 * 字节数组,结点流
 * @author 郑鑫
 */
public class TestByteArrayDemo {
    public static void main(String [] args) {
        try {
            read(write()); //直接读写到字节数组中的
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 输入流,操作与文件输入流一致 
     * @throws IOException 
     */
    public static void read(byte[] src) throws IOException {
        InputStream is = new BufferedInputStream( ///使用缓冲流加快速度,这样的话就要使用InputStream(多态)
                    new ByteArrayInputStream(src)
                );
        //如果不用缓冲流,就可以直接使用ByteArrayInputStream
        ByteArrayInputStream iss = new ByteArrayInputStream(src);
        byte[] flush = new byte[1024];
        int len = 0;
        while(-1 != (len = is.read(flush))) {
            System.out.println(new String(flush,0,len));
        }
        is.close();
    }

    /**
     * 输出流: 操作与文件输出流有些不同,有新增的方法,不能使用多态
     * 注意方法toByteArray()方法的使用,读到字节数组中
     * @throws IOException 
     */
    public static byte[] write() throws IOException {
        byte dest[];
        ByteArrayOutputStream os = new ByteArrayOutputStream();  //注意有新增的方法不使用多态
        String msg = "操作与文件输出流有些不同";
        byte[] info = msg.getBytes();
        os.write(info,0,info.length);
        os.close();
        dest = os.toByteArray();  //得到结点流中的字节数组
        return dest;
    }
}

同时,也可以用数组流拷贝文件

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import Test.IO.Util.FileUtil;

/**
 * 文件拷贝到字节数组 : 文件 --> 程序 --> 字节数组
 * 字节数组拷贝到文件 : 字节数组 --> 程序 -->文件
 * @author 郑鑫
 */
public class TestByteArrayDemo02 {
    public static void main(String[] args) throws IOException {
        byte[] data = getByteFromFile("D:/eclipsework/zx/test/a.txt"); //不只是文件,也可以是图片等等
        System.out.println(new String(data));
        toFileFromByteArray(data,"D:/eclipsework/zx/test/b.txt");
    }

    /**
     * 文件到字节数组
     * @param path
     * @return
     * @throws IOException
     */
    public static byte[] getByteFromFile(String path) throws IOException {
        File src = new File(path);
        InputStream is = new BufferedInputStream(new FileInputStream(src));
        byte[] dest = null;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        int len = 0;
        byte[] flush = new byte[1024];  //先读到字节数组中
        while(-1 != (len = is.read(flush))) {
            bos.write(flush,0,len); //将字节数组中的内容写到输出流中
        }
        dest = bos.toByteArray();  //从输出流中获取字节数组
        //bos.close();
        //is.close();
        FileUtil.closeAll(bos,is); //这个是关闭流的工具包,在下面的程序工具类中有
        return dest;
    }

    /**
     *字节数组到文件
     */
    public static void toFileFromByteArray(byte[] src,String destPath) throws IOException {
        //目的地
        File dest = new File(destPath);
        //字节数组输入流
        InputStream is = new BufferedInputStream(new ByteArrayInputStream(src));
        //文件输出流
        OutputStream os = new BufferedOutputStream(new FileOutputStream(dest));
        int len = 0;
        byte[] flush = new byte[1024];
        while(-1 != (len = is.read(flush))) {
            os.write(flush,0,flush.length);
        }
        os.flush();//记得刷一下
        os.close();
        is.close();
    }
}

DataStream(数据类型处理流 )流,主要处理基本类型和String

输入流 : DataInputStream,输出流 : DataOutputStream
方法:readXxx(), WriteXxx()
注意其中可能出现的异常:java.io.EOFException : 已经达到文件的末尾,没有读取到文件
还有要注意:读取的顺序和写出一致,必须存在才能读取

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * DataStream(数据类型处理流 )流,主要处理基本类型和String 
 * 输入流 : DataInputStream,输出流 : DataOutputStream
 * readXxx(), WriteXxx()
 * java.io.EOFException : 已经达到文件的末尾,没有读取到文件
 * @author 郑鑫
 *
 */
public class TestDataDemo {
    public static void main(String[] args) throws IOException {
        write("D:/eclipsework/zx/test/c.txt");
        read("D:/eclipsework/zx/test/c.txt");
    }

    /**
     * 写入数据类型到文件
     * @param destPath
     * @throws IOException
     */
    public static void write(String destPath) throws IOException {
        double a = 2.3;
        long b = 567L;
        String str = "数据类型";
        File dest = new File(destPath);
        // 数据类型处理流 DataInputStream(使用新增的方法,不要使用上转型和多态)
        DataOutputStream os = new DataOutputStream(
                new BufferedOutputStream(
                         new FileOutputStream(dest)
                        )
                );

        os.writeDouble(a);
        os.writeLong(b);
        os.writeUTF(str);
        os.flush();
        os.close(); 
    }

    /**
     *从文件读取
     * 读取的顺序和写出一致,必须存在才能读取
     * @param srcPath
     * @throws IOException 
     */
    public static void read(String srcPath) throws IOException {
        DataInputStream is = new DataInputStream(
                new BufferedInputStream(new FileInputStream(new File(srcPath)))
            );
        //读取的顺序和写出一致,必须存在才能读取
        double num = is.readDouble();
        double num2 = is.readLong();
        String str = is.readUTF();
        System.out.println(num);
        System.out.println(num2);
        System.out.println(str);
    }
}

再看一个数据类型写到字节数组中的例子

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;

/**
 * 数据类型写到字节数组
 * @author 郑鑫
 */
public class TestDataDemo02 {
    public static void main(String[] args) throws IOException {
        byte[] data = new byte[1024];
        System.out.println(new String(data = write())); //这个是看不懂的(乱码机器识别)
        read(data); 
    }
    /**
     * 读到字节数组
     * @return
     * @throws IOException
     */
    public static byte[] write() throws IOException {
        double a = 2.3;
        long b = 567L;
        String str = "数据类型";
        byte[] dest = null;
        // 数据类型处理流 DataInputStream(使用新增的方法,不要使用上转型和多态)
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        DataOutputStream os = new DataOutputStream(
                new BufferedOutputStream(bos)
                );
        os.writeDouble(a);
        os.writeLong(b);
        os.writeUTF(str);
        os.flush();
        os.close(); 
        dest = bos.toByteArray();
        return dest;
    }
    /**
     * 从字节数组读取
     * @param src
     * @throws IOException
     */
    public static void read(byte[] src) throws IOException {
        // 数据类型处理流 DataInputStream(使用新增的方法,不要使用上转型和多态)
        ByteArrayInputStream ios = new ByteArrayInputStream(src);
        DataInputStream is = new DataInputStream(
                new BufferedInputStream(ios)
                );
        double num = is.readDouble();
        double num2 = is.readLong();
        String str = is.readUTF();
        is.close(); 
        System.out.println(num);
        System.out.println(num2);
        System.out.println(str);
    }
}

序列化,反序列化,就是对象存到文件,实现Serilizable

序列化就是对象存到文件 : 引用类型的存储 保留数据类型
反序列化就是从文件中读取对象(引用类型)
反序列化 : 输入流 ObjectInputStream
序列化 : 输出流 ObjectOutputStream
序列化的时候要注意:

  • 注意序列化的对象和反序列化的顺序要一致
  • 不是所有的对象都可以序列化 : 要实现Serilizable
  • 不是所有的属性都需要序列化(对象中的某个属性存到文件就叫做对象的某个属性被序列化,如果没有被序列化就存到文件,读取的时候是Null,不需要序列化的属性用transient标记)
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Arrays;
/*
 * 实体类
 * java.io.Serializable只是一个接口(标识这个类可以序列化)
 */
class Employee implements java.io.Serializable{  //要实现序列化必须是实现这个接口
    private transient String name;  //不需要序列化
    private double salary;  //只序列化 工资
    public Employee(String name, double salary) {
        super();
        this.name = name;
        this.salary = salary;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public double getSalary() {
        return salary;
    }
    public void setSalary(double salary) {
        this.salary = salary;
    } 
}

/**
 * 就是对象存到文件 : 引用类型的存储 保留数据类型 
 * 反序列化 : 输入流 ObjectInputStream
 * 序列化 : 输出流  ObjectOutputStream
 * 
 * 1)注意序列化的对象和反序列化的顺序要一致 
 * 2)不是所有的对象都可以序列化 : 要实现Serilizable
 * 3)不是所有的属性都需要序列化
 * @author 郑鑫
 *
 */
public class TestObjectDataDemo {
    public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
        seriwrite("D:/eclipsework/zx/test/e.txt");
        serread("D:/eclipsework/zx/test/e.txt");
    }
    /**
     * 序列化 : 序列化employee中的salary(存入文件)
     * @param destPath
     * @throws FileNotFoundException
     * @throws IOException
     */
    public static void seriwrite(String destPath) throws FileNotFoundException, IOException {
        Employee emp = new Employee("zhengxin", 10000);
        int[] arr = {1,2,3,4};
        File dest = new File(destPath);
        ObjectOutputStream os = new ObjectOutputStream(
                    new BufferedOutputStream(new FileOutputStream(dest))
                );
        os.writeObject(emp); //直接把对象写入文件
        os.writeObject(arr);//直接把数组写入文件
        os.close();
    }

    /**
     * 反序列化:读取
     * @param srcPath
     * @throws FileNotFoundException
     * @throws IOException
     * @throws ClassNotFoundException
     */

    public static void serread(String srcPath) throws FileNotFoundException, IOException, ClassNotFoundException {
        File src = new File(srcPath);
        ObjectInputStream is = new ObjectInputStream(
                    new BufferedInputStream(new FileInputStream(src))
                );
        Object obj = is.readObject();
        if(obj instanceof Employee) {
            Employee emp = (Employee)obj;
            System.out.println(emp.getName()); //输出为null,名字没有序列化(没有存到文件中)
            System.out.println(emp.getSalary());
        }
        int[]arr = (int[])is.readObject();
        System.out.println(Arrays.toString(arr));
        is.close();
    }
}

效果
这里写图片描述


PrintStream

PrintStream和IO的关系,可以从控制台读入输出,也可以从文件读入输出。

import java.io.BufferedOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintStream;

/**
 * @author 郑鑫
 */
public class TestPrintStream {
    public static void main(String[] args) throws FileNotFoundException {
        PrintStream out = System.out;
        out.println("test");
        //改变out流
        out = new PrintStream(new BufferedOutputStream(new FileOutputStream("D:/eclipsework/zx/test/print.txt")));
        out.println("io is so easy"); //把这句话写到print.txt中
        out.flush();
        out.close(); //一定要记得及时关闭
    }
}

效果这里写图片描述


System中的三个常量 : err,in,out

知识:

  • InputStream从控制台输入
  • Scanner从文件解析读取
  • 重定向setIn(),setOut(),setErr()方法
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.PrintStream;
import java.util.Scanner;

/**
 * System中的三个常量 : err,in,out
 * @author 郑鑫
 *
 */
public class TestSytemDemo {
    public static void main(String[] args) {
        //test1();
//      try {
//          test2();
//      } catch (FileNotFoundException e) {
//          e.printStackTrace();
//      }
        try {
            test3();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    public static void test1() {
        System.out.println("out");
        System.err.println("err");
    }

    /**
     * Input从控制台输入和从文件解析
     * @throws FileNotFoundException
     */
    public static void test2() throws FileNotFoundException {
        InputStream is = System.in; //输入流的父类
        Scanner sc = new Scanner(is);
        System.out.println(sc.nextLine());

        //使用了多态
        //从文件读取 : 相当于Scanner解析吧
        InputStream re = new BufferedInputStream(new FileInputStream("D:/eclipsework/zx/test/print.txt"));
        sc = new Scanner(re);
        System.out.println(sc.nextLine());
    }
    /**
     * 重定向
     * setIn()
     * setOut()
     * setErr()方法
     * @throws FileNotFoundException 
     */
    public static void test3() throws FileNotFoundException{
        System.setOut(new PrintStream(new BufferedOutputStream(new FileOutputStream("D:/eclipsework/zx/test/print.txt")),true)); //后面的true 代表的是自动刷星
        //不需要手动的flush
        System.out.println("zhengxin");

        //然后回到控制台控制重写把out变成控制台输出
        //也要借助FileOutputStream文件流(控制台也是一个文件)
        System.setOut(new PrintStream(new BufferedOutputStream(new FileOutputStream(FileDescriptor.out)),true)); //后面的true 代表的是自动刷新
        System.out.println("back....");
    }
}

分别测试test1(),test2(),test3()的效果
这里写图片描述
这里写图片描述
这里写图片描述

阅读更多
个人分类: JavaIO
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭