【JAVA基础】23 IO流-其他流

1. 序列流

  • 什么是序列流

    • 序列流可以把多个字节输入流整合成一个,从序列流中读取数据时,将从被整合的第一个流开始读,读完一个之后继续读第二个, 以此类推.

  • 类:

    • java.io.SequenceInputStream
      • 构造方法:
        • SequenceInputStream(InputStream s1, InputStream s2)   通过记住这两个参数来初始化新创建的SequenceInputStream(将按顺序读取这两个参数),以提供从此SequenceInputStream读取的字节。
        • SequenceInputStream(Enumeration<? extends InputStream> e)   通过记住参数来初始化新创建的SequenceInputStream,该参数必须是生成运行时类型为InputStream对象的Enumeration型参数。
      • 方法:
        • int available()    返回不受阻塞地从当前底层输入流读取(或跳过)的字节数的估计值,方法是通过下一次调用当前底层输入流的方法。
        • void close()    关闭此输入流并释放与此流关联的所有系统资源。
        • int read()     从此输入流中读取下一个数据字节。
        • int read(byte[] b, int off, int len)      将最多 len 个数据字节从此输入流读入 byte 数组。
  • 整合两个的实例:
    • SequenceInputStream(InputStream, InputStream)
    • package com.heima.otherio;
      
      import java.io.FileInputStream;
      import java.io.FileOutputStream;
      import java.io.FileWriter;
      import java.io.IOException;
      import java.io.SequenceInputStream;
      
      public class Demo1_SequenceInputStream {
      
          /**
           * @param args
           * @throws IOException 
           */
          public static void main(String[] args) throws IOException {
              FileInputStream fis1 = new FileInputStream("a.txt");
              FileInputStream fis2 = new FileInputStream("b.txt");
              
              SequenceInputStream sis = new SequenceInputStream(fis1, fis2);
              FileOutputStream fos = new FileOutputStream("out.txt");
              
              int b;
              while((b = sis.read()) != -1) {
                  fos.write(b);
              }
              
              sis.close();
              fos.close();
              
          }
      }
      View Code
  • 整合多个的实例:
    • SequenceInputStream(Enumeration)
    • package com.heima.otherio;
      
      import java.io.FileInputStream;
      import java.io.FileNotFoundException;
      import java.io.FileOutputStream;
      import java.io.IOException;
      import java.io.InputStream;
      import java.io.SequenceInputStream;
      import java.util.Enumeration;
      import java.util.Vector;
      
      public class Demo2_SequenceInputStream {
      
          /**
          整合多个序列流
          SequenceInputStream(Enumeration<? extends InputStream> e) 
                通过记住参数来初始化新创建的 SequenceInputStream,该参数必须是生成运行时类型为 InputStream 对象的 Enumeration 型参数。
           * @throws IOException 
           */
          public static void main(String[] args) throws IOException {
              FileInputStream fis1 = new FileInputStream("a.txt"); 
              FileInputStream fis2 = new FileInputStream("b.txt"); 
              FileInputStream fis3 = new FileInputStream("c.txt"); 
              
              Vector<InputStream> v = new Vector<>(); //创建vector集合对象 
              v.add(fis1); //将流对象添加 
              v.add(fis2); 
              v.add(fis3); 
              Enumeration<InputStream> en = v.elements(); //获取枚举引用 
              SequenceInputStream sis = new SequenceInputStream(en); //传递给SequenceInputStream构造 
              FileOutputStream fos = new FileOutputStream("out.txt"); 
              
              int b; 
              while((b = sis.read()) != -1) { 
                  fos.write(b); 
                  }
      
              sis.close();
              fos.close();
          }
      
      }
      View Code

