17_IO编程

百知教育 - 孙帅 - 17_IO编程

10_对象序列化的细节

  1. 类实现了Serializable接口: 此类对象反序列化不会调用构造方法。
  2. 该类继承的父类实现了Serializable接口: 反序列化时,父类对象和此类对象都不会调用构造方法。
  3. 该类实现了Serializable接口而父类没有实现: 反序列化时,父类调用无参构造方法重建对象,而该类对象不会调用构造方法。
  • 代码1(利用异常EOFException判断对象文件结尾,跳出死循环):
    package day23;
    import java.io.*;
    public class TestObjectStreamRead{
     public static void main(String[] args){
      FileInputStream fis = null;
      ObjectInputStream ois = null;
      try{
       fis = new FileInputStream("student.dat");
       ois = new ObjectInputStream(fis);
       while(true){
        Object o = ois.readObject();
        System.out.println(o);
       }
      }catch(Exception e){
       System.out.println("end of file");
      }finally{
       try{
        ois.close();
       }catch(IOException e){
        e.printStackTrace();
       }
      }
     }
    }
  • 运行结果:
    在这里插入图片描述
  • 代码2:
    package day23;
    import java.io.*;
    public class TestDeSerializable{
     public static void main(String[] args){
      FileOutputStream fos = null;
      ObjectOutputStream oos = null;
      try{
       fos = new FileOutputStream("student.dat");
       oos = new ObjectOutputStream(fos);
       B b = new B();
       oos.writeObject(b);
       System.out.println("Write Over");
      }catch(Exception e){
       e.printStackTrace();
      }finally{
       try{
        oos.close();
       }catch(IOException e){
        e.printStackTrace();
       }
      }
      
      
      FileInputStream fis = null;
      ObjectInputStream ois = null;
      try{
       fis = new FileInputStream("student.dat");
       ois = new ObjectInputStream(fis);
       ois.readObject();
       System.out.println("Read Over");
      }catch(Exception e){
       e.printStackTrace();
      }finally{
       try{
        ois.close();
       }catch(IOException e){
        e.printStackTrace();
       }
      }
     }
    }
    class A {
     public A(){
      System.out.println("A()");
     }
    }
    class B extends A implements Serializable{
     public B(){
      System.out.println("B()");
     }
    }
  • 运行结果:
    在这里插入图片描述

11_自定义序列化

-反序列化先调用无参构造方法再调用自定义序列化规则 重建对象。

  • 代码:
    package day23;
    import java.io.*;
    public class TestExternalizable{
     public static void main(String[] args){
      Student s1 = new Student("YKY" , 20);
      
      FileOutputStream fos = null;
      ObjectOutputStream oos = null;
      try{
       fos = new FileOutputStream("student.dat");
       oos = new ObjectOutputStream(fos);
       oos.writeObject(s1);
       System.out.println("Write Over");
       oos.close();
      }catch(Exception e){
       e.printStackTrace();
      }
      
      FileInputStream fis = null;
      ObjectInputStream ois = null;
      
      try{
       fis = new FileInputStream("student.dat");
       ois = new ObjectInputStream(fis);
       Object o1 = ois.readObject();
       System.out.println(o1);
       System.out.println("Read Over");
       ois.close();
      }catch(Exception e){
       e.printStackTrace();
      }
     }
    }
    class Student implements Externalizable{
     String name;
     int age;
     
     public Student(String name , int age){
      this.name = name;
      this.age = age;
     }
     public Student(){}
     
     @Override
     public String toString(){
      return "Student [name="+name+", age="+age+"]";
     }
     
     @Override
     public void writeExternal(ObjectOutput out) throws IOException{
      out.writeUTF(name);
      out.writeInt(age);
     }
     
     @Override
     public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException{
      name = in.readUTF();
      age = in.readInt();
     }
    }
  • 运行结果:
    在这里插入图片描述

