java学习笔记(IO流):

1.IO流


1).按流的方向分类:
        

 1)输入流
 2)输出流

2)按类型分类:       

              字节流:先有
                              按方向      抽象类
                              字节输入 :InputStream
                              字节输出 :OutputStream
              字符流:后有
                              字符输入 :Reader
                              字符输出 :Writer

3)特有功能:

  1)创建文件输出流
      public FileOutputStream(String name):创建文件
      public FileOutputStream(String pathname,boolean append):如果第二个参数为true,则自动后面追加 
        public FileOutputStream(String name) throws FileNotFoundException
        //底层创建:创建流对象fos内存执行输出的文件aaa.txt
        FileOutputStream fos = new FileOutputStream("xxx.txt") ;
  2)写数据:
       //abstract void write(int b ):写入单个字节
       fos.write(97) ;//97---a 写入的内容是a

       // void write(byte[] b):写入一个字节数组
       fos.write("hello,IO".getBytes()); 写入的字节数组是hello,IO
   3)释放资源
        //底层:将fos流对象不再执行那个文件了
        fos.close() ;

4)IO流的输入/输出方式:

    1.字节输出流:

      FileOutputStream的构造方法
      public FileOutputStream(String pathname,boolean append):如果第二个参数为true,则自动后面追加
public class FileOutputStreamDemo {
    public static void main(String[] args) throws IOException {//自己使用可以去抛异常

        //创建文件字节输出流对象
       // FileOutputStream fos = new FileOutputStream("fos.txt") ;
        //public FileOutputStream(String pathname,boolean append)
        FileOutputStream fos = new FileOutputStream("fos.txt",true) ;

        //写数据
        //写一个字节数组
        for(int x = 0 ; x < 10 ; x++){
            fos.write(("hello"+x).getBytes()) ;
            //换行符号 "\r\n"
            fos.write("\r\n".getBytes());

        }

        //释放资源
        fos.close() ;
    }
}
开发中,需要处理异常:
       try{
 *
 *               可能出现问题的代码;---一旦这有问题:Jvm 就会创建异常对象
 *
 *           }   catch   (异常类名 e)  { //如果和当前异常类名匹配了
 *                  //处理异常
 *                  //System.out.println("数组角标越界了") ;
 *                  e.printStackTrace() ;//可以看到你自己写的代码哪块出错了以及底层原码
 *           }finally{
 *
 *               //释放资源
 *           }

2.字节输入流:

1) 构造方法:FileInputStream
     public FileInputStream(String name) throws FileNotFoundException:创建文件字节输入流对象
 成员方法:
     read这些方法:都是阻塞式方法:只要文件没有读完,一直等待要读取!
     1-1)abstract int read():一次读取一个字节,返回的读取的字节数
public class FileInputStreamDemo3 {
    public static void main(String[] args) throws IOException {

        //创建文件字节输入流对象
        //FileInputStream fis = new FileInputStream("fis.txt") ;//当前项目下的fis.txt
        //读取的是当前项目下的java文件FileOutputStreamDemo2.java
        FileInputStream fis = new FileInputStream("FileOutputStreamDemo2.java") ;

        //读:abstract int read():一次读取一个字节
        //第一次读
        /*int by = fis.read();
        //System.out.println(by) ;//97---
        //将这个字节数----变成字符
        System.out.println((char)by);

        System.out.println("-------------------") ;
        //第二次读
        by = fis.read() ;
        System.out.println((char)by);
        System.out.println("-------------------") ;
        //第三次读
        by = fis.read() ;
        System.out.println((char)by);

        System.out.println("-------------------") ;
        //第四次读
        by = fis.read() ;
        System.out.println((char)by);
        System.out.println("-------------------") ;
        //第五次读
        by = fis.read() ;
        System.out.println((char)by);*/
        //第六次读
      /*  by = fis.read() ;
        System.out.println(by);
        System.out.println((char)by);*/

      //使用循环思想改进
       /* int by = fis.read() ;
        while(by!=-1){
            System.out.print((char)by);
            by = fis.read() ;
        }*/
       //在优化:将赋值,判断一块使用
        //刚开始:还没还是读 字节数0
        int by = 0 ;
        while((by=fis.read())!=-1){
            System.out.print((char)by);
        }
        //3)释放资源
        fis.close() ;
    }
}
1-2)int read(byte[] b) :一次读取一个字节数组
 int read(byte[] b)  :一次读取一个字节数组
 */