2. 内存输出流

  • 什么是内存输出流

    • 该输出流可以向内存中写数据,把内存当作一个缓冲区,写出之后可以一次性获取出所有数据

    • 此类实现了一个输出流,其中的数据被写入一个 byte 数组。缓冲区会随着数据的不断写入而自动增长。
      可使用 toByteArray() 和 toString() 获取数据。
      关闭 ByteArrayOutputStream 无效,此类中的方法在关闭此流后仍可被调用,而不会产生任何 IOException。

  • 类:
    • java.io.ByteArrayOutputStream
      • 构造方法:
        • ByteArrayOutputStream()  创建一个新的byte数组输出流
        • ByteArrayOutputStream(int size)    创建一个新的byte数组输出流,它具有指定大小的缓冲区容量(以字节为单位)
      • 方法:
        • void close()   关闭ByteArrayOutputStream 无效。在关闭此流后仍可被调用,而不会产生任何 IOException。
        • void reset()    将此byte数组输出流的count字段重置为0,从而丢弃输出流中目前已累积的所有输出
        • int size()   返回缓冲区的当前大小
        • byte[] toByteArray()   创建一个新分配的byte数组
        • String toString()   使用平台默认的字符集,通过解码字节将缓冲区内容转换为字符串
        • String toString(String charsetName)  使用指定的charsetName,通过解码字节将缓冲区内容转换为字符串
        • void write(byte[] b, int off, int len)    将指定byte数组中从偏移量off开始的 len 个字节写入此 byte 数组输出流
        • void write(int b)   将指定的字节写入此 byte数组输出流
        • void writeTo(OutputStream out)   将此 byte数组输出流的全部内容写入到指定的输出流参数中,这与使用 out.write(buf, 0, count)  调用该输出流write方法效果一样。
      • 字段摘要:
        • protected byte[]  buf   存储数据的缓冲区
        • protected int coount 缓冲区中有效字节数
  • 示例:
    • package com.heima.otherio;
      
      import java.io.ByteArrayOutputStream;
      import java.io.FileInputStream;
      import java.io.FileNotFoundException;
      import java.io.IOException;
      
      public class Demo3_ByteArrayOutputStream {
      
          /**
           * 内存输出流 ByteArrayOutputStream
           此类实现了一个输出流,其中的数据被写入一个 byte 数组。
           缓冲区会随着数据的不断写入而自动增长。
           可使用 toByteArray() 和 toString() 获取数据。 
           关闭 ByteArrayOutputStream 无效。
           此类中的方法在关闭此流后仍可被调用,而不会产生任何 IOException。
           * @throws IOException 
           */
          public static void main(String[] args) throws IOException {
      //        demo1();
              FileInputStream fis = new FileInputStream("a.txt"); 
              ByteArrayOutputStream baos = new ByteArrayOutputStream(); // 在内存中创建了可以增长的内存数组
              
              int b;
              while((b = fis.read()) != -1) {
                  baos.write(b);
              }
              
              fis.close();
              byte[] arr = baos.toByteArray();  // 将缓冲区的数据全部获取出来,并赋值给arr数组
              System.out.println(new String(arr,0,arr.length));
              
              System.out.println(baos);  // 默认使用toString方法,将缓冲区的内容自动转换为了字符串
          }
      
          public static void demo1() throws FileNotFoundException, IOException {
              /*
               * FileInputStream读取中文可能会出现乱码问题
               * 解决方法:
               * 1. 字符流
               * 2. ByteArrayInputStream
               */
              FileInputStream fis = new FileInputStream("a.txt");  
              byte[] arr = new byte[3];
              int len;
              while((len = fis.read(arr)) != -1) {
                  System.out.println(new String(arr,0,arr.length));
              }
          }
      
      }
      View Code
  • 面试题
    • 定义一个文件输入流,调用read(byte[] b)方法,将a.txt文件中的内容打印出来(byte数组大小限制为5)
    • package com.heima.otherio;
      
      import java.io.ByteArrayOutputStream;
      import java.io.FileInputStream;
      import java.io.IOException;
      
      public class Demo4_ByteArrayOutputStream {
          public static void main(String[] args) throws IOException {
              FileInputStream fis = new FileInputStream("a.txt");
              ByteArrayOutputStream baos = new ByteArrayOutputStream();
              
              byte[] arr = new byte[5];
              int len;
              while((len = fis.read(arr)) != -1) {
                  baos.write(arr,0,len);
              }
              
              fis.close();
              System.out.println(baos);
          }
      }
      View Code