12_对象的浅克隆与深克隆

  • 代码:
    package day23;
    import java.io.*;
    public class TestClone{
     public static void main(String[] args){
      Address addr = new Address();
      Worker w = new Worker("YKY" , 20 , addr);
      try{
       Object o = w.clone(); 
       Worker w1 = (Worker)o;
       System.out.println(w == w1);
       System.out.println(w.addr == w1.addr);
      }catch(CloneNotSupportedException e){
       e.printStackTrace();
      }
     }
    }
    class Worker implements Serializable , Cloneable{
     String name;
     int age;
     Address addr;
     
     public Worker(){}
     public Worker(String name , int age , Address addr){
      this.name = name;
      this.age = age;
      this.addr = addr;
     }
     
     @Override
     public String toString(){
      return "Worker [name="+name+", age="+age+", addr="+addr+"]";
     }
     
     @Override
     public Object clone() throws CloneNotSupportedException{
      
      ByteArrayOutputStream baos = null;
      ObjectOutputStream oos = null;
      byte[] bs = null;
      try{
       baos = new ByteArrayOutputStream();
       oos = new ObjectOutputStream(baos);
       oos.writeObject(this);
       bs = baos.toByteArray();
      }catch(IOException e){
       e.printStackTrace();
      }finally{
       try{
        oos.close();    
       }catch(IOException e){
        e.printStackTrace();
       }
      }
      
      ByteArrayInputStream bais = null;
      ObjectInputStream ois = null;
      Object o = null;
      try{
       bais = new ByteArrayInputStream(bs);
       ois = new ObjectInputStream(bais);
       o = ois.readObject();
      }catch(IOException e){
       e.printStackTrace();
      }finally{
       try{
        ois.close();    
       }catch(IOException e){
        e.printStackTrace();
       }   
       return o;
      }
     }
    }
    class Address implements Serializable{
     String addr;
    }
  • 运行结果:
    在这里插入图片描述

13_中文乱码问题

  • 字符的编码:
    字符的编码方式和解码方式不统一,可能造成乱码问题。
  • 几种常见的编码方式:
    • ASCII: 美国
    • ISO-8859-1: 西欧
    • GB2312: 早期简体中文
    • GBK: 扩充版简体中文
    • Big5: 繁体中文(台湾、澳门、香港)
  • 代码:
    package day23;
    import java.io.UnsupportedEncodingException;
    public class TestEncoding{
     public static void main(String[] args){
      String str = "中关村软件园百知教育";
      try{
       byte[] bs = str.getBytes("GBK");  //编码   
       String str1 = new String(bs, "Big5");  //解码
       System.out.println(str);
       System.out.println(str1);
      }catch(UnsupportedEncodingException e){
       e.printStackTrace();
      }
     }
    }
  • 运行结果:
    在这里插入图片描述

14_UTF-8编码方式

  • Unicode
    • 全球统一
    • UTF-16
    • UTF-8
  • 所有语种向上兼容ASCII编码方式,因此英文不会出现乱码
  • 代码:
    package day23;
    import java.io.UnsupportedEncodingException;
    public class TestEncoding{
     public static void main(String[] args){
      String str = "到百知,学Java";
      try{
       byte[] bs = str.getBytes("GBK");  //编码   
       String str1 = new String(bs, "Big5");  //解码
       System.out.println(str);
       System.out.println(str1);
      }catch(UnsupportedEncodingException e){
       e.printStackTrace();
      }
     }
    }
  • 运行结果:
    在这里插入图片描述

