zoukankan      html  css  js  c++  java
  • 6.5(java学习笔记)其他流(字节数组流,数据流,对象流,打印流)

    一、字节数组流

      之前使用输入输出流的操作的对象是文件,而这里字节数组流操作的对象是内存,内存可以看做是一个字节数组。

      使用字节数组流读写就可以看做是从内存A到内存B的读写,对象时内存即字节数组。

      

      1.1构造方法

        ByteArrayOutputStream()//创建一个字符数组输出流

        ByteArrayInputStream(byte[] buf)//创建一个字节数组输入流,这里面的buff可看做内存对象即字符数组

      

      2.2主要方法

        ByteArrayInputStream:

        read(byte[] bu)//读取输入流中的数据,放入bu中。

        ByteArrayOutputStream:

        public void write(byte[] bu)//将bu(可看做内存对象数据),写入输出流。

        byte[] toByteArray()//创建一个新的字节数组,并将输出流中数据放入其中

      2.3例子

        

    import java.io.BufferedInputStream;
    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    
    public class ByteArrayStream {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            read(write());
        }
        public static void read(byte[] by){
            int len = 0;
            //将内存对象B放入输入流
            InputStream r = new BufferedInputStream(new ByteArrayInputStream(by));//把这里的by看做内存对象
            byte[] flush = new byte[1024];//把flush看做另外一个内存对象
            try {
                //将内存对象B与输入流关联,来后通过输入流读取对象B数据放入flush中
                while(-1 != (len = r.read(flush))){//读取输入流中的数据放入flush,即读取内存对象B中的数据
                    System.out.println(new String(flush,0,len));//打印出读取的数据
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        
        public static byte[] write(){
            byte[] by = null;//内存对象B
            byte []info = "字节数组流".getBytes();//内存对象A
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            try {
                bos.write(info);//将内存A块内容写入输出流
                by = bos.toByteArray();//内存对象B接收输出流中的数据
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return by;//返回内存对象B
        }
        
    }
    运行结果:
    字节数组流

    wtire:首先将内存A的数据写入输出流,然后内存B获取输入流中的数据,最后将内存B作为返回值。

    read:将内存B放入输入流,然后通过输入流读取内存B中的数据放入flush中,然后将flush转为字符打印出来。

    这里在一个程序中运行看着有点奇怪而且不好理解,我们就把内存A内存B看着是两台电脑各自内存,这样便于理解一些。

    二、数据流

      采用数据流进行读写可以允许将原始java数据类型写入流中,即既保持了数据也保存了数据类型。

      2.1构造方法

        DataInputStream(InputStream  in)

        DataOutputStream(OutStream out)

      2.2主要方法

        void writeInt(int v)//写入int型数据

        void writeLong(long v)//写入long型数据

        void writeUTF(String str)//将字符串以UTF-8格式写入输出流

        

        int readInt()//读取Int型数据并返回

        long readLong()//读取long型数据并返回

        String readUTF()//读取UTF-8转换的字符串

        基本操作方法与文件读写无太大差别,只是加上了数据类型,这些方法时DataStream独有的方法,故调用它们要避免多态。

      2.3例子

        

    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.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    public class DateStream {
    
        public static void main(String[] args) throws IOException {
            // TODO Auto-generated method stub
            write();
            read();
        }
        public static void read() throws IOException{
            DataInputStream dis = new DataInputStream(//数据流
                                        new BufferedInputStream(//缓冲流
                                                new FileInputStream(
                                                        new File("F:\依风\Desktop\data.txt")
                                                        )
                                                )
                                        );
            //注意:这里读取类型的顺序要和写入时的类型顺序对应,不然会出现错误。
            long lo = dis.readLong();//将不同类型用对应方法读出。
            int in = dis.readInt();
            String str = dis.readUTF();
            dis.close();
            System.out.println(lo + "-->" + in +"-->" + str);
        }
        
        public static void write() throws IOException{
            long lo = 100L;
            int in = 21;
            String str = "DataStream";
            DataOutputStream dos = new DataOutputStream(//数据流
                                         new BufferedOutputStream(//缓冲流
                                             new FileOutputStream(
                                                 new File("F:\依风\Desktop\data.txt")
                                             )
                                         )
                                   );
            dos.writeLong(lo);//将不同类型用对应的方法写入
            dos.writeInt(in);
            dos.writeUTF(str);
            dos.flush();
            dos.close();
        }
    }
    运行结果:
    100-->21-->DataStream

    这里一开始往文件中写入的是long型,然后是int类型最后是String

    那么读取时也应该先读long,然后int最后String。

    如果写入和读取的顺序不一致可能会导致读取的数据有误,也可以出现EOFException。

    这里写入的数据不是给人类看的,而是给机器识别的。我可以打开写入的文件会发现里面会有乱码。

    三、对象流

        使用对象流,可以写入、读出对象的信息以及属性属性。对象流和之前输入输出流功能类似,

        不过是将之前的文件换成了对象,这里的对象时我们通过new创建的对象。

        将对象写如文件实质是是将对象转换为字节序列,然后将字节序列写入文件,这个称为序列化。

        读取字节序列然后转换为对象就称为反序列化。

        对象被序列化必须实现java.io.Serializable接口,改接口表示可以序列化。对象的类没有实现这个接口会出现一次次。

        对象中某些属性不想被序列化可以加transient修饰,transient修饰就代表这个属性不参加序列化。

        3.1构造方法

        Public ObjectOutputStream(OutputStream out)

        Public ObjectInputStream(InputStream in)

        

        3.2主要方法

         Object readObject()//从输入流中读取对象

         void writeObject(Object obj)//将obj写入输出流

        3.3例子 

    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;
    
    public class ObjectStream {
        public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException{
            read(write());
        }
        //将对象写入指定文件,并返回指定文件路径信息
        public static String write() throws FileNotFoundException, IOException{
            String filePath = "F:\依风\Desktop\ObjectStream.txt";
            ObjectOutputStream oos = new ObjectOutputStream(//使用独有方法,不发生多态
                                        new BufferedOutputStream(
                                            new FileOutputStream(
                                                new File(filePath))));
            oos.writeObject(new Employ("hcf",4000));//传入对象
            oos.flush();
            oos.close();
            return filePath;
        }
        
        //接受指定文件路径信息,并读取文件中的对象
        public static void read(String filePath) throws FileNotFoundException, IOException, ClassNotFoundException{
            ObjectInputStream ois = new ObjectInputStream(
                                        new BufferedInputStream(
                                            new FileInputStream(
                                                new File(filePath))));
            Employ em = (Employ)ois.readObject();//将读取的对象强制转型
            System.out.println(em.getName() + ":" + em.getMoney());//输出对象信息
        }
    }
    
    
    class Employ implements java.io.Serializable{//必须实现接口
        private transient String name;//姓名没有被序列化
        private int money;
        public Employ(){}
        public Employ(String name,int money){
            setName(name);
            setMoney(money);
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getMoney() {
            return money;
        }
        public void setMoney(int money) {
            this.money = money;
        }
    }
    运行结果:
    null:4000

    我们可以看到没有被序列化的属性显示为null

    比如一个矩形类中有长、宽属性,还有面积属性,

    那么序列化时可以不序列化面积属性,因为面积属性可以通过长宽计算出来。  

    四、打印流

        打印流(PraintStream)类似输出流,但打印流使用方便而且可以打印出任何类型的数据。

        想我们平常使用很多的System.out.println()就是调用打印流中的println()方法。

        4.1构造函数

        PrintStream(OutputStream out)//创建打印流

        PrintStream(OutputStream out, boolean autoFlush)//创建打印流,autoFlush为true代表自动刷新缓冲区
        PrintStream(File fileName, String csn)//创建指定文件的打印流,csn为编码方式

        4.3主要方法

        print(......);//打印参数内容,几乎可为任何形式参数,末尾不加回车。

        println(......)//打印参数内容,末尾加回车。

        

        

        4.4例子 

    import java.io.BufferedOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.PrintStream;
    import java.io.UnsupportedEncodingException;
    import java.util.Scanner;
    
    public class Print {
        public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException{
            PrintStream ps = new PrintStream(//常规初始化
                    new BufferedOutputStream(
                        new FileOutputStream(
                            new File("F:\依风\Desktop\print.txt"))));
            PrintStream pc = new PrintStream("F:\依风\Desktop\printCsn.txt","GBK");//指定编码
            PrintStream pf = new PrintStream(//自动刷新
                    new BufferedOutputStream(
                        new FileOutputStream(
                            new File("F:\依风\Desktop\printFlush.txt"))),true);
            pf.println("autoFlush");
            pf.close();
            pc.print("GBK");
            pc.flush();
            pc.close();
            ps.print("print
    "+1.3);
            ps.flush();
            ps.close();
        }
    }

    运行结果:

    4.5 Sytem.out和 System.in

    我们平常调用System.out.println()函数打印,打印的内容是显示在控制台上的,System.out也是一个打印流。

    而这个打印流关联的就是控制台,可以把控制台也看做一个文件,平常打印出来的数据就是往控制台这个文件打印。

    那么我们能否将这个文件换成别的文件呢,即调用System.out.println()不是向控制台输出信息,而是向我们指定的文件输入信息。

    答案是可以的,System里面提供了一个方法System.SetOut(PrintStream out)方法,可以设置System.out。

    可以看到参数是一个打印流。

    设置指定的参数后,Sytem.out.println()就会将内容打印到指定的打印流中。

    public class Print {
        public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException{
            System.setOut(new PrintStream(new FileOutputStream(new File("F:\依风\Desktop\print.txt"))));
            System.out.println("setOut");
        }
    }

    还有System.in,这个比较常用的用法就是作为Scanner的参数,表示从键盘输入。

    System.in其实就是一个输入流(InputStream),而System.in默认是键盘,这里可以把键盘也看做一个文件,就是从键盘这个文件读取内容。

    那么同样的,我们也可以将System.in修改为其他文件。

    就需要用到System.setIn(InputStream in).这时就是读取设置之后的输入流

    import java.io.BufferedInputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.PrintStream;
    import java.io.UnsupportedEncodingException;
    import java.util.Scanner;
    
    public class Print {
        public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException{
            //重定向了System.in将原来的将键盘输入更改为其他输入
            System.setIn(new BufferedInputStream(new FileInputStream(new File("F:\依风\Desktop\print.txt"))));
            Scanner si = new Scanner(System.in);
            System.out.println(si.nextLine());//读取一行
            
        }
    }
    运行结果:
    setOut//根据文件内容决定

    那么我么修改了Sytem.in(键盘输入)和System.out(控制台输出)为其他的文件后是否可以还原它们,当然是可以的,之前说了键盘、控制台都是文件

    (在windows中一切都可以看做是文件),现在的关键就是要找到代表控制台可键盘的文件,然后再次Set就可以了。

    我们来看下源码:

    其中FileDescriptor.in就代表键盘,....out就代表控制台,

    public class Print {
        public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException{
            //输出重定向为指定文件
            System.setOut(new PrintStream(new FileOutputStream(new File("F:\依风\Desktop\print.txt"))));
            System.out.println("setSystem.outAndSystem.in");
            System.out.close();
            //输出重定向为控制台
            System.setOut(new PrintStream(new FileOutputStream(FileDescriptor.out)));
            //输入重定向为指定文件
            System.setIn(new BufferedInputStream(new FileInputStream(new File("F:\依风\Desktop\print.txt"))));
            Scanner si = new Scanner(System.in);
            System.out.println(si.nextLine());//内容输出控制台
        }
    }
    运行结果:
    setSystem.outAndSystem.in

    还有一个System.err也是一个打印流,这个主要用于打印出错误信息。比如:

    这些红色的错误信息就是err打印出来的。

    import java.io.BufferedInputStream;
    import java.io.File;
    import java.io.FileDescriptor;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.PrintStream;
    import java.io.UnsupportedEncodingException;
    import java.util.Scanner;
    
    public class Print {
        public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException{
            System.err.println("错误信息");
        }
    }

    运行结果:

  • 相关阅读:
    开放源码的对象关系映射工具ORM.NET 插入数据 Insert/Update Data
    开放源码的对象关系映射工具ORM.NET 快档开发入门 Quick Start
    .NET 动态脚本语言Script.NET 开发指南
    开放源码的对象关系映射工具ORM.NET 删除数据 Deleting Records using ORM.NET
    .NET Remoting过时了吗?为什么公司的项目还是选择用.NET Remoting,而不是WCF?
    开放源码的对象关系映射工具ORM.NET 查看和显示数据 View and Display data using ORM.NET
    开放源码的对象关系映射工具ORM.NET 查询表 调用存储过程 增加自定义代码
    技术人生:坚持,每日一博
    CQRS:CQRS + DDD + MDP 实现快速应用程序开发
    NodeJs:Happy代码生成器,重构了代码,更新了文档,完善了示例,欢迎下载使用
  • 原文地址:https://www.cnblogs.com/huang-changfan/p/9889444.html
Copyright © 2011-2022 走看看