3. 对象操作流

  • 什么是对象操作流

    • 该流可以将一个对象写出,或者读取一个对象到程序中,也就是执行了序列化和反序列化的操作。

  • 类:
    • java.io.ObjectOutputStream
      • 构造方法:
        • protected  ObjectOutputStream()   为完全重新实现ObjectOutputStream的子类提供一种方法,让它不必分配仅由ObjectOutputStream的实现使用的私有数据
        • ObjectOutputStream(OutputStream out)    创建写入指定的OutputStream 的ObjectOutputStream
      • 方法:
        • void close() 关闭流
        • void flush()   刷新该流的缓冲
        • protected void annotateClass(Class<?> cl)    子类可以实现此方法,从而允许在流中存储类数据
        • protected void annotateProxyClass(Class<?> c1)   子类可以实现此方法,从而在流中存储订制数据和动态代理类的描述符
        • void defaultWriteObject()    将当前类的非静态和非瞬态字段写入此流
        • protected void  drain()    排空ObjectOutputStream中的所有已缓冲数据
        • protected boolean enableReplaceObject(boolean enable)   允许流对流中的对象进行替换
        • void reset()   重置将丢弃已写入流中的所有对象的状态
        • void useProtocoVersion(int version)  指定要在写入流使用的流协议版本
        • void write(byte[] buf)   写入一个byte数组
        • void write(byte[] buf, int off, int len)   写入字节的子数组
        • void write(int val)   写入一个字节
        • void writeBoolean(boolean val)   写入一个boolean值
        • void writeByte(int val)   写入一个8位字节
        • void writeBytes(String str)   以字节序列形式写入一个String
        • void writeChar(int val)  写入一个16位的char值
        • void writeChars(String str)  以char序列形式写入一个String
        • protected void writeClassDescriptor(ObjectStreamClass desc)   将指定的类描述符写入ObjectOutputStream
        • void writeDouble(double val)  写入一个64位的double值
        • void writeFields()   将已缓冲的字段写入流中
        • void writeFloat(float val)    写入一个32位的float值
        • void writeInt(int val)   写入一个32位的int值
        • void writeLong(long val)  写入一个64位的long值
        • void writeObject(Object obj)  将指定的对象写入ObjectOutputStream
        • protected void writeObjectOverride(Object obj)   子类用于重写默认writeObject方法的方法
        • void writeShort(int val) 写入一个16位的short值
        • protected void writeStreamHeader() 提供writeStreamHeader方法,这样子类可以将其自身的头部添加或预加到流中
        • void writeUnshared(Object obj)   将“未共享”对象写入ObjectOutputStream
        • void writeUTF(String str)   以utf-8修改版格式写入此String的基本数据
    • 注意点:
      • 类通过实现 java.io.Serializable 接口以启用其序列化功能。未实现此接口的类将无法使其任何状态序列化或反序列化。
      • 只能将支持 java.io.Serializable 接口的对象写入流中。每个 serializable 对象的类都被编码,编码内容包括类名和类签名、对象的字段值和数组值,以及从初始对象中引用的其他所有对象的闭包。 

        扫描二维码关注公众号,回复: 11346117 查看本文章
    • java.io.ObjectInputStream
      • ObjectInputStream 对以前使用 ObjectOutputStream 写入的基本数据和对象进行反序列化。 

      • 只有支持 java.io.Serializable 或 java.io.Externalizable 接口的对象才能从流读取。 

      • 构造方法:
        • protected ObjectInputStream()   为完全重新实现ObjectInputStream 的子类提供一种方法,让它不必分配仅由ObjectInputStream的实现使用的私有数据
        • ObjectInputStream(InputStream in)   创建从指定InputStream读取的ObjectInputStream
      • 方法:
        • int available()  返回可以不受阻塞地读取的字节数。
        • void close()   关闭输入流。
        • void defaultReadObject()    从此流读取当前类的非静态和非瞬态字段。
        • protected boolean enableResolveObject(boolean enable)    使流允许从该流读取的对象被替代。
        • int read()   读取数据字节。
        • int read(byte[] buf, int off, int len)   读入 byte 数组。
        • boolean readBoolean()  读取一个 boolean 值。
        • byte readByte()  读取一个 8 位的字节。
        • char readChar()  读取一个 16 位的 char 值。
        • protected ObjectStreamClass readClassDescriptor()   从序列化流读取类描述符。
        • double readDouble()    读取一个 64 位的 double 值。
        • ObjectInputStream.GetField  readFields()   按名称从流中读取持久字段并使其可用。
        • float  readFloat()  读取一个 32 位的 float 值。
        • void readFully(byte[] buf)   读取字节,同时阻塞直至读取所有字节。
        • void readFully(byte[] buf, int off, int len)    读取字节,同时阻塞直至读取所有字节。
        • int readInt()     读取一个 32 位的 int 值。
        • long readLong()   读取一个 64 位的 long 值。
        • Object readObject()    从 ObjectInputStream 读取对象。
        • protected Object readObjectOverride()  此方法由 ObjectOutputStream 的受信任子类调用,这些子类使用受保护的无参数构造方法构造 ObjectOutputStream。
        • short readShort()    读取一个 16 位的 short 值。
        • protected void readStreamHeader()    提供的 readStreamHeader 方法允许子类读取并验证它们自己的流头部。
        • Object readUnshared()   从 ObjectInputStream 读取“非共享”对象。
        • int readUnsignedByte()  读取一个无符号的8位字节。
        • int readUnsignedShort()   读取一个无符号的 16 位 short 值。
        • String readUTF()  读取 UTF-8 修改版格式的 String。
        • void registerValidation(ObjectInputValidation obj, int prio)  在返回图形前注册要验证的对象
        • protected Class<?>  resolveClass(ObjectStreamClass desc)  加载指定流类描述的本地等价类。
        • protected Object resolveObject(Object obj)    在反序列化期间,此方法允许 ObjectInputStream 的受信任子类使用一个对象替代另一个。
        • protected Class<?>  resolveProxyClass(String[] interfaces)  返回一个代理类,该类实现在代理类描述符中命名的接口;子类可以实现此方法,以便从流及动态代理类的描述符中读取自定义数据,允许它们使用接口和代理类的替换加载机制。
        • int skipBytes(int len)  跳过字节。
  • 示例:
    • package com.heima.otherio;
      
      import java.io.FileNotFoundException;
      import java.io.FileOutputStream;
      import java.io.IOException;
      import java.io.ObjectOutputStream;
      
      import com.heima.bean.Person;
      
      public class Demo5_ObjectOutputStream {
      
          /**
          序列化:将对象写到文件上。
           * @throws IOException 
           * @throws FileNotFoundException 
           */
          public static void main(String[] args) throws FileNotFoundException, IOException {
              Person p1 = new Person("Ann",23);
              Person p2 = new Person("Bill",24);
              
              ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("out.txt"));  //创建对象输出流
              oos.writeObject(p1);   //无论是字节输出流,还是字符输出流都不能直接写出对象
              oos.writeObject(p2);
              /* 
               * 如果Person类没有实现Serializable接口,则会报错:
               * java.io.NotSerializableException
               */
              oos.close();
          }
      }
      序列化
    • package com.heima.otherio;
      
      import java.io.FileInputStream;
      import java.io.FileNotFoundException;
      import java.io.IOException;
      import java.io.ObjectInputStream;
      
      import com.heima.bean.Person;
      
      public class Demo6_ObjectInputStream {
      
          /**
           * 反序列化:读取对象
           * @throws IOException 
           * @throws FileNotFoundException 
           * @throws ClassNotFoundException 
           */
          public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
               ObjectInputStream ois = new ObjectInputStream(new FileInputStream("out.txt"));
               Person p1 = (Person)ois.readObject();
               Person p2 = (Person)ois.readObject();
               Person p3 = (Person) ois.readObject();
               System.out.println(p1);
               System.out.println(p2);
               ois.close();
          }
      
      }
      反序列化
  •  对象操作流优化
    • 将对象存储在集合中写出
      • package com.heima.otherio;
        
        import java.io.FileNotFoundException;
        import java.io.FileOutputStream;
        import java.io.IOException;
        import java.io.ObjectOutputStream;
        import java.util.ArrayList;
        
        import com.heima.bean.Person;
        
        public class Demo7_ObjectOutputStream {
        
            /**
             * 将对象存储在集合中写出
             * @throws IOException 
             * @throws FileNotFoundException 
             */
            public static void main(String[] args) throws FileNotFoundException, IOException {
                Person p1 = new Person("张三", 23); 
                Person p2 = new Person("李四", 24); 
                Person p3 = new Person("马哥", 18); 
                Person p4 = new Person("辉哥", 20);
        
                ArrayList<Person> list = new ArrayList<>(); 
                list.add(p1); 
                list.add(p2); 
                list.add(p3); 
                list.add(p4);
        
                ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("out.txt")); 
                oos.writeObject(list); //写出集合对象
        
                oos.close();
            }
        
        }
        View Code
    • 读取到的是一个集合对象
      • package com.heima.otherio;
        
        import java.io.FileInputStream;
        import java.io.FileNotFoundException;
        import java.io.IOException;
        import java.io.ObjectInputStream;
        import java.util.ArrayList;
        
        import com.heima.bean.Person;
        
        public class Demo8_ObjectInputStream {
        
            /**
             * 读取到的是一个集合对象
             * @throws IOException 
             * @throws FileNotFoundException 
             * @throws ClassNotFoundException 
             */
            public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
                ObjectInputStream ois = new ObjectInputStream(new FileInputStream("out.txt")); 
                
                //想去掉黄色可以加注解 @SuppressWarnings("unchecked") 
                ArrayList<Person> list = (ArrayList<Person>)ois.readObject(); //泛型在运行期会被擦除,索引运行期相当于没有泛型
                
                for (Person person : list) { 
                    System.out.println(person); 
                    }
        
                ois.close();
            }
        
        }
        View Code
    • 加上id号
      • package com.heima.bean;
        
        import java.io.Serializable;
        
        public class Person implements Serializable{
            /**
             * 
             */
            private static final long serialVersionUID = 1L;  // 如果不添加id号,就会随机生成id号,不方便报错时查看版本号
            private String name;
            private int age;
            
            public Person() {
                super();
            }
        
            public Person(String name, int age) {
                super();
                this.name = name;
                this.age = age;
            }
        
            public String getName() {
                return name;
            }
        
            public void setName(String name) {
                this.name = name;
            }
        
            public int getAge() {
                return age;
            }
        
            public void setAge(int age) {
                this.age = age;
            }
            
            
        }
        View Code
  • 注意:
    • 要写出的对象必须实现Serializable接口才能被序列化
    • 不用必须加id号