public class FileInputStreamDemo4 {
    public static void main(String[] args) throws IOException {

        //读取是当前项目下的fis2.txt文件
        //创建文件字节输入流对象
        FileInputStream fis = new FileInputStream("fis2.txt") ;
      

        //优化上面代码:一般一次读取一个字节数组:数组的长度:1024或者是1024的整数倍
        //最终版代码
        byte[] bytes = new byte[1024] ;//提供字节缓冲区
        //实际的长度:根据内容判断 :获取实际字节数
        int len = 0 ;
        //判断和获取一块使用
        while((len=fis.read(bytes))!=-1){
            System.out.println(new String(bytes,0,len)); //每次从0开始获取实际字节数---转换成字符串
        }
        //释放资源
        fis.close() ;
    }
}    //读取fis2.txt  文件
adc
adc
adc  

3.字节缓冲流(别名 "字节高效流"):

 1)字节缓冲输入流:BufferedInputStream 
    构造方法 BufferedInputStream(InputStream in) 
    成员方法:使用InputStream的read的功能: 一次读取一个字节/一次读取一个字节数组
public class BufferedOutputSteamDemo {
    public static void main(String[] args) throws IOException {
        //write();
        //读
        read() ;
    }

    //读取 当前项目下的bos.txt的内容
    private static void read() throws IOException {
        //创建字节缓冲输入流对象
        //BufferedInputStream(InputStream in)
        BufferedInputStream bis = new BufferedInputStream(形式参数
是一个抽象类,需要子类对象
                new FileInputStream("bos.txt")) ;

        //一次读取一个字节
       /* int by = 0 ;
        while((by=bis.read())!=-1){
            //展示出来
            System.out.print((char)by);
        }*/
       //一次读取一个字节数组
        byte[] bytes = new byte[1024] ;
        int len = 0 ;
        while((len=bis.read(bytes))!=-1){
            //展示
            System.out.println(new String(bytes,0,len));
        }
        //释放资源
        bis.close() ;
    }
}
2)字节缓冲输出流(别名 "字节高效流"):BufferedOutputStream
      这个流仅仅是在内部提供了一个缓冲区(字节数组),针对文件的输出并且同时写入数据使用的还是底层流OutputStream 
      构造方法: public BufferedOutputStream(OutputStream out):构造一个默认的缓冲区大小,通过底层流进行输出(写入数据)
public class BufferedOutputSteamDemo {
    public static void main(String[] args) throws IOException {
       write();     
    }
    private static void write() throws IOException {
        //创建字节缓冲输出流对象
        //public BufferedOutputStream(OutputStream out):
形式参数是一个抽象类,需要子类对象

        BufferedOutputStream bos = 
new BufferedOutputStream(new FileOutputStream("bos.txt")) ;

        //写数据:使用的底层流的OutputStream的方法
        bos.write("hello,BufferedStream".getBytes());

        //释放资源
        bos.close();
    }
}

4.合并流:

1)SequenceInpuStream----是InputStream的子类:它这个类只能操作源文件
 构造函数:
   public SequenceInputStream(InputStream s1,InputStream s2):将两个字节输入流对象指向的文件进行合并 
public class SequenceInpuStreamTest {
    public static void main(String[] args) throws IOException {
        method1();       
    }
    private static void method1() throws IOException {
        //创建两个字节文件输入流对象:指向两个文件
        InputStream in = new FileInputStream("FileOutputStreamDemo.java") ;
        InputStream in2 = new FileInputStream("FileOutputStreamDemo2.java") ;
        //封装到合并流中
        SequenceInputStream sis = new SequenceInputStream(in,in2) ;

        //目的地文件D:\EE_2110\day26\code\Copy.java
        //BufferedOutputStream流
        BufferedOutputStream bos = new BufferedOutputStream(
                new FileOutputStream("D:\\EE_2110\\day26\\code\\Copy.java")) ;

        //一次读取一个字节数组
        byte[] bytes = new byte[1024] ;
        int len = 0 ;
        while((len=sis.read(bytes))!=-1){
            bos.write(bytes,0,len) ;
            bos.flush() ;
        }
        //释放
        bos.close() ;
        sis.close();
    }
}
    public SequenceInputStream(Enumeration<? extends InputStream> e)当两个以上的文件进行复制到一个文件中
