IO-2

回顾:
学习了基本的4个父类的流
分别是
字节输入输出流
InputStream 和 OutputStream
字符输入输出流
Reader 和 Writer
因为InputStream 和 OutputStream 是抽象类 所以不能直接new对象
所以这里需要使用其子类流:
IO --> Input 和 Output
需要实现的就是 如何 将 内存中的数据写入到磁盘汇中 在从磁盘中将数据读取到内存中
既然写到磁盘最好的保存方式就是文件,所以这里就需要使用文件字节流
FileInputStream 和 FileOutputStream
那么无论如何大家必须记住几个点:
1.现在用的是什么流
2.流的流向是什么 是读取 还是写出
3.需要知道流中的数据是什么 是字节 还是字符
只要掌握以上三点ok什么流都可以写
除了上面这些还要记住如何循环读取数据 read(byte[] b) 和 wirter(byte[],int offset,int len)
只要流就需要关闭资源 和 写流的时候 可以刷新

使用字节流完成一张图片的读写操作--->文件
看InandOutStream包

/**
 * 
 */
package com.qfedu.Day20.IO.InandOutStream;

import java.io.*;

public class InAndOutDemo {
    public static void main(String[] args) {
        //1.将当前磁盘中的文件读取到内存
        InputStream is = null;
        //2.将内存中数据再次写入到磁盘中
        OutputStream os = null;
        try {
            is = new FileInputStream(new File("D:\\123\\1.jpg"));
            os = new FileOutputStream(new File("img/1.jpg"));
            
            //现在使用的文件字节输入输出流 --> 字节
            //读写流程
            //1.字节数组存储当前数据 一次就是1KB  乘4  乘 8
            byte[] buf = new byte[1024];
            //ps:read方法是有返回值的:实际读取内容的长度
            //若读取到文件的末尾 -1 没有读取到-1继续读取
            int len = 0; //用来存储实际读取额长度
            while( (len = is.read(buf))!=-1) {
                //写出数据
                os.write(buf, 0, len);
            }
            os.flush();
            System.out.println("老子写完了!!!");
    
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally {
             if(is != null) {
                 try {
                    is.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
             }
            if (os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            
        }

    }

}

/**
 * 
 */
package com.qfedu.Day20.IO.InandOutStream;

import java.io.*;

public class InAndOutDemo2 {
    public static void main(String[] args)throws Exception {
        //1将文件夹中的数据过滤出来
        File srcFile = new  File("Java");
        File desFile = new  File("test");
        File[] files = srcFile.listFiles(new FilenameFilter() {
            /*
             * dir 对应的就是srcFile中的文件路径
             * name 对应的是srcFile中文件路径下的文件名
             */
            @Override
            public boolean accept(File dir, String name) {
                
                return name.endsWith(".java") && new File(dir,name).isFile();
            }
        });
        //2拿到文件的路径,将对应路径的文件写入到新的文件中
        for(File file : files) {
            //构建流对象 输入(读) 输出(写) 
            InputStream is  = new FileInputStream(file);
            OutputStream os = new FileOutputStream(new File(desFile,file.getName()));
             byte[] buf = new byte[1024];
             int len = 0;
             while((len = is.read(buf))!=-1) {
                 os.write(buf, 0, len);
             }
             os.flush();
             System.out.println("老子写完了!!!!");
             //最后完成的流先关闭
             os.close();
             is.close();
        }

    }

}

 

总结:
字节流的应用:可以拷贝文件(音频,视频,图像,压缩,doc,exe等等)
字节流千万不要用来拷贝文本文件,因为可能出现乱码

字符输入输出流(专门用来拷贝文本文件的)
Reader 字符输入流
Writer 字符输出流
可以使用字符流来进行文件的读写操作,汉子一些特殊字符都可以应对并且不会乱码的问题
字符流和字节流最大的不同就是
流中的数据不同: 字符 char 字节 byte
Reader和Writer是抽象类不能直接创建对象,此时使用 其之类的方式来完成对象的构建
FileReader 和 FileWriter 子类
读取和写出方式和FileInputStream和FileOutputStream是一样的
只不过这里我们使用的是字符流,所以流中的数据是字符char
批量存储数据的话需要使用是字符数组 char[]
常用方法:
构造方法摘要
FileReader(File file) 通过File对象创建字符输入流
FileReader(String fileName) 通过路径创建字符输入流
read(char[] cbuf, int off, int len) 将字符读入数组的某一部分
若返回值是-1 证明读取到文件末尾,不是的就是实际读取的长度

FileWriter(File file) 通过File对象创建字符输出流对象
FileWriter(File file, boolean append) 通过File对象创建字符输出流对象,传入true值可以追加(参考字节流)
FileWriter(String fileName) 通过路径创建字符输出流
FileWriter(String fileName, boolean append) 通过路径创建字符输出流,传入true值可以追加(参考字节流)
write(char[] cbuf, int off, int len) 写入字符数组的某一部分。
字符数组,从字符数组开始写,实际长度是多少
close() 关闭此流,但要先刷新它。
void flush() 刷新该流的缓冲。
看 Reader 包 和 Writer包

/**
 * 
 */
package com.qfedu.Day20.IO.Reader;

import java.io.*;

public class ReaderDemo {
    public static void main(String[] args) {
        //1.创建流对象 -->流的流向 (读)
        Reader reader = null;
        try {
            reader = new FileReader("dir/file.txt");
            
            //2.流中数据类型是什么 ---> char类型
            char[] cbuf = new char[1024];
            //实际读取内容的长度
            int len =  0;
            while((len = reader.read(cbuf))!=-1) {
                System.out.println(new String(cbuf,0,len));
            }
            
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally {
            if(reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }

    }

}

/**
 * 
 */
package com.qfedu.Day20.IO.Writer;

import java.io.*;

public class WriterDemo {

    public static void main(String[] args) {
        //1.构建流对象 --> 写出去(输出流)
        String str1 = "饿了!";
        String str2 = "今天早饭就吃了一个三明治\n";
        String str3 = "经过了1个半小时 饿了...真的饿\n";
        String str4 = "吃饭去吧!!!!";
        Writer writer = null;
        try {
            //FileWriter和FileInputStrea类似
            //都提供了一个构造方法 这个方法可以在文件的末尾追加新的数据
            //参数是boolean 默认值是false代表不追加 ,若需要追加请使用true
            writer = new FileWriter("dir/饿了么.txt");
            //提供一个特有方法 参数是字符串 将字符串写出去
            writer.write(str1);
            writer.write(str2);
            writer.write(str3);
            writer.write(str4);
            //append 正常使用的效果和wirter是一样的
            //除非使用了 可以追加 不然,一般情况下是不会会使用这个方法
            writer.append("拜拜!!!");
            //出上面这些方法外最常用的就是write(cbuf, off, len);
            writer.flush();
            System.out.println("写完了");
    
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally {
            if(writer != null) {
                try {
                    writer.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    
    }

}

 


需求:使用字符流完成一张图片的读写操作--->文件 将当前图片打开
总结:
字符流和字节流的基本应用是一样,但是应用场景是完全不同
字符流主要应用于文本文件的读取和写入操作,不要使用字符完成特殊文件(音频,视频,图片,压缩包等等)的拷贝
看ReaderAndWriter包

/**
 * 
 */
package com.qfedu.Day20.IO.ReaderAndWriter;

import java.io.*;

public class ReaderAndWriterDemo {
    public static void main(String[] args) {
         //1.构建流对象 --> 流的流向(输入,输出)
         //2.流中的数据应该是 字符
        Reader reader = null;
        Writer writer = null;
        try {
            reader = new FileReader("D:\\123\\2.jpg");
            writer = new FileWriter("img/2.jpg");
            
            //明确了流中的数据是字符
            //创建字符数组存储内容并读取大小
            char[] cbuf = new char[1024];
            //定义变量存储实际读取的长度
            int len = 0;
            while( (len = reader.read(cbuf)) != -1) {
                writer.write(cbuf, 0, len);
            }
            writer.flush();
            System.out.println("写完了!!!!");
        
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally {
            if(writer != null) {
                try {
                    writer.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if(reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
        
    }

}

 

标准输入输出流:(重定向)
System.in 标准输入流 数据类型是InputStream 所以当前类所以字节流
System.out 标准输出流 数据类型是 PrintStream 打印字节输出流 也属于字节流
ps:Scanner input = new Scanner(System.in);
System.out.println("控制台上")

若需要修改标准输入输出流的流向此时需要使用如下两个方法
这两个方法属于System类 并且是静态方法,所以可以直接调用
static void setIn(InputStream in)
重新分配“标准”输入流。
static void setOut(PrintStream out)
重新分配“标准”输出流。
看SystemInAndOut

/**
 * 
 */
package com.qfedu.Day20.IO.SystemInAndOut;

import java.io.*;

public class SystemInAndOutDemo{
      public static void main(String[] args) {
           //既然要改变流的流向
          //1.就要创建流的流向
          //先构建system.in的流向和构建System.out的流向
          //1.7之后Java提供的新try...catch语法 可以直接释放对象
          //ps若有多个对象使用;隔开,若只有一个对象就不需要分号了
          try(InputStream is = new FileInputStream("src/com/qfedu/Day20/IO/ReaderAndWriter/ReaderAndWriterDemo.java");
                  PrintStream ps = new PrintStream(new File("dir/newJava.java"))){
              //修改当前标准输输出流的流向
              System.setIn(is);//此时System.in就不会在控制台上获取数据了,而是从你定义的流中获取数据
              System.setOut(ps);//此时System.out就不会打印到控制台上了,打印你所定义的流位置
              
              //当前的流都属于字节流
              byte[] buf = new byte[1024];
              int len = 0;
              while((len = System.in.read(buf))!=-1) {
                  System.out.write(buf, 0, len);
              }
             
              //标准输入输出流改变会控制台
              
              //改变流的流向
              
              //1.需要使用
              /*
               * FileOutputStream(FileDescriptor fdObj) 创建一个向指定文件描述符处写入数据的输出文件流
               * 参数是一个文件描述符 ---> 文件句柄
               * 帮组我们将已经改的原有标准输入输出流改回系统
               * 需要两个静态字段(属性)
               * static FileDescriptor in 标准输入流的句柄。 
               * static FileDescriptor out 标准输出流的句柄 
               * 当前流对象就已经获取了系统输出的标准
               */
            PrintStream  ps1 = new PrintStream(new FileOutputStream(FileDescriptor.out));
             System.setOut(ps1);
             System.out.println("老子写完了!!!!!");//不能打印到控制台上,因为改变了流的流向
            
              System.out.flush();
              
          }catch(IOException e) {
              e.printStackTrace();
          }
        
    }
}

 

需求:将"老子写完了"这句话重新打印到控制台;

 

字符编码发展过程
阶段1:
计算机只认识数字,我们在计算机里一切数据都是以数字来表示,因为英文符号有限,
所以规定使用的字节的最高位是0.每一个字节都是以0~127之间的数字来表示,比如A对应65,a对应97.
这就是美国标准信息交换码-ASCII.

阶段2:
随着计算机在全球的普及,很多国家和地区都把自己的字符引入了计算机,比如汉字.(易语言(中文)-->java)
此时发现一个字节能表示数字范围太小,不能包含所有的中文汉字,那么就规定使用两个字节来表示一个汉字.
规定:原有的ASCII字符的编码保持不变,仍然使用一个字节表示,为了区别一个中文字符与两个ASCII码字符,
中文字符的每个字节最高位规定为1(中文的二进制是负数).这个规范就是GB2312编码,
后来在GB2312的基础上增加了更多的中文字符,比如汉字,也就出现了GBK.

阶段3:
新的问题,在中国是认识汉字的,但是如果把汉字传递给其他国家,该国家的码表中没有收录汉字,其实就显示另一个符号或者乱码.
为了解决各个国家因为本地化字符编码带来的影响,咱们就把全世界所有的符号统一进行编码-Unicode编码(万国码).
\u0000 ~ \uFFFF
此时某一个字符在全世界任何地方都是固定的,比如'哥',在任何地方都是以十六进制的54E5来表示.
Unicode的编码字符都占有2个字节大小.
--------------------------------------------------------------------------------------------------------------
常见的字符集:
ASCII: 占一个字节,只能包含128个符号. 不能表示汉字
ISO-8859-1:(latin-1):占一个字节,收录西欧语言(西文),不能表示汉字.
ANSI:占两个字节,在简体中文的操作系统中 ANSI 就指的是 GB2312.
GB2312/GBK/GB18030:占两个字节,支持中文.
UTF-8:是一种针对Unicode的可变长度字符编码,又称万国码,是Unicode的实现方式之一。
编码中的第一个字节仍与ASCII兼容,这使得原来处理ASCII字符的软件无须或只须做少部份修改,即可继续使用。
因此,它逐渐成为电子邮件、网页及其他存储或传送文字的应用中,优先采用的编码。互联网工程工作小组(IETF)要求所有互联网协议都必须支持UTF-8编码。
UTF-8 BOM:是MS搞出来的编码,默认占3个字节,不要使用这个.
存储数据,数度的第第一位 出现 ?
你好北京天安门! ---> ?你好北京天安门! --> 修改文件的编码集,手动Notpad++文本编辑器

--------------------------------------------------------------------------------------------------------------

存储字母,数字和汉字:
存储字母和数字无论是什么字符集都占1个字节.
存储汉字: GBK家族占两个字节,UTF-8家族占3个字节(变长).

--------------------------------------------------------------------------------------------------------------

不能使用单字节的字符集(ASCII/ISO-8859-1)来存储中文.

转换流:
InputStreamReader 字节流转换为字符流
OutputStreamWriter 字符流转换为字节流
设置编码并加强 字节流的使用
字节流 读取特殊文件 / 文本文件
字符流 文本文件
ps:读取时字节编码就设置错误,打印时就不会成功
读取时就是错误,打印时肯定是错误,所以在设置编码时一定要设置正确
读取时是正确的,打印的时候就可以改变其编码


InputStreamReader 的父类是谁? 是什么流转什么流
父类是Reader 字符流 字节流转换字符流
构造方法摘
InputStreamReader(InputStream in) 通过字节流对象创建当前转换流对象
InputStreamReader(InputStream in, Charset cs) 通过字节流对象创建当前转换流对象,并且可以制定读取文件的编码集
InputStreamReader(InputStream in, String charsetName) 通过字节流对象创建当前转换流对象,并且可以制定读取文件的编码集
若是使用CharSet形式 CharSet.forName("GBK") --> 小括号中是一个字符串,写编码名称即可
若是使用字符串形式 就直接传入编码名即可 "UTF-8"
void close() 关闭该流并释放与之关联的所有资源。
int read(char[] cbuf, int offset, int length) 将字符读入数组中的某一部分。
看InputStreamReader包

/**
 * 
 */
package com.qfedu.Day20.IO.InputStreamReader;

import java.io.*;
import java.nio.charset.Charset;

public class InputStreamReaderDemo {

    public static void main(String[] args) {
        //1.先明确使用的流 流向 (读取 In/read)
        //ps:一定一定要注意,创建流对象时,参数传递的是什么
        //当前就是创建了一个转换流对象,此时就是将字节输入流转换为字符输入流
        //当前是字节转换字符流的基本写法 --->使用的是默认编码GBK
        //  ctrl + / 批量注释
//        InputStreamReader isr = null;
//        try {
//            isr = 
//                    new InputStreamReader(
//                            new FileInputStream(
//                                    new File("src/com/qfedu/Day20/IO/Reader/ReaderDemo.java")));
//            //可以获取当前文件的字符编码
//            //几乎与用不了,这个方法只能在程序运行起来后才能获得当前文件的编码
//            System.out.println("当前文件的字符编码时:"+isr.getEncoding());
//            //2.当前流中的 数据是什么  char字符
//            char[] cbuf = new char[1024];
//            int len = 0;
//            while((len = isr.read(cbuf))!=-1) {
//                 System.out.println(new String(cbuf,0,len));
//            }
//            
//        } catch (FileNotFoundException e) {
//            // TODO Auto-generated catch block
//            e.printStackTrace();
//        } catch (IOException e) {
//            // TODO Auto-generated catch block
//            e.printStackTrace();
//        }finally {
//            if(isr != null) {
//                try {
//                    isr.close();
//                } catch (IOException e) {
//                    // TODO Auto-generated catch block
//                    e.printStackTrace();
//                }
//            }
//        }
        
        //使用编码集的形式来读取数据
        //当前file1.txt文件的编码时UTF-8
        //此时创建的转换流对象使用的是UTF-8编码集
        try(InputStreamReader isr = 
                new InputStreamReader(
                        new FileInputStream(
                                new File("dir/file1.txt")),Charset.forName("UTF-8"))){
            System.out.println("当前文件编码是:"+isr.getEncoding());
            char[] cbuf = new char[1024];
            int len = 0;
            while((len = isr.read(cbuf))!=-1) {
                //全转换为大写
                System.out.println(new String(cbuf,0,len).toUpperCase());
            }
            
        }catch(IOException e) {
            e.printStackTrace();
        }
        
    }

}

 


OutputStreamWriter 的父类是谁? 是什么流转什么流
父类是Writer 字符流 字符流转字节流
构造方法
OutputStreamWriter(OutputStream out)通过字节流对象创建当前转换流对象
OutputStreamWriter(OutputStream out, Charset cs) 通过字节流对象创建当前转换流对象,并且可以制定读取文件的编码集
OutputStreamWriter(OutputStream out, String charsetName) 通过字节流对象创建当前转换流对象,并且可以制定读取文件的编码集
若是使用CharSet形式 CharSet.forName("GBK") --> 小括号中是一个字符串,写编码名称即可
若是使用字符串形式 就直接传入编码名即可 "UTF-8"
void close() 关闭此流,但要先刷新它。
void flush() 刷新该流的缓冲。
void write(char[] cbuf, int off, int len) 写入字符数组的某一部分。

需求:使用转换流来完成文件的读取和写入操作,实现文件的拷贝
1.源文件的编码集是UTF-8
目标文件的编码就是GBK
2.源文件的编码集是GBK
目标文件的编辑是UTF-8
3.源文件的编码集是UTF-8
目标文件的编码集是UTF-8

总结:转换流的作用其实就是加强字节流的文件读写能力
转换流可以防止文件乱码,可以设置编码值
看InReaderAndOutWriter

/**
 * 
 */
package com.qfedu.Day20.IO.InputStreamReader;

import java.io.*;
import java.nio.charset.Charset;

public class InputStreamReaderDemo {

    public static void main(String[] args) {
        //1.先明确使用的流 流向 (读取 In/read)
        //ps:一定一定要注意,创建流对象时,参数传递的是什么
        //当前就是创建了一个转换流对象,此时就是将字节输入流转换为字符输入流
        //当前是字节转换字符流的基本写法 --->使用的是默认编码GBK
        //  ctrl + / 批量注释
//        InputStreamReader isr = null;
//        try {
//            isr = 
//                    new InputStreamReader(
//                            new FileInputStream(
//                                    new File("src/com/qfedu/Day20/IO/Reader/ReaderDemo.java")));
//            //可以获取当前文件的字符编码
//            //几乎与用不了,这个方法只能在程序运行起来后才能获得当前文件的编码
//            System.out.println("当前文件的字符编码时:"+isr.getEncoding());
//            //2.当前流中的 数据是什么  char字符
//            char[] cbuf = new char[1024];
//            int len = 0;
//            while((len = isr.read(cbuf))!=-1) {
//                 System.out.println(new String(cbuf,0,len));
//            }
//            
//        } catch (FileNotFoundException e) {
//            // TODO Auto-generated catch block
//            e.printStackTrace();
//        } catch (IOException e) {
//            // TODO Auto-generated catch block
//            e.printStackTrace();
//        }finally {
//            if(isr != null) {
//                try {
//                    isr.close();
//                } catch (IOException e) {
//                    // TODO Auto-generated catch block
//                    e.printStackTrace();
//                }
//            }
//        }
        
        //使用编码集的形式来读取数据
        //当前file1.txt文件的编码时UTF-8
        //此时创建的转换流对象使用的是UTF-8编码集
        try(InputStreamReader isr = 
                new InputStreamReader(
                        new FileInputStream(
                                new File("dir/file1.txt")),Charset.forName("UTF-8"))){
            System.out.println("当前文件编码是:"+isr.getEncoding());
            char[] cbuf = new char[1024];
            int len = 0;
            while((len = isr.read(cbuf))!=-1) {
                //全转换为大写
                System.out.println(new String(cbuf,0,len).toUpperCase());
            }
            
        }catch(IOException e) {
            e.printStackTrace();
        }
        
    }

}

 

内存流(了解) ---> 设计模式 --> 适配器模式
内存计算的效率要比磁盘高,磁盘要发生IO读写操作
ps:请不要以自己电脑的内存取比较服务器内存
1.字节内存流:ByteArrayInputStream/ByteArrayOutputStream
2.字符内存流:CharArrayReader/CharArrayWriter
3.字符串内存StringReader/StringWriter
数据都是临时存储到内存:
以数组名在内的内存流,临时存储到数组中然后在取出来
以字符串在内的内存流,临时存储到字符串中然后在取出来

/**
 * 
 */
package com.qfedu.Day20.IO.NeiCun;

import java.io.*;

public class Demo {
    public static void main(String[] args)throws Exception{
        //showByteArray();
        //1.数据写入字符串流中
        StringWriter writer = new StringWriter();
        writer.write("小龙是什么地方的人?");
        writer.write("河南人");
        writer.write("B哥是什么地方的人?");
        writer.write("火星人");
        
        StringReader reader = new StringReader(writer.toString());
        char[] buffer = new char[1024];
        int len = 0;
        while((len = reader.read(buffer))!=-1) {
            System.out.println(new String(buffer,0,len));
        }
        

    }
    public static void showByteArray()throws Exception {
        //因为,需要将数据先存储到内存数据中然后才能使用内存流将数据读取出来
                //创建字节内存输出流 程序-->内存 写入数据
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                bos.write("ABCDEFG".getBytes());//将数据写入到内存
                //要使用数组来保存数据
                byte[] buffer = bos.toByteArray();
                
                //读取  内存中数据将数据在读取到 --> 程序中
                //参数是一个数组 --> 存储着写入到写入到内存中的数据
                ByteArrayInputStream bis = new ByteArrayInputStream(buffer);
                  byte[] bs = new byte[5];
                  int len = 0;
                  while((len = bis.read(bs))!=-1) {
                      System.out.println(new String(bs,0,len));
                  }
                bis.close();
                bos.close();
                //CharArrayReader 和 CharArrayWriter 使用方式和 byte是一样的 改变数组数据类型即可
    }

}

 


缓冲流
字节缓冲流:
在操作数据的时候,先将数据存储到内部的缓冲区中(字节数组),然后,程序操作缓冲区的数据
最大的特点,可以提法哦流中传输的数据,非常建议使用这个流
BufferedInputStream 字节输入缓冲流
BufferedOutputStream 字节输出缓冲流
这个流之所以是缓冲路在于它创建对象的方法

 

/**
 * 
 */
package com.qfedu.Day20.IO.BufferedInputStream;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

import com.qfedu.Day20.IO.SystemInAndOut.SystemInAndOutDemo;

public class BufferedInputStreamDemo {    
    public static void main(String[] args) {
        //再碰到异常一样要抓取
        //参数是一个字节输入流对象
        try(BufferedInputStream bis = 
                new BufferedInputStream(
                        new FileInputStream(
                                new File("src/com/qfedu/Day20/IO/BufferedInputStream/BufferedInputStreamDemo.java")))){
            //判断当前流对象是否支持mark标记 --> true 支持 false 不支持
            System.out.println("判断是否支持标记:"+bis.markSupported());
            bis.mark(1);//字节个数,给了什么数那么下次读取就在什么位置开始
            byte[] buf = new byte[1024];
            int len = 0;
            while((len = bis.read(buf))!=-1) {
                System.out.println(new String(buf,0,len));
                
            }
            System.out.println("----------------------再次重新读取文件的内容-------------------------");
            bis.reset();//重启标记
            while((len = bis.read(buf))!=-1) {
                System.out.println(new String(buf,0,len));
                
            }
            //一次读取一个节
            /*
             * hello
             * bis.read() --> h
             * bis.read() --> e
             * bis.mark(3) 对多可以读取几个字节
             * bis.read() --> l
             * bis.read() --> l
             * bis.read() --> o
             * bis.reset();
             * bis.read() //llo
            
             * 
             */
            
        }catch(IOException e) {
            e.printStackTrace();
        }

    }

}


/**
 * 
 */
package com.qfedu.Day20.IO.BufferedOutputStream;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintStream;

public class BufferedOutputStreamDemo {
    public static void main(String[] args)throws Exception {
        //在控制台上获取数据-->bis流对象就可以在控制台上获取数据
        //ps:Scanner --> 在控制台上获取数据
        BufferedInputStream bis = new BufferedInputStream(System.in);
        PrintStream ps = new PrintStream(new FileOutputStream(new File("dir/字节缓冲流输出的数据.txt")));
        System.setOut(ps);
        //构建标准输出流
        BufferedOutputStream bos = new BufferedOutputStream(System.out);
        //在控制台上输入数据输入什么就写入到对应的文件中
        byte[] bs = new byte[1024];
        int len = 0;
        while(true) {
            //获取控制台输入
            len = bis.read(bs);
           //创建一个字符串
            String content = new String(bs,0,len);
            //只要是输入886,这个程序就停止
            if("886".equals(content)) {
                break;
            }
            bos.write(content.getBytes());
            bos.flush();
        }    
        bos.close();
        bis.close();
    
    }

}

 

posted @ 2018-08-24 20:09  lijun199309  阅读(194)  评论(0编辑  收藏  举报