4. 打印流

  • 什么是打印流

    • 向文本输出流打印对象的格式化表示形式。
    • 此类实现在 PrintStream 中的所有 print 方法。它不包含用于写入原始字节的方法,对于这些字节,程序应该使用未编码的字节流进行写入。 
    • 该流可以很方便的将对象的toString()结果输出,并且自动加上换行,而且可以使用自动刷出的模式
    • System.out就是一个PrintStream,其默认向控制台输出信息
  • 类:
    • java.io.PrintStream   打印字节流,只操作数据目的的
    • java.io.PrintWriter   打印字符流,只操作数据目的的
      • 构造方法:
        • PrintWriter(File file)   使用指定文件创建不具有自动行刷新的新 PrintWriter
        • PrintWriter(File file, String csn)  创建具有指定文件和字符集且不带自动刷行新的新 PrintWriter。
        • PrintWriter(OutputStream out)  根据现有的 OutputStream 创建不带自动行刷新的新 PrintWriter。
        • PrintWriter(OutputStream out, boolean autoFlush )  通过现有的 OutputStream 创建新的 PrintWriter。
        • PrintWriter(String fileName)       创建具有指定文件名称且不带自动行刷新的新 PrintWriter。
        • PrintWriter(String fileName, String csn)   创建具有指定文件名称和字符集且不带自动行刷新的新 PrintWriter。
        • PrintWriter(Writer out)     创建不带自动行刷新的新 PrintWriter。
        • PrintWriter(Writer out, boolean autoFlush)      创建新 PrintWriter。
      • 方法:
        • PrintWriter append(char c)   将指定字符添加到此 writer。
        • PrintWriter append(CharSequence csq)   将指定的字符序列添加到此 writer。
        • PrintWriter append(CharSequence csq, int start, int end)   将指定字符序列的子序列添加到此 writer。
        • boolean checkError()   如果流没有关闭,则刷新流且检查其错误状态。
        • protected void clearError()   清除此流的错误状态。
        • void close()    关闭该流并释放与之关联的所有系统资源。
        • void flush()   刷新该流的缓冲。
        • PrintWriter format(Local 1, String format, Object... args)  使用指定格式字符串和参数将一个格式化字符串写入此 writer 中。
        • PrintWriter format(String format, Object... args)      使用指定格式字符串和参数将一个格式化字符串写入此 writer 中。
        • void print(boolean b)   打印 boolean 值。
        • void print(char c)    打印字符。
        • void print(char[] s)    打印字符数组。
        • void print(double d)     打印 double 精度浮点数。
        • void print(float f)    打印一个浮点数。
        • void print(int i)    打印整数。
        • void print(long l)   打印 long 整数。
        • void print(Object obj)  打印对象。
        • void print(String s)    打印字符串。
        • PrintWriter printf(Local l, String format, Object... args)    使用指定格式字符串和参数将格式化的字符串写入此 writer 的便捷方法。
        • PrintWriter printf(String format, Object... args)    使用指定格式字符串和参数将格式化的字符串写入此 writer 的便捷方法。
        • void println()       通过写入行分隔符字符串终止当前行。
        • void println(boolean x)        打印 boolean 值,然后终止该行。
        • void println(char x)       打印字符,然后终止该行。
        • void println(char[] s)        打印字符数组,然后终止该行。
        • void println(double d)      打印双精度浮点数,然后终止该行。
        • void println(float f)     打印浮点数,然后终止该行。
        • void println(int i)         打印整数,然后终止该行。
        • void println(long l)       打印 long 整数,然后终止该行。
        • void println(Object obj)        打印 Object,然后终止该行。
        • void println(String s)       打印 String,然后终止该行。
        • protected void setError()       指示已发生错误。
        • void write(char[] buf)     写入字符数组。
        • void write(char[] buf, int off, int len)           写入字符数组的某一部分。
        • void write(int c)    写入单个字符。
        • void write(String s)      写入字符串。
        • void write(String s, int off, int len)    写入字符串的某一部分。
    • 示例:
      • package com.heima.otherio;
        
        import java.io.FileOutputStream;
        import java.io.IOException;
        import java.io.PrintStream;
        import java.io.PrintWriter;
        
        import com.heima.bean.Person;
        
        public class Demo9_PrintStream {
            public static void main(String[] args) throws IOException {
        //        demo1();
                
                PrintWriter pw = new PrintWriter(new FileOutputStream("out.txt"), true);
                pw.println(97);  // 写入97 // 只针对println方法,自动刷出,写到out.txt文件中
                pw.write(97);    // 写入a
                pw.print(97);
                
                //pw.close();  
                
            }
        
            public static void demo1() {
                System.out.println(97);
                
                PrintStream ps = System.out; // 获取标注输出流
                
                ps.println(97); 
                //其实底层用的是Integer.toString(x),将x转换为数字字符串打印
        
                ps.println("xxx"); 
                
                ps.println(new Person("张三", 23));  //com.heima.bean.Person@186b0ee
            
                Person p = null; 
                ps.println(p); //如果是null,就返回null,如果不是null,就调用对象的toString()
            }
        }
        View Code

          

