zoukankan      html  css  js  c++  java
  • IO流

    数据流的方向可以分为:输入流,输出流。输入和输出是针对内存来说的,从内存中出来就是输出,到内存中去就是输入。

    读取数据的方式可以分为:字符流,字节流。字节流按照字节的方式的读取,字符流按照字符的方式读取,也就是一次读取两个字节,因为java中一个字符占两个字节。

    那么什么情况下使用字节流?当读取图片、声音、视屏等二进制文件的时候,不过如果是纯文本的时候也是可以用字节流的!字节流万能的。

    当读取纯文本的时候用字符流!那么读Word文档要用什么?Word文档不光有文字还有格式,所以不是纯文本,要用字节流。

    Java中所有字节流都以Stream结尾,所有的字符流都含有Reader或者Writer

    InputStreamReader、OutputStreamWriter 属于转换流,字节流转字符流

    FileInputStream

    文件字节输入流,按照字节方式读取文件。在D盘新建文件IOTest.txt,内容为abcde123456789

    package iotest;
    
    import java.io.FileInputStream;
    
    /**
     * Created by Arenas on 2016/10/28.
     */
    public class IOTest01 {
    
        public static void main(String[] args) throws Exception{
    
            FileInputStream fis = new FileInputStream("D:/IOTest.txt");
            //available()返回流中剩余的估计字节数
            System.out.println(fis.available()); //14
            System.out.println(fis.read());     //97
            System.out.println(fis.available());//13
            //跳过两个字节
            fis.skip(2);
            System.out.println(fis.read()); //100
    
            fis.close();
        }
    
    }

    FileOutputStream

    package iotest;
    
    import java.io.FileOutputStream;
    
    /**
     * Created by Arenas on 2016/10/28.
     */
    public class IOTest02 {
    
        public static void main(String[] args){
            FileOutputStream fos = null;
            try{
                //直接添加,会覆盖原有内容
                //如果该文件不存在,则会创建一个文件
    //            fos = new FileOutputStream("D:/IOTest.txt");
                //以追加的方式添加到文件中
                fos = new FileOutputStream("D:/IOTest.txt" , true);
                String str = "Hello World!";
                //将String转换成byte数组
                byte[] bytes = str.getBytes();
                //将btyes中数据全部写入
    //            fos.write(bytes);
                fos.write(bytes , 3 , 2);//去掉前面三个,从第四个开始数两个数写入,也就是追加lo
                //推荐最后为了将数据完整的写入硬盘,执行flush()
                fos.flush();//强制写入
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                try{
                    if (fos != null)
                        fos.close();
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }
    }

     字节流的文件的复制粘贴

    package iotest;
    
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    
    /**
     * Created by Arenas on 2016/10/28.
     */
    public class IOTest04 {
        public static void main(String[] args) throws Exception{
            FileInputStream fis = new FileInputStream("D:/iopic.jpg");
            FileOutputStream fos = new FileOutputStream("D:/newiopic.jpg");
            byte[] bytes = new byte[1024];
            int length;
            while ((length = fis.read(bytes)) != -1){
                fos.write(bytes , 0 , length);
            }
            fis.close();
            fos.close();
        }
    }

    FileReader

    package iotest;
    
    import java.io.FileReader;
    
    /**
     * Created by Arenas on 2016/10/28.
     * java.lang.Object
     继承者 java.io.Reader
        继承者 java.io.InputStreamReader 转换流:字节流--->字符流
            继承者 java.io.FileReader 文件字符输入流
     */
    public class IOTest05 {
        public static void main(String[] args){
            FileReader reader = null;
            try{
                reader = new FileReader("D:/IOTest.txt");
                char[] chars = new char[512];//1kb,因为是读字符,所以用char而不是byte
                int length;
                while ((length = reader.read(chars)) != -1){
                    System.out.println(new String(chars , 0 , length));
                }
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                try{
                    if (reader != null)
                        reader.close();
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }
    }

    字符流的文件复制和粘贴

    package iotest;
    
    import java.io.FileReader;
    import java.io.FileWriter;
    
    /**
     * Created by Arenas on 2016/10/28.
     * 注意只能操作纯文本
     */
    public class IOTest06 {
        public static void main(String[] args) throws Exception{
            FileReader reader = new FileReader("D:/IOTest.txt");
            FileWriter writer = new FileWriter("D:/newIOTest.txt");
            char[] chars = new char[512];
            int length;
            while ((length = reader.read(chars)) != -1)
                writer.write(chars , 0 , length);
            writer.flush();
            reader.close();
            writer.close();
        }
    }

     BufferedReader

    package iotest;
    
    import java.io.BufferedReader;
    import java.io.FileReader;
    
    /**
     * Created by Arenas on 2016/10/29.
     * BufferedReader
     */
    public class IOTest07 {
        public static void main(String[] args) throws Exception{
            //根据流出现的位置,又可以分为包装流(处理流)、节点流
            //比如这里fileReader是一个节点流,bufferedReader是一个处理流,相当于在管子外面套了缓存区
            FileReader fileReader = new FileReader("D:/剪刀手爱德华.txt");
            BufferedReader bufferedReader = new BufferedReader(fileReader);
            String str;
            while ((str = bufferedReader.readLine()) != null)
                System.out.println(str);//readLine()方法读取一行,但是行尾不带换行符!!所以要换行需要println()
            bufferedReader.close();//这里关闭只要关闭最外面的包装流,这里有一个装饰者模式
        }
    }

    关于节点流和包装流

    package iotest;
    
    import java.io.BufferedReader;
    import java.io.FileInputStream;
    import java.io.InputStreamReader;
    
    /**
     * Created by Arenas on 2016/10/29.
     */
    public class IOTest08 {
        public static void main(String[] args) throws Exception{
            FileInputStream fis = new FileInputStream("D:/IOTest.txt");//文件字节输入流
            InputStreamReader isr = new InputStreamReader(fis);//将字节流转换成字符流
            BufferedReader reader = new BufferedReader(isr);
            //这里fis相对于isr来说,fis是节点流,isr是包装流
            //而isr相对于reader来说,isr又是节点流,reader是包装流
            //所以包装流和节点流是相对来说的
        }
    }

    DataInputStream/DataOutputStream

    package iotest;
    
    import java.io.DataOutputStream;
    import java.io.FileOutputStream;
    
    /**
     * Created by Arenas on 2016/10/30.
     * DataOutputStream,数据字节输出流,这是一个比较特殊的流
     * 可以将内存中 int i = 10 写到文件中,但是写进去的不是字符串,而是二进制数据,并且是带类型的!!!
     */
    public class IOTest09 {
        public static void main(String[] args) throws Exception{
            DataOutputStream dos = new DataOutputStream(new FileOutputStream("D:/IOTest.txt"));
            dos.writeByte(1);
            dos.writeBoolean(false);
            dos.writeInt(3);
            dos.writeDouble(3.3);
            dos.writeFloat(3.4f);
    
            dos.flush();
            dos.close();
        }
    }

    文件的数据直接打开是乱码,要用对应的DataInputStream来读

    package iotest;
    
    import java.io.DataInputStream;
    import java.io.FileInputStream;
    
    /**
     * Created by Arenas on 2016/10/30.
     */
    public class IOTest11 {
        public static void main(String[] args) throws Exception{
            DataInputStream dis = new DataInputStream(new FileInputStream("D:/IOTest.txt"));
            //这里去读取数据的顺序必须跟写进去的顺序相同,不能多读,不然会抛出java.io.EOFException
            byte b = dis.readByte();
            boolean flag = dis.readBoolean();
            int i = dis.readInt();
            int i1 = dis.readInt();
            double d = dis.readDouble();
    //        float f = dis.readFloat();
            System.out.println(b);
            System.out.println(flag);
            System.out.println(i);
            System.out.println(i1);//1074423398 d和i1都错了 虽然d是对应的正确的类型!!
            System.out.println(d);//1.9035983735196154E185
    //        System.out.println(f);
    
            dis.close();
        }
    }

    PrintStream/PrintWriter

    package iotest;
    
    import java.io.FileOutputStream;
    import java.io.PrintStream;
    
    /**
     * Created by Arenas on 2016/10/30.
     * java.io.PrintStream;标准的输出流,默认打印到控制台
     * java.io.PrintWriter;以字符的方式
     */
    public class IOTest10 {
        public static void main(String[] args) throws Exception{
            //默认打印到控制台
            PrintStream printStream = System.out;
            printStream.println("Hello World!");
            //改变输出方向setOut,输出到IOTest.txt中
            System.setOut(new PrintStream(new FileOutputStream("D:/IOTest.txt")));
            System.out.println("must tear down the wall");
        }
    }

    ObjectInputStream/ObjectOutputStream

    package iotest;
    
    import java.io.Serializable;
    
    /**
     * Created by Arenas on 2016/10/30.
     * Serializable这个接口内没有任何方法,只是起到一个标识的作用,称做标识接口,像这样的接口还有java.lang.Cloneable
     * JVM看到标识接口会对他特殊待遇
     */
    public class User implements Serializable {
    
        private String name;
    
        public User(String name){
            this.name = name;
        }
    
        @Override
        public String toString() {
            return "User -- > name = " + name;
        }
    }
    package iotest;
    
    import java.io.FileOutputStream;
    import java.io.ObjectOutputStream;
    
    /**
     * Created by Arenas on 2016/10/30.
     * java.io.ObjectInputStream;将硬盘中的数据反序列化到JVM内存中
     * java.io.ObjectOutputStream;序列化Java对象到硬盘
     */
    public class IOTest12 {
        public static void main(String[] args) throws Exception{
            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:/IOTest.txt"));
            User user = new User("kobe");//要传输的对象必须序列化!否则会抛出异常
            oos.writeObject(user);
            oos.flush();
            oos.close();
        }
    }
    package iotest;
    
    import java.io.FileInputStream;
    import java.io.ObjectInputStream;
    
    /**
     * Created by Arenas on 2016/10/30.
     */
    public class IOTest13 {
        public static void main(String[] args) throws Exception{
            ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:/IOTest.txt"));
            Object o = ois.readObject();//注意在反序列化的时候User.java这个文件不能删,因为在readObject的时候要创建对象,创建对象需要类
            System.out.print(o);//User -- > name = kobe
            ois.close();
        }
    }

     serialVersionUID

     之前有说到User在反序列化时是不能删的,如果删掉改变User呢?比如在User中加条private int age;属性,这个时候反序列化就会抛出异常

    Exception in thread "main" java.io.InvalidClassException: iotest.User; local class incompatible: stream classdesc serialVersionUID = 4408450428999604713, local class serialVersionUID = 6602202455712956108

    因为反序列化时会重新编译User,得到serialVersionUID跟流里面的User的serialVersionUID不同。这是由于在User实现serializable接口的时候,JVM会提供一个“特殊待遇”----给该类加上一个属性static final long serialVersionUID = 232313231L;在改变User后,由于User重新编译,JVM会重新分配一个序列化版本号。

    所以,这里可以自己加上serialVersionUID这条属性,不让系统自动生成。那么不管该类如何变,序列化版本号都不会改变了。

    package iotest;
    
    import java.io.Serializable;
    
    /**
     * Created by Arenas on 2016/10/30.
     * Serializable这个接口内没有任何方法,只是起到一个标识的作用,称做标识接口,像这样的接口还有java.lang.Cloneable
     * JVM看到标识接口会对他特殊待遇
     */
    public class User implements Serializable {
        //自己加上版本号
        static final long serialVersionUID = 2323123123L;
        private String name;
        //增加一条属性
        private int age;
    
        public User(String name){
            this.name = name;
        }
    
        //改变toString方法
        @Override
        public String toString() {
            return "User -- > name = " + name + " , age = " + age;
        }
    }

    再运行IOTest13会得到:User -- > name = kobe , age = 0。没有产生类的兼容性问题

    如果需要某个属性不参加序列化,那么就加上transient关键字修饰,如

    private transient String name;

    再运行IOTest13反序列化会得到

    User -- > name = null , age = 0

    File

    文件和目录路径名的抽象表示形式。也就是说文件夹和文件都是一个File

    package iotest;
    
    import java.io.File;
    
    /**
     * Created by Arenas on 2016/10/31.
     * 递归找出所有子文件
     */
    public class FileTest01 {
        public static void main(String[] args)throws Exception{
            File file = new File("D:/Android");
            findAllFile(file);
        }
    
        public static void findAllFile(File file){
            //当是文件的时候就返回
            if (file.isFile())
                return;
            //当是目录的时候就遍历所有文件
            File[] files = file.listFiles();
            for (File f : files){
                System.out.println(f.getAbsolutePath());
                findAllFile(f);
            }
        }
    }
  • 相关阅读:
    Gentoo 使用genkernel之后,修改了kernel,重新编译kernel和生成initramfs
    如何让git自动在commit message中加入你需要的sob?
    Gentoo:请安装bashcompletion package
    Kernel开发 SubmittingPatches,有关ifdef和static inline & macro
    Kernel开发 Thunderbird配置 From kernel documentation
    Gentoo 添加gentoozh overlay
    linux把文件压缩成.tar.gz的命令
    redhat下装ftp服务器(vsftpd)
    GDB调试精粹及使用实例
    linux中常用的头文件
  • 原文地址:https://www.cnblogs.com/i-love-kobe/p/6007189.html
Copyright © 2011-2022 走看看