IO

作者: zlb | 来源:发表于2016-05-26 11:35 被阅读50次
    IO结构

    IO流:用于处理设备上的数据,即:InputStream,OutputStream

    IO流的具体分类:
    1,根据处理的数据类型不同分为:字节流与字符流
    2,根据流的方向不同分为:输出流与输入流

    字符流的由来:
    因为文件的编码不同,而有了对字符进行高效操作的字符流对象
    原理:其实就是基于字节流读取数据时,去查了 指定编码表

    字节流与字符流的区别
    1,字节流读取的 时候,读取一个字节就返回一个字节,
    字符流使用了字节流读取到一个或多个字节流时,先去查指定的编码 表,将查到的字符返回
    2,字节流能够读取所有的类型数据,而字符流只能处理字符类型

    一.File

    • 目录列表
      假设我们想查看目录列表,可使用list()方法查看File对象下所有的目录,但是如果想查看类型为.java类的文件,那么我们就使用“目录过滤器”
    package File;
    import java.io.File;
    import java.io.FilenameFilter;
    import java.util.Arrays;
    import java.util.regex.Pattern;
    public class DirList {
        public static void main(String[] args) {
            File file = new File(".");
            String[] list;
            list = file.list(new DirFilter(".*"));
            Arrays.sort(list,String.CASE_INSENSITIVE_ORDER);
            for(String str : list){
                System.out.println(str);
            }
        }
    }
    package File;
    import java.io.File;
    import java.io.FilenameFilter;
    import java.util.regex.Pattern;
    public class DirFilter implements FilenameFilter{
        private Pattern pattern;
        public DirFilter(String filenName){
            pattern = Pattern.compile(filenName);
        }
        @Override
        public boolean accept(File dir, String name) {
            return pattern.matcher(name).matches();
        }
    }
    

    DirFilter 这个类存在的原因就是把accept() 方法提供给 list() 使用,使list()可以回调accept() 进而决定哪些文件包含在列表里 这就是策略模式的体现
    list()方法会为此目录下的所有的方法都调用accept()方法,来判断此文件是否在内

    • 目录的检查及创建
      File 类不仅仅只代表存在的目录,也可以用File对象来创建不存在的目录,也可以用File查看文件的各种特性

    输入流 InputStream

    InputStream

    每一种数据源都有相应的InputStream子类,因为InputStream是个处于顶层的类,用来处理各种数据源的类都继承了InputStream类,我们来看看这些类:
    ByteArrayInputStream:处理字节数组的类,允许将内存的缓冲区当做InputStream使用。
    StringBufferInputStream:将String转换成InputStream,内部实现用的是StringBuffer。
    FileInputStream:从文件中读取数据。
    PipedInputStream:用于从管道中读取数据。
    SequenceInputStream:将多个流对象转化成一个InputStream。
    FilterInputStream:装饰器类,为其它InputStream类提供功能。

    • 读取文件内容
     package InputStream;
    import java.io.BufferedReader;
    import java.io.FileReader;
    import java.io.IOException;
    public class BufferedInputFile2 {
        public static String read(String fileName) throws IOException{
            BufferedReader br = new BufferedReader(new FileReader(fileName));
            StringBuilder sb =  new StringBuilder();
            String s = "";
            while((s = br.readLine())!=null){
                sb.append(s+"\n");
            }
            if(br!=null){
                br.close();
            }
            return sb.toString();
        }
        public static void main(String[] args) {
            try {
        System.out.println(read("E:\\WorkSpaceSSH\\Demo_18\\src\\InputStream\\BufferedInputFile.java"));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
    * DataInputStream类
    import java.io.DataInputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    public class DataOutputStreamDemo{
       public static void main(String[] args) throws IOException{
           File file = new File("d:" + File.separator +"hello.txt");
           DataInputStream input = new DataInputStream(new FileInputStream(file));
           char[] ch = new char[10];
           int count = 0;
           char temp;
           while((temp = input.readChar()) != 'C'){
               ch[count++] = temp;
           }
           System.out.println(ch);
        }
    }
    

    输出流 OutputStream

    outputstream

    OutputStream 是所有的输出字节流的父类,它是一个抽象类。
    ByteArrayOutputStream、FileOutputStream是两种基本的介质流,它们分别向Byte 数组、和本地文件中写入数据。PipedOutputStream 是向与其它线程共用的管道中写入数据,
    ObjectOutputStream 和所有FilterOutputStream的子类都是装饰流。具体例子跟InputStream是对应的。

    • 文件复制
    import java.io.*;
    class hello{
       public static void main(String[] args) throws IOException {
           if(args.length!=2){
               System.out.println("命令行参数输入有误,请检查");
               System.exit(1);
           }
           File file1=new File(args[0]);
           File file2=new File(args[1]);
           if(!file1.exists()){
               System.out.println("被复制的文件不存在");
               System.exit(1);
           }
           InputStream input=new FileInputStream(file1);
           OutputStream output=new FileOutputStream(file2);
           if((input!=null)&&(output!=null)){
               int temp=0;
               while((temp=input.read())!=(-1)){
                    output.write(temp);
               }
           }
           input.close();
           output.close();
        }
    }
    
    * DataOutputStream
    import java.io.DataOutputStream;
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.IOException;
    public class DataOutputStreamDemo{
       public static void main(String[] args) throws IOException{
           File file = new File("d:" + File.separator +"hello.txt");
           char[] ch = { 'A', 'B', 'C' };
           DataOutputStream out = null;
           out = new DataOutputStream(new FileOutputStream(file));
           for(char temp : ch){
               out.writeChar(temp);
           }
           out.close();
        }
    }
    

    添加属性和有用的接口

    java IO 类库需要多种不同功能的组合,这正是使用装饰器模式的理由所在
    这也是java IO类库里存在filter(过滤器)的原因所在,抽象类filter是所有装饰器的基类。装饰器类必须和它所装饰的类具有相同的接口,但它也可以扩展
    装饰器在给我们提供许多灵活性的时候也给我们带来了复杂性,我们必须创建许多类 才能得到我们需要的单个的IO对象

    Reader 和 Writer

    Reader 是所有的输入字符流的父类,它是一个抽象类。
    Writer 是所有的输出字符流的父类,它是一个抽象类
    设计Reader和Writer主要是为了国际化,老的IO流仅支持8位的字节流,不能很好的支持16位的,所以添加Reader和Writer就是为了所有的IO操作中能很好地 支持Unicode
    InputStreamReader 可以把 InputStream 转化为 Reader
    OutoutStreamWrite 可以把OutputStream转化为Write

    • 从文件中读取数据
    import java.io.*;
    class hello{
       public static void main(String[] args) throws IOException {
           String fileName="D:"+File.separator+"hello.txt";
           File f=new File(fileName);
           char[] ch=new char[100];
           Reader read=new FileReader(f);
           int temp=0;
           int count=0;
           while((temp=read.read())!=(-1)){
               ch[count++]=(char)temp;
           }
           read.close();
           System.out.println("内容为"+new String(ch,0,count));
        }
    }
    
    • BufferedReader
      注意:BufferedReader只能接受字符流的缓冲区,因为每一个中文需要占据两个字节,所以需要将System.in这个字节输入流变为字符输入流
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    public class BufferedReaderDemo{
       public static void main(String[] args){
           BufferedReader buf = new BufferedReader(
                    newInputStreamReader(System.in));
           String str = null;
           System.out.println("请输入内容");
           try{
               str = buf.readLine();
           }catch(IOException e){
               e.printStackTrace();
           }
           System.out.println("你输入的内容是:" + str);
        }
    }
    

    字节流与字符流的转换

    InputStreamReader:字节到字符的桥梁
    OutputStreamWriter:字符到字节的桥梁
    这两个流对象是字符体系中的成员,它们有转换作用,本身又是字符流,所以在构造的时候需要传入字节流对象进来。

    //将字节输出流转化为字符输出流
    import java.io.*;
    class hello{
       public static void main(String[] args) throws IOException {
           String fileName= "d:"+File.separator+"hello.txt";
           File file=new File(fileName);
           Writer out=new OutputStreamWriter(new FileOutputStream(file));
           out.write("hello");
           out.close();
        }
    
    //将字节输入流变为字符输入流
    import java.io.*;
    class hello{
       public static void main(String[] args) throws IOException {
           String fileName= "d:"+File.separator+"hello.txt";
           File file=new File(fileName);
           Reader read=new InputStreamReader(new FileInputStream(file));
           char[] b=new char[100];
           int len=read.read(b);
           System.out.println(new String(b,0,len));
           read.close();
        }
    }
    

    标准IO流

    标准IO模型,java提供了System.in,System.out,System.err
    其中System.err和System.out都已报装成了PrintStream 但是System.in
    却是一个未被报装过的InputStream,所以在System.in之前要对其进行包装

    package OutputStream;
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    public class Echo {
        public static void main(String[] args) {
            BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
            String c = "";
            try {
                while((c=reader.readLine())!=null&&c.length()!=0){
                    System.out.println(c);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
    • 将System.out 转换为PrintWrite
      System.out 是一个PrintStream 而PrintStream 是一个OutputStream 而PrintWrite有一个可以接受OutputStream 参数的构造器
    PrintWriter out = new PrintWriter(System.out,true);
            out.println("hello ");
    

    压缩

    • 利用GZIP进行简单的压缩
      GZIP接口非常的简单,如果要对单个的数据流进行压缩,GZIP就很合适
    package zip;
    import java.io.BufferedOutputStream;
    import java.io.BufferedReader;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.FileReader;
    import java.io.InputStreamReader;
    import java.util.zip.GZIPInputStream;
    import java.util.zip.GZIPOutputStream;
    public class GIZPcomress {
        public static void main(String[] args) {
            try {
                BufferedReader br = new BufferedReader(
                        new FileReader(
                                "E:\\WorkSpaceSSH\\Demo_18\\src\\InputStream\\BufferedInputFile.java"));
                BufferedOutputStream os = new BufferedOutputStream(
                        new GZIPOutputStream(
                                new FileOutputStream(
                                        "E:\\WorkSpaceSSH\\Demo_18\\src\\InputStream\\BufferedInputFile4.java")));
                System.out.println("write file");
                int c;
                while ((c = br.read()) != -1) {
                    os.write(c);
                }
                br.close();
                os.close();
                System.out.println("read file");
                BufferedReader br2 = new BufferedReader(
                        new InputStreamReader(
                                new GZIPInputStream(
                                        new FileInputStream(
                                                "E:\\WorkSpaceSSH\\Demo_18\\src\\InputStream\\BufferedInputFile4.java"))));
                String s = "";
                while ((s = br2.readLine()) != null) {
                    System.out.println(s);
                }
            } catch (Exception e) { 
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
    
    • 用zip 进行压缩 解压
    package zip;
    import java.io.BufferedInputStream;
    import java.io.BufferedOutputStream;
    import java.io.BufferedReader;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.FileReader;
    import java.util.zip.Adler32;
    import java.util.zip.CheckedInputStream;
    import java.util.zip.CheckedOutputStream;
    import java.util.zip.ZipEntry;
    import java.util.zip.ZipInputStream;
    import java.util.zip.ZipOutputStream;
    //压缩
    public class ZipCompress {
        public static void main(String[] args) {
            try {
                FileOutputStream fos = new FileOutputStream("E:\\WorkSpaceSSH\\Demo_18\\src\\InputStream\\BufferedInputFile5.zip");
                CheckedOutputStream cs = new CheckedOutputStream(fos, new Adler32());
                ZipOutputStream zs = new ZipOutputStream(fos);
                BufferedOutputStream bos = new BufferedOutputStream(zs);
                zs.setComment("this is zip file");
                System.out.println("开始压缩");
                BufferedReader reader = new BufferedReader(new FileReader("E:\\WorkSpaceSSH\\Demo_18\\src\\InputStream\\BufferedInputFile.java"));
                zs.putNextEntry(new ZipEntry("E:\\WorkSpaceSSH\\Demo_18\\src\\InputStream\\BufferedInputFile.java"));
                int s = 0;
                while((s=reader.read())!=-1){
                    bos.write(s);
                }
                bos.close();
                System.out.println("checkNum:"+cs.getChecksum().getValue());
                System.out.println("开始读文件");
                FileInputStream fis = new FileInputStream("E:\\WorkSpaceSSH\\Demo_18\\src\\InputStream\\BufferedInputFile5.zip");
                CheckedInputStream cis = new CheckedInputStream(fis, new Adler32());
                ZipInputStream zi = new ZipInputStream(fis);
                BufferedInputStream bis = new BufferedInputStream(zi);
                ZipEntry zn = null;
                while((zn = zi.getNextEntry())!=null){
                    System.out.println("this file:"+zn);
                    int n = 0;
                    while((n = bis.read())!=-1){
                        System.out.write(n);
                    }
                }
                System.out.println("checkNum:"+cs.getChecksum().getValue());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    

    序列化

    Java平台允许我们在内存中创建可复用的Java对象,但一般情况下,只有当JVM处于运行时,这些对象才可能存在,即,这些对象的生命周期不会比JVM的生命周期更长。但在现实应用中,就可能要求在JVM停止运行之后能够保存(持久化)指定的对象,并在将来重新读取被保存的对象。Java对象序列化就能够帮助我们实现该功能。java 的对象的序列化将那些实现了Serializable接口的对象转换成字节序列,并且能够在以后将字节序列恢复为原来的对象
    什么时候用序列化:
    a)当你想把的内存中的对象保存到一个文件中或者数据库中时候;
    b)当你想用套接字在网络上传送对象的时候;
    c)当你想通过RMI传输对象的时候;

    package Serializable;
    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 A {
        private static int i = 10;
        private transient static String s = "java";
        public static void main(String[] args) {
            try {
                User user = new User();
                user.setSex('男');
                user.setUsername("小李");
                user.setUserpass("123");
                ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("user.out"));
                oos.writeObject(user);
                oos.close();
                ObjectInputStream ois = new ObjectInputStream(new FileInputStream("user.out"));
                User user2 = (User)ois.readObject();
                //String ss = ois.readUTF();
                //System.out.println(ss);
                System.out.println(user2.getUsername());
                System.out.println(user2.getSex());
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
    }
    
    • 序列化的控制
      有时候我们不想整个对象都序列化,只需要对象的一部分序列化,此时就应该用到:Externalizable
      Externalizable 是一个接口 需要实现两个方法writeExternal(),readExternal()
    package Serializable;
    import java.io.Externalizable;
    import java.io.IOException;
    import java.io.ObjectInput;
    import java.io.ObjectOutput;
    public class Bilp1 implements Externalizable{
        private User user;
        public Bilp1(){
            System.out.println("Bilp1()");
        }
        public Bilp1(User user){
            this.user = user;
        }
        @Override
        public void writeExternal(ObjectOutput out) throws IOException {
            // TODO Auto-generated method stub
            //out.writeObject(user);
            System.out.println("writeExternal()");
        }
        @Override
        public void readExternal(ObjectInput in) throws IOException,
                ClassNotFoundException {
            // TODO Auto-generated method stub
            System.out.println("readExternal()");
        }
    }
    
    • transient关键字
      当某个字段被声明为transient后,默认序列化机制就会忽略该字段。此处将User类中的username字段声明为transient
    private transient String username;
    

    相关文章

      网友评论

          本文标题:IO

          本文链接:https://www.haomeiwen.com/subject/oktxdttx.html