5. 标准输入输出流

  • 什么是标准输入输出流

    • System.in 是 InputStream,标准输入流,默认可以从键盘输入读取字节数据

    • System.out 是 PrintStream,标准输出流,默认可以向Console中输出字符和字节数据

  • 修改标准输入输出流

    • 修改输入流:System.setIn(InputStream)

    • 修改输出流:System.setOut(PrintStream)

    • package com.heima.otherio;
      
      import java.io.FileInputStream;
      import java.io.FileNotFoundException;
      import java.io.IOException;
      import java.io.InputStream;
      import java.io.PrintStream;
      
      public class Demo10_SystemInOut {
      
          /**
           * @param args
           * @throws IOException 
           */
          public static void main(String[] args) throws IOException {
              System.setIn(new FileInputStream("a.txt")); 
              System.setOut(new PrintStream("b.txt")); 
              
              InputStream in = System.in;   
              PrintStream ps = System.out;  
              
              int b;
              while((b = in.read()) != -1) {  
                  ps.write(b);    
              }
      
              in.close();
              ps.close();
          }
      
      }
      View Code
  • 修改标准输入输出流拷贝图片
    • package com.heima.otherio;
      
      import java.io.FileInputStream;
      import java.io.FileNotFoundException;
      import java.io.IOException;
      import java.io.InputStream;
      import java.io.PrintStream;
      
      public class Demo11_SystemInOut {
      
          /**
           * @param args
           * @throws IOException 
           */
          public static void main(String[] args) throws IOException {
              System.setIn(new FileInputStream("E:\\1.jpg")); //改变标准输入流
              System.setOut(new PrintStream("E:\\copy1.jpg")); //改变标准输出流
      
              InputStream is = System.in; //获取标准输入流
              PrintStream ps = System.out; //获取标准输出流
      
              int len; 
              byte[] arr = new byte[1024 * 8];
      
              while((len = is.read(arr)) != -1) { 
                  ps.write(arr, 0, len); 
              }
      
              is.close(); 
              ps.close();
          }
      
      }
      View Code
  • 注意:只要没有和文件绑定,不用close()

 