15_字符流

  • Reader/Writer
    字符流 的父类,抽象类
    • FileReader/FileWriter 文件字符流,节点流
    • BufferedReader/BufferedWriter 缓冲流,过滤流
    • PrintWriter 缓冲流,过滤流
    • InputStreamReader/OutputStreamWriter 常叫 桥转换类,具有桥转换功能,即 将字节流转换为字符流转换时可以指定编码方式
  • 代码(!!!PrintWriter是缓冲流,要用flush方法将数据从缓冲区写入文件,才能正确读文件):
    package day23;
    import java.io.*;
    public class TestReaderAndWriter{
     public static void main(String[] args){
      FileOutputStream fos = null;
      OutputStreamWriter fw = null;
      PrintWriter pw = null;
      
      FileInputStream fis = null;
      InputStreamReader fr = null;
      BufferedReader br = null;
      try{
       fos = new FileOutputStream("b.txt");
       fw = new OutputStreamWriter(fos , "GBK");
       pw = new PrintWriter(fw);
       //pw = new PrintWriter("b.txt"); //等价于上面三行,一步到位
       pw.println("闺中少妇不知愁");
       pw.println("春日凝妆上翠楼");
       pw.println("忽见陌头杨柳色");
       pw.println("悔教夫婿觅封侯");
       pw.flush();  //!!!把缓冲区里的数据写入文件
       System.out.println("Write Over");
       
       fis = new FileInputStream("b.txt");
       fr = new InputStreamReader(fis , "GBK");
       br = new BufferedReader(fr);
       System.out.println("Read Begin");
       while(true){
        String s = br.readLine();  //每次读一行,读到换行符结束    
        if(s == null) break;
        System.out.println(s);
       }  
      }catch(Exception e){
       e.printStackTrace();
      }finally{
       try{
        //pw.close();
        br.close();
       }catch(IOException e){
        e.printStackTrace();
       }
      }
     }
    }
  • 运行结果:
    在这里插入图片描述

16_File类

  • IO流:
    对文件中的内容进行操作。
  • File类:
    • 对文件自身进行操作,例如:删除文件,文件重新命名等。
    • File 只代表 文件 或是 文件夹 ,不具有操作文件的功能所有的操作基于它提供的方法。
  • File类常用方法:
    1. public boolean createNewFile(): 创建文件,创建成功返回true,如果文件存在返回值为false。
    2. public boolean mkdir() 创建文件夹,创建成功返回true,如果文件存在返回值为false。
    3. public boolean delete 删除文件夹/文件,删除成功返回true,否则返回false。
      1. 当删除文件夹时,只有当文件夹为空时,才可以被删除。
      2. 而删除文件是,不管文件内容是否为空,都会被删除。
    4. public boolean renameTo(File f) 更改文件的名字,更改成功返回true,否则返回false。
    5. public boolean setReadOnly() 设置文件为只读。
    6. public String getName() 获取文件名(含扩展名)、文件夹名。
    7. public boolean exists() 判断一个文件或是目录是否存在,存在返回true,否则返回false。
    8. public String getAbsolutePath() 获得绝对路径。
    9. public File[] listFile() 获取当前文件夹下所有的文件、文件夹。
    10. public boolean isFile() 判断File对象所对应的是否为文件,而不是目录。
    11. public boolean isDirectory() 判断File对象所对应的是否为目录,而不是文件。
  • 代码:
    package day23;
    import java.io.*;
    public class TestFile{
     public static void main(String[] args){
      /*
      File f = new File("abc");
      try{
       f.createNewFile();   
      }catch(IOException e){
       e.printStackTrace();
      }
      f.delete();
      f.mkdir();
      */
      
      /*
      File dir = new File("C:\\Users\\念衷\\desktop\\java");
      File[] fs = dir.listFiles();
      for(File f : fs){
       System.out.print(f.getName()+"   ");
       if(f.isFile()) System.out.println("文件");
       if(f.isDirectory()) System.out.println("目录");
      }
      */
      
      /*
      File dir = new File("abc");
      deleteDir(dir);
      */
      
      /*
      File dir = new File("C:\\Users\\念衷\\desktop\\java");
      File[] fs = dir.listFiles(new FileFilter(){
       public boolean accept(File pathname){
        return pathname.isFile();
       }
      });
      for(File f : fs){
       System.out.println(f.getName());
      }
      */
      
      File dir = new File("C:\\Users\\念衷\\desktop\\java");
      listJavaFiles(dir);
     }
     static void deleteDir(File dir){
      File[] fs = dir.listFiles();
      for(File f : fs){
       if(f.isFile()) f.delete();
       if(f.isDirectory()) deleteDir(f);
       }
      dir.delete();
     }
     static void listJavaFiles(File dir){
      File[] fs = dir.listFiles(new FileFilter(){
       public boolean accept(File pathname){
        if(pathname.isFile()){
         return pathname.getName().endsWith(".java");
        }
        if(pathname.isDirectory()){
         listJavaFiles(pathname);
        }
        return false;
       }
      });
      for(File f : fs){
       System.out.println(f.getName());
      }
     }
    }
  • 运行结果:
    在这里插入图片描述