public class SequenceInpuStreamTest {
    public static void main(String[] args) throws IOException {
        //method1();
        method2() ;//多个文件进行复制(两个以上的文件)
    }

    private static void method2() throws IOException {
        //当前项目下的FileOutputStreamDemo.java/FileOutputStreamDemo2.java/InputAndOutputStreamCopy.java
        //复制到D:\EE_2110\day26\code\\MyCopy.java

        // public SequenceInputStream(Enumeration<? extends InputStream> e)
        //        //创建Vector集合<InputStream>
        Vector<InputStream> v  = new Vector<>() ;
        v.add(new FileInputStream("FileOutputStreamDemo.java")) ;
        v.add(new FileInputStream("FileOutputStreamDemo2.java")) ;
        v.add(new FileInputStream("InputAndOutputStreamCopy.java")) ;

        //类似于迭代器:获取Enumeration枚举组件接口对象
        Enumeration<InputStream> enumeration = v.elements();
        //直接创建合并流对象
        SequenceInputStream sis = new SequenceInputStream(enumeration) ;
        //封装目的地文件

        BufferedOutputStream bos = new BufferedOutputStream(
                new FileOutputStream("D:\\EE_2110\\day26\\code\\MyCopy.java")) ;

        //一次读取一个字节数组
        byte[] bytes = new byte[1024] ;
        int len = 0 ;
        while((len=sis.read(bytes))!=-1){
            bos.write(bytes,0,len) ;
            bos.flush() ;
        }
        //释放
        bos.close() ;
        sis.close();
    }

5.字符流:

1)Reader和Writer的子类进行操作文件复制:

 * 如果使用Reader和Writer的子类进行操作:字符转换流(InputStreamReader/OutputStreamWriter)
 * 复制文件,太麻烦了!
 *
 * 他们提供了具体的便捷类,可以直接操作文件  FileReader/FileWriter
 * FileReader(String pathname):使用平台默认字符集:进行解码
 * FileWriter(String pathname)使用平台默认字符集:进行编码
 *      字符流针对文本文件操作:
 *    当前项目 FileOutputStreamDemo.java------>拷贝到当前项目下;My.java
public class CopyFileTest {