6. 两种方式实现键盘录入

  • BufferedReader的readLine方法:

    • BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

    • package com.heima.otherio;
      
      import java.io.BufferedReader;
      import java.io.IOException;
      import java.io.InputStreamReader;
      
      public class Demo12_BufferedReader {
      
          /**
           BufferedReader的readLine方法,实现键盘录入
           * @throws IOException 
           */
          public static void main(String[] args) throws IOException {
              BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
              String line = br.readLine();
              System.out.println(line);
              br.close();
          }
      }
      View Code 
  • Scanner 

    • Scanner sc = new Scanner(System.in);

 

7. 随机访问流

  • 随机访问流概述

    • RandomAccessFile概述

    • RandomAccessFile类不属于流,是Object类的子类。但它融合了InputStream和OutputStream的功能。

    • 支持对随机访问文件的读取和写入。

  • 构造方法:

    • RandomAccessFile(File file, String mode)   创建从中读取和向其中写入(可选)的随机访问文件流,该文件由 File 参数指定。
    • RandomAccessFile(String name, String mode)   创建从中读取和向其中写入(可选)的随机访问文件流,该文件具有指定名称。
  • 模式mode
    • r   只读
    • rw  读写
    • rws   读写,还要求对文件的内容或元数据的每个更新都同步写入到底层存储设备
    • rwd   读写,还要求对文件的内容的每个更新都同步写入到底层存储设备
  • 方法:
    • void close()    关闭此随机访问文件流并释放与该流关联的所有系统资源。
    • FileChannel getChannel()    返回与此文件关联的唯一 FileChannel 对象。
    • FileDescriptor getFD()     返回与此流关联的不透明文件描述符对象。
    • long getFilePointer()      返回此文件中的当前偏移量。
    • long length()         返回此文件的长度。
    • int read()     从此文件中读取一个数据字节。
    • int read(byte[] b)   将最多 b.length 个数据字节从此文件读入 byte 数组。
    • int read(byte[] b, int off, int len)    将最多 len 个数据字节从此文件读入 byte 数组。
    • boolean readBoolean()   从此文件读取一个 boolean
    • byte readByte()   从此文件读取一个有符号的八位值。
    • char readChar()   从此文件读取一个字符。
    • double readDouble()    从此文件读取一个 double
    • float readFloat()    从此文件读取一个 float
    • void readFully()      将 b.length 个字节从此文件读入 byte 数组,并从当前文件指针开始。
    • void readFully(byte[] b, int off, int len)       将正好 len 个字节从此文件读入 byte 数组,并从当前文件指针开始。
    • int readInt()         从此文件读取一个有符号的 32 位整数。
    • String readLine()       从此文件读取文本的下一行。
    • long readLong()         从此文件读取一个有符号的 64 位整数。
    • short readShort()        从此文件读取一个有符号的 16 位数。
    • int readUnsignedByte()          从此文件读取一个无符号的八位数。
    • int readUnsignedShort()   从此文件读取一个无符号的 16 位数。
    • String readUTF()      从此文件读取一个字符串。
    • void seek(long pos)    设置到此文件开头测量到的文件指针偏移量,在该位置发生下一个读取或写入操作。
    • void setLength(long newLength)   设置此文件的长度。
    • int skipBytes(int n)    尝试跳过输入的 n 个字节以丢弃跳过的字节。
    • void write(byte[] b)   将 b.length 个字节从指定 byte 数组写入到此文件,并从当前文件指针开始。
    • void write(byte[] b, int off, int len)    将 len 个字节从指定 byte 数组写入到此文件,并从偏移量 off 处开始。
    • void write(int b)    向此文件写入指定的字节。
    • void writeBoolean(boolean v)   按单字节值将 boolean 写入该文件。
    • void writeByte(int v)   按单字节值将 byte 写入该文件。
    • void writeBytes(String s)    按字节序列将该字符串写入该文件。
    • void writeChar(int v)     按双字节值将 char 写入该文件,先写高字节。
    • void writeChars(String s)    按字符序列将一个字符串写入该文件。
    • void writeDouble(double v)    使用 Double 类中的 doubleToLongBits 方法将双精度参数转换为一个 long,然后按八字节数量将该 long 值写入该文件,先定高字节。
    • void writeFloat(float v)   使用 Float 类中的 floatToIntBits 方法将浮点参数转换为一个 int,然后按四字节数量将该 int 值写入该文件,先写高字节。
    • void writeInt(int v)     按四个字节将 int 写入该文件,先写高字节。
    • void writeLong(long v)    按八个字节将 long 写入该文件,先写高字节。
    • void writeShort(int v)    按两个字节将 short 写入该文件,先写高字节。
    • void writeUTF(String str)    使用 modified UTF-8 编码以与机器无关的方式将一个字符串写入该文件。
  • 示例

    • package com.heima.otherio;
      
      import java.io.FileNotFoundException;
      import java.io.IOException;
      import java.io.RandomAccessFile;
      
      public class Demo13_RandomAccessFile {
      
          /**
           * RandomAccessFile类不属于流,是Object类的子类。
           * 但它融合了InputStream和OutputStream的功能。
           * 支持对随机访问文件的读取和写入。
           * @throws IOException 
           */
          public static void main(String[] args) throws IOException {
              RandomAccessFile raf = new RandomAccessFile("a.txt", "rw");
              raf.write(97);
              raf.seek(10);  // 设置到此文件开头测量到的文件指针偏移量,在该位置发生下一个读取或写入操作。
              raf.writeChars("this is a local at 10");
              raf.close();
          }
      
      }
      View Code
  • seek方法的好处:
    • 可以实现多线程下载。如设置线程1从指针10万处开始读取,线程2从指针20万处开始读取,以此类推。

  