17_NIO_Buffer

  • ByteBuffer的两种创建方式:
    1. ByteBuffer.allocate(capacity)
    2. ByteBuffer.wrap(byte[] bs);
  • ByteBuffer中的方法:
    1. flip() 使position = 0 , 一般用来从 写模式切换到读模式
    2. clear() 使position = 0 ,limit = 0 , 一般用来从 读模式切换到写模式
  • ByteBuffer中的三个重要指针:
    1. position 当前读写位置
    2. limit 限制,即实际所存内容的capacity
    3. capacity 容量
  • 代码:
    package day23;
    import java.io.*;
    import java.nio.CharBuffer;
    import java.nio.charset.Charset;
    import java.nio.channels.FileChannel;
    import java.nio.ByteBuffer;
    public class TestBuffer{
     public static void main(String[] args){
      //ByteBuffer buffer = ByteBuffer.allocate(20);
      /*
      FileOutputStream fos = null;
      FileChannel channel = null;
      ByteBuffer buffer = null;
      try{
       fos = new FileOutputStream("a.txt");
       channel = fos.getChannel();
       buffer = ByteBuffer.wrap("HelloWorld".getBytes());
       channel.write(buffer);
      }catch(IOException e){
       e.printStackTrace();
      }finally{
       try{    
        channel.close(); 
       }catch(IOException e){
        e.printStackTrace();
       }
      }
      */
      
      FileInputStream fis = null;
      FileChannel channel = null;
      ByteBuffer buffer = null;
      try{
       fis = new FileInputStream("a.txt");
       channel = fis.getChannel();
       buffer = ByteBuffer.allocate(10);
       
       /*
       System.out.println(channel.read(buffer));
       byte[] bs = buffer.array();
       for(byte b : bs){
        System.out.print((char)b);
       }
       System.out.println();
       */
       
       while(true){
        int len = channel.read(buffer);
        if(len == -1) break;
        buffer.flip();
        while(buffer.hasRemaining()){
         System.out.print((char)(buffer.get()));
        }
        System.out.println();
        buffer.clear();
       }
      }catch(IOException e){
       e.printStackTrace();
      }finally{
       try{    
        channel.close(); 
       }catch(IOException e){
        e.printStackTrace();
       }
      }
      
      ByteBuffer bb = ByteBuffer.wrap("百知教育".getBytes());
      
      Charset cs = Charset.forName("GBK");
      Charset bs2 = Charset.forName("Big5");
      ByteBuffer bb2 = cs.encode("百知教育");
      
      CharBuffer cb = cs.decode(bb2);
      
      System.out.println(cb);
     }
    }
  • 运行结果:
    在这里插入图片描述