    public static void main(String[] args) {

        //捕获异常
        //创建字符输入流对象:操作源文件
        FileReader fr = null ;
        FileWriter fw = null ;
        try {
           fr = new FileReader("FileOutputStreamDemo.java") ;
           fw = new FileWriter("My.java") ;

            //读写操作
            //一次读取一个字符数组
            char[] chs = new char[1024] ;
            int len = 0 ;//实际字符数
            while((len=fr.read(chs))!=-1){
                //写
                fw.write(chs,0,len) ;
                fw.flush() ;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(fw!=null){
                try {
                    fw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(fr!=null){
                try {
                    fr.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

2)字符输入流:Reader:抽象类

子类:InputStreamReader:字符缓冲输入流:通向字节输入流的桥梁
 * 构造方法
 * InputStreamReader(InputStream in) :使用平台默认的字符集进行解码,里面包装的字节流
 * InputStreamReader(InputStream in,String charsetName):使用指定的字符集进行解码
 *
 * 读取:
 *      读一个字符read()
 *      读一个字符数组read(char[] chs)
 */
public class InputStreamReaderDemo {
    public static void main(String[] args) throws IOException {

        //需要读取oos.txt
        //创建字符缓冲输入流对象
        //InputStreamReader(InputStream in)
        InputStreamReader isr = new InputStreamReader(
                new FileInputStream("oos.txt"),"GBK") ;


        //一次读取一个字符
      /*  int ch = 0 ;//字符数 ()
        while((ch=isr.read())!=-1){
            System.out.print((char)ch);
        }*/
      //一次读取一个字符数组
        char[] chs = new char[1024] ;
        int len = 0 ;
        while((len=isr.read(chs))!=-1){
            System.out.print((new String(chs,0,len))) ;
        }
        //释放资源
        isr.close() ;
    }
}

3)字符流出:

* 字符流出现的原因:在字节流基础上,它会提供字符集,解决乱码问题!
 * 如果使用记事本打开一个文件,(文本文件)---优先采用的就是字符流!
 * 图片/音频/视频------>只能使用字节流
 *
 * Writer:抽象类----->子类 :字符转换输出流OutputStreamWriter:里面包装的是字节流
 * 构造方法
 * OutputStreamWriter(OutputStream out) :使用平台默认的编码字符集进行编码--->写入数据
 * OutputStreamWriter(OutputStream out,String charsetName )使用指定的编码字符集进行编码--->写入数据
 * 写的功能:
 *          write(int ch):写一个字符
 *          write(char[] chs):写字符数组
 *          write(char[] chs,int index,int len):写字符数组的一部分
 *          writer(String str):写字符串
 *          writer(String str,int index,int len):写字符串的一部分
 *
 */
public class OutputStreamWriterDemo {
    public static void main(String[] args) throws IOException {

        //创建字符输出流对象
        //OutputStreamWriter(OutputStream out)
       // Writer out = new OutputStreamWriter(new FileOutputStream("out.txt")) ;
        /*OutputStreamWriter oos = new OutputStreamWriter(
                    new FileOutputStream("oos.txt")) ;*///默认平台 utf-8 编码
        OutputStreamWriter oos = new OutputStreamWriter(
                new FileOutputStream("oos.txt"),"GBK") ;// 指定GBK 编码

        oos.write("hello,字符流");
        //释放资源
        oos.close() ;
    }
}

4)字符缓冲输入流(字符流的高效流):

    BufferedReader:字符缓冲输入流 提供默认的缓冲区大小 缓冲区足够大 BufferedReader(Reader in)

   特有功能: String readLine() 读取一行内容

public class BufferedReaderDemo {
    public static void main(String[] args) throws IOException {

        //创建字符缓冲输入流对象:读取bw.txt
        BufferedReader br = new BufferedReader(new FileReader("bw.txt")) ;

        //bw.txt---拷贝D盘:字符缓冲输出流 my.txt
        BufferedWriter bw = new BufferedWriter(new FileWriter("D:\\my.txt")) ;


        //String readLine() 读取一行内容

     /*   //第一次读
        String line = br.readLine() ; //readLine()阻塞式方法
        System.out.println(line) ;

        //第二次读
        line =  br.readLine() ;
        System.out.println(line);

        //第三次读
        line = br.readLine() ;
        System.out.println(line);

        //第四次读
        line = br.readLine() ;
        System.out.println(line);

        //第五次读
        line = br.readLine() ;
        System.out.println(line);*/
        //循环改进
        String line = null ;
        while((line=br.readLine())!=null){
            //System.out.println(line);
            bw.write(line);
            bw.newLine();
            bw.flush();
        }

        //释放资源
        bw.close();
        br.close();
    }
}
5)字符缓冲输出流 (字符流的高效流):
仅仅提供缓冲区
* BufferedWriter(Writer out)  :提供默认缓冲区大小,默认值足够大:8192个长度(底层是一种字符数组)
* 特有功能:
*      public void newLine() throws IOException :写入行的分隔符号
public class BufferedWriterDemo {
    public static void main(String[] args) throws IOException {

        //创建字符缓冲输出流对象
        BufferedWriter bw = new BufferedWriter(new FileWriter("bw.txt")) ;

        //写数据
        bw.write("hello");
        //调用 public void newLine() throws IOException :写入行的分隔符号
        bw.newLine() ;
        bw.write("world");
        bw.newLine() ;
        bw.write("java");
        bw.newLine() ;
        //字符流的使用:在关闭前最好刷新流
        //public void flush()
        bw.flush() ;

        //关闭
        bw.close();
    }
}

6.序列化:

1)概念:

ObjectOutputStream
     就是在将Java对象(实体类:User/Product/Order...)
                 变成一种流数据,他们里面的数据存储流中,
                       就可以在网络(服务器集群中:共享)中传输!
 1)序列化:OutputStream
     构造方法:
          public ObjectOutputStream(OutputStream out)
    成员方法:
          public final void writeObject(Object obj) throws IOException:写入一个实体对象
2)反序列化ObjectInputStream
      就是将流数据(存储的一些相关的实体类数据)-----还原成Java对象!
      public ObjectInputStream(InputStream in) throws IOException:将文件中的数据,进行读取
      public final Object readObject()throws IOException,ClassNotFoundException
public class Person implements Serializable {