8. 数据输入输出流

  • 什么是数据输入输出流

    • DataInputStream, DataOutputStream可以按照基本数据类型大小读写数据

    • 例如:按Long大小写出一个数字,写出时该数据占8字节,读取的时候也可以按照Long类型读取,一次读取8个字节。

  • 使用方式

    • package com.heima.otherio;
      
      import java.io.DataInputStream;
      import java.io.DataOutputStream;
      import java.io.FileInputStream;
      import java.io.FileNotFoundException;
      import java.io.FileOutputStream;
      import java.io.IOException;
      
      public class Demo14_DataInputOutputStream {
      
          /**
           * DataInputStream, DataOutputStream可以按照基本数据类型大小读写数据
           * @throws IOException 
           */
          public static void main(String[] args) throws IOException {
      
              DataOutputStream dos = new DataOutputStream(new FileOutputStream("b.txt")); 
              dos.writeInt(997); 
              dos.writeInt(998); 
              dos.writeInt(999);
      
              dos.close();
      
              DataInputStream dis = new DataInputStream(new FileInputStream("b.txt")); 
              int x = dis.readInt(); 
              int y = dis.readInt(); 
              int z = dis.readInt(); 
              System.out.println(x); // 997
              System.out.println(y); // 998
              System.out.println(z); // 999
              dis.close(); 
          }
      
      }
      View Code

