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("错误信息");
        }
    }

    运行结果:

  • 相关阅读:
    项目不能imports同名命名空间
    表格分页
    关于Web Post信息的编码
    JJHIS构想
    asp.net客户端传参的小结
    注销类业务的处理
    枚举类型的一些用法总结
    MO功能使能情况
    在内嵌页面得到某个内嵌页面所在的frame
    不同包里的全局变量定义方式及系统配置处理
  • 原文地址:https://www.cnblogs.com/huang-changfan/p/9889444.html
Copyright © 2011-2022 走看看