    //固定的序列化版本Id
    private static final long serialVersionUID = 6815664471916807752L;

    public transient String name ;//transient可以标记某个成员变量不参与序列化
    int age ;

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
public class ObjectStreamDemo {
    public static void main(String[] args) throws IOException, ClassNotFoundException {

   write() ;
        //read() ;
    }


    //反序列
    private static void read() throws IOException, ClassNotFoundException {
        //创建反序列化流对象
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("oos.txt")) ;

        // public final Object readObject()
        Object object = ois.readObject();

        System.out.println(object) ;
        //关闭资源
        ois.close() ;


    }

    //序列化
    private static void write() throws IOException {

        //将Person对象中里面成员信息永久存储到指定文件中:序列化,前提条件:Person类型必须实现标记接口序列化!
        //文件中乱码,不影响读取,通过反序列化---可以还原回来

        //创建序列化流对象
        ObjectOutputStream oos = new ObjectOutputStream(
                new FileOutputStream("oos.txt")) ;

        //创建Person类对象
        Person p = new Person() ;
        p.name = "高圆圆" ;
        p.age = 42 ;

        //public final void writeObject(Object obj)
        oos.writeObject(p) ;

        //释放资源
        oos.close() ;
    }
}

4.Propertis类:

Propertis:属性集合类(属性列表)是一个Map,但是没有泛型,键和值都是String
*
* 特有功能:
*      public Object setProperty(String key,String value):添加键和值
*      public Set<String> stringPropertyNames():获取所有 键的集合
*      public String getProperty(String key):获取键对应的值
*      public void store(Writer writer, String comments):将属性列表中的内容保存指定的文件中
*      参数2:给属性列表一个描述
*
*       public void load(Reader reader):将文件中的内容加载属性列表中
public class PropertiesTest {
    public static void main(String[] args) throws IOException {
        myLoad() ;

        //有一个属性列表
        Properties prop = new Properties() ;
        prop.setProperty("孙杰","30") ;
        prop.setProperty("臧永青","25") ;
        prop.setProperty("陈荣昌","28") ;
        prop.setProperty("陈琛","28") ;
        prop.setProperty("遆子林","25") ;
        prop.setProperty("于水利","26") ;

        //将属性列表中的内容保存指定文件中
        Writer w = new FileWriter("name.txt") ;
        prop.store(w,"name's list") ;
        //释放资源
        w.close() ;
    }

    //将文件中加载进来,将属性列表中内容可以遍历
    private static void myLoad() throws IOException {
        Reader r = new FileReader("Lucky.txt") ;
        //创建空的列表
        Properties prop = new Properties() ;
        //System.out.println(prop);
        prop.load(r);
        //System.out.println(prop);

        //获取所有的值
       /* Collection<Object> values = prop.values();
        for(Object obj :values){
            System.out.println(obj);
        }*/
        Set<String> keySet = prop.stringPropertyNames();
        for(String key :keySet){
            String value = prop.getProperty(key);
            System.out.println(key+"="+value) ;
        }

    }
}

----------------------加载src 目录 下的文件.properties--------------------------
 private static void method() throws IOException {
        //文件在哪个了中要读:
        //1)获取当前了类的字节码文件对象
        /*Class c = Test2.class ;
        //2)获取类加载器
        ClassLoader classLoader = c.getClassLoader();
        //3)通过类加载获取当前src目录下面的配置文件所在的输入流对象
        InputStream inputStream = classLoader.getResourceAsStream("name.properties");*/
        InputStream inputStream =
                Test2.class.getClassLoader().getResourceAsStream("name.properties");

        //创建Properties
        Properties prop = new Properties() ;
        prop.load(inputStream);

        System.out.println(prop) ;
    }



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值