9. Properties

  • Properties的概述

    • Properties 类表示了一个持久的属性集。

    • Properties 可保存在流中或从流中加载。

    • 属性列表中每个键及其对应值都是一个字符串。

    • Proterties是主要用于读取配置文件,K:V键值对的。K:V键值对在配置文件中的存在形式为字符串。由于Properties通过一些方法固定用字符串类型的,所以不用泛型(泛型可以指定任意数据类型)。
  • 类:
    •  java.lang.Object 
      • java.util.Dictionary<K,V>
        • java.util.Hashtable<Object, Object>
          • java.util.Properties  是Hashtable的子类,可以使用Hashtable的put方法
    • 构造方法:
      • Properties()   创建一个无默认值的空属性列表
      • Properties(Properties defaults)   创建一个带有指定默认值的空属性列表
    • 方法:
      • String getProperty(String key)  用指定的键在此属性列表中搜索属性
      • String getProperty(String key, String defaultValue)   用指定的键在属性列表中搜索属性
      • void list(PrintStream out)  将属性列表输出到指定的输出流
      • void list(PrintWriter out)   将属性列表输出到指定的输出流
      • void load(InputStream inStream)    从输入流中读取属性列表(键和元素对)
      • void load(Reader reader)   按简单的面向行的格式从输入字符流中读取属性列表(键和元素对)
      • void loadFromXML(InputStream in)     将指定输入流中由XML文档所表示的所有属性加载到此属性表中
      • Enumertation<?>  propertyNames()   返回属性列表中所有键的枚举,如果在主属性列表中未找到同名的键,则包括默认属性列表中不同的键
      • Object setProperty(String key, String value)   调用Hashtable的方法put
      • void store(OutputStream out, String comments)   以适合使用load(InputStream)方法加载到Properties表中的格式,将此Properties表中的属性列表(键和元素对)写入输出流
      • void store(Writer writer, String comments)   以适合使用load(Reader)方法的格式,将此Properties表中的属性列表(键和元素对)写入输出字符
      • void storeToXML(OutputStream os, String comment)    发出一个表示此表中包含的所有属性的XML文档
      • void storeToXML(OutputStream os, String comment, String encoding)   使用指定的编码发出一个表示此表中包含的所有属性的XML文档
      • Set<String>  stringPropertyNames()   返回此属性列表中的键集,其中该键及其对应值是字符串,如果在主属性列表中未找到同名的键,则还包括默认列表中不同的键
      • 从类java.util.Hashtable继承的方法:
        • clear, clone, contains, constainsKey, containsValue, elements, entrySet, equals, get, hashCode, isEmpty, keys, keySet, put, putAll, rehash, remove, size, toString, values
      • 从类java.lang.Object继承的方法:
        • finalize, getClass, notify, notifyAll, wait, wait, wait
  • 案例演示

    • Properties作为Map集合的使用

    • package com.heima.otherio;
      
      import java.util.Properties;
      
      public class Demo15_Properties {
      
          /**
           * @param args
           */
          public static void main(String[] args) {
              Properties prop = new Properties();
              prop.put("abc", 123);
              System.out.println(prop);  // 输出{abc=123}
          }
      
      }
      View Code
  • Properties的特殊功能

    • public Object setProperty(String key,String value)

    • public String getProperty(String key)

    • public Enumeration<String> propertyNames()

  • 案例演示

    • Properties的特殊功能

    • package com.heima.otherio;
      
      import java.util.Enumeration;
      import java.util.Properties;
      
      public class Demo15_Properties {
      
          /**
           * @param args
           * Properties是Hashtable的子类
           */
          public static void main(String[] args) {
      //        demo1();
              Properties prop = new Properties();
              prop.setProperty("name", "Ann");
              prop.setProperty("age", "23");
              prop.setProperty("gender", "female");
              System.out.println(prop);
              
              Enumeration<String> en = (Enumeration<String>) prop.propertyNames();
              while(en.hasMoreElements()) {
                  String key = en.nextElement(); // 获取Properties中的每一个键
                  String value = prop.getProperty(key); // 根据键获取值
                  System.out.println(key + "=" + value);
              }
          }
      
          public static void demo1() {
              Properties prop = new Properties();
              prop.put("abc", 123);
              System.out.println(prop);  // 输出{abc=123}
          }
      
      }
      View Code
  • Properties的load()和store()功能

  • 案例演示

    • Properties的load()和store()功能

    • package com.heima.otherio;
      
      import java.io.FileInputStream;
      import java.io.FileNotFoundException;
      import java.io.FileOutputStream;
      import java.io.IOException;
      import java.util.Enumeration;
      import java.util.Properties;
      
      public class Demo15_Properties {
      
          /**
           * @param args
           * Properties是Hashtable的子类
           * @throws IOException 
           * @throws FileNotFoundException 
           */
          public static void main(String[] args) throws FileNotFoundException, IOException {
      //        demo1();
      //        demo2();
              Properties prop = new Properties();
              prop.load(new FileInputStream("config.properties"));  //将文件上的键值对读取到集合中
              System.out.println(prop);  // 打印文件上的键值对信息
              prop.setProperty("tel", "1234567890");   // 修改属性tel的值
              System.out.println(prop);   // 打印修改后的键值对信息
              
              // 将修改后的键值对信息保存在文件
              // 第二个参数是对列表参数的描述,可以给值,也可以给null
              prop.store(new FileOutputStream("config.properties"), "修改过tel字段"); 
              
          }
      
          public static void demo2() {
              Properties prop = new Properties();
              prop.setProperty("name", "Ann");
              prop.setProperty("age", "23");
              prop.setProperty("gender", "female");
              System.out.println(prop);
              
              Enumeration<String> en = (Enumeration<String>) prop.propertyNames();
              while(en.hasMoreElements()) {
                  String key = en.nextElement(); // 获取Properties中的每一个键
                  String value = prop.getProperty(key); // 根据键获取值
                  System.out.println(key + "=" + value);
              }
          }
      
          public static void demo1() {
              Properties prop = new Properties();
              prop.put("abc", 123);
              System.out.println(prop);  // 输出{abc=123}
          }
      
      }
      View Code

 

猜你喜欢

转载自www.cnblogs.com/zoe233/p/13163246.html