18_利用NIO实现文件拷贝

  • 代码:
    package day23;
    import java.io.*;
    import java.nio.MappedByteBuffer;
    import java.nio.channels.FileChannel;
    import java.nio.ByteBuffer;
    public class TestNIOFileCopy{
     public static void main(String[] args){
      
      long t1 = System.currentTimeMillis();
      fileCopy2("04_用节点流实现文件拷贝.wmv" , "04_用节点流实现文件拷贝1.wmv");
      long t2 = System.currentTimeMillis();
      System.out.println("字节数组拷贝:"+(t2-t1));
      long t3 = System.currentTimeMillis();
      fileCopy3("04_用节点流实现文件拷贝.wmv" , "04_用节点流实现文件拷贝1.wmv");
      long t4 = System.currentTimeMillis();
      System.out.println("缓冲字节数组拷贝:"+(t4-t3));
      long t5 = System.currentTimeMillis();
      fileCopy4("04_用节点流实现文件拷贝.wmv" , "04_用节点流实现文件拷贝1.wmv");
      long t6 = System.currentTimeMillis();
      System.out.println("ByteBuffer拷贝:"+(t6-t5));
      long t7 = System.currentTimeMillis();
      fileCopy5("04_用节点流实现文件拷贝.wmv" , "04_用节点流实现文件拷贝1.wmv");
      long t8 = System.currentTimeMillis();
      System.out.println("MappedByteBuffer拷贝:"+(t8-t7));
      long t9 = System.currentTimeMillis();
      fileCopy5("04_用节点流实现文件拷贝.wmv" , "04_用节点流实现文件拷贝1.wmv");
      long t10 = System.currentTimeMillis();
      System.out.println("FileChannel的transferTo方法拷贝:"+(t10-t9));
     }
     static void fileCopy2(String srcName , String destName){
      InputStream in = null;
      OutputStream out = null;
      byte[] bs = new byte[1024];
      try{
       in = new FileInputStream(srcName);
       out = new FileOutputStream(destName);
       while(true){
        int len = in.read(bs);
        if(len == -1) break;
        out.write(bs , 0 , len);
       }
      }catch(Exception e){
       e.printStackTrace();
      }finally{
       try{
        in.close();
        out.close();
       }catch(IOException e){
        e.printStackTrace();
       }
      }
     }
     static void fileCopy3(String srcName , String destName){
      InputStream in = null;
      BufferedInputStream bis = null;
      OutputStream out = null;
      BufferedOutputStream bos = null;
      byte[] bs = new byte[1024];
      try{
       in = new FileInputStream(srcName);
       bis = new BufferedInputStream(in);
       out = new FileOutputStream(destName);
       bos = new BufferedOutputStream(out);
       while(true){
        int len = bis.read(bs);
        if(len == -1) break;
        bos.write(bs , 0 , len);
       }
      }catch(Exception e){
       e.printStackTrace();
      }finally{
       try{
        bis.close();
        bos.close();
       }catch(IOException e){
        e.printStackTrace();
       }
      }
     }
     static void fileCopy4(String srcName , String destName){
      FileInputStream fis = null;
      FileOutputStream fos = null;
      FileChannel fc1 = null;
      FileChannel fc2 = null;
      ByteBuffer buffer = ByteBuffer.allocate(1024);
      try{
       fis = new FileInputStream(srcName);
       fos = new FileOutputStream(destName);
       fc1 = fis.getChannel();
       fc2 = fos.getChannel();
       
       while(true){
        int len = fc1.read(buffer);
        if(len == -1) break;
        buffer.flip();
        fc2.write(buffer);
        buffer.clear();
       }
       
      }catch(IOException e){
       e.printStackTrace();
      }finally{
       try{
        fc1.close();
        fc2.close();
       }catch(IOException e){
        e.printStackTrace();
       }
      }
     }
     static void fileCopy5(String srcName , String destName){
      FileInputStream fis = null;
      FileOutputStream fos = null;
      FileChannel fc1 = null;
      FileChannel fc2 = null;
      try{
       fis = new FileInputStream(srcName);
       fos = new FileOutputStream(destName);
       fc1 = fis.getChannel();
       fc2 = fos.getChannel();
       
       MappedByteBuffer buffer = fc1.map(FileChannel.MapMode.READ_ONLY , 0 , fc1.size());
       fc2.write(buffer);
       
      }catch(IOException e){
       e.printStackTrace();
      }finally{
       try{
        fc1.close();
        fc2.close();
       }catch(IOException e){
        e.printStackTrace();
       }
      }
     }
     static void fileCopy6(String srcName , String destName){
      FileInputStream fis = null;
      FileOutputStream fos = null;
      FileChannel fc1 = null;
      FileChannel fc2 = null;
      try{
       fis = new FileInputStream(srcName);
       fos = new FileOutputStream(destName);
       fc1 = fis.getChannel();
       fc2 = fos.getChannel();
       
       fc1.transferTo(0 , fc1.size() , fc2);
       
      }catch(IOException e){
       e.printStackTrace();
      }finally{
       try{
        fc1.close();
        fc2.close();
       }catch(IOException e){
        e.printStackTrace();
       }
      }
     }
    }
  • 运行结果:
    在这里插入图片描述
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值