IO流

来源:互联网 发布:linux系统图形界面 编辑:程序博客网 时间:2024/05/12 23:35


IO

一、IO流概述及其分类

 1.概念

       IO流用来处理设备之间的数据传输

       Java对数据的操作是通过流的方式

       Java用于操作流的类都在IO包中

       流按流向分为两种:输入流,输出流。

       流按操作类型分为两种:

              字节流 :字节流可以操作任何数据,因为在计算机中任何数据都是以字节的形式存储的

              字符流 :字符流只能操作纯字符数据,比较方便。

 2.IO流常用父类

       字节流的抽象父类:

              InputStream

              OutputStream

       字符流的抽象父类:

             Reader

             Writer         

 3.IO程序书写

       使用前,导入IO包中的类

       使用时,进行IO异常处理

       使用后,释放资源

 

二、IO(read()方法返回值为什么是int)

 read()方法读取的是一个字节,为什么返回是int,而不是byte

             因为字节输入流可以操作任意类型的文件,比如图片音频等,这些文件底层都是以二进制形式的存储的,如果每次读取都返回byte,有可能在读到中间的时候遇到111111111

             那么这11111111byte类型的-1,我们的程序是遇到-1就会停止不读了,后面的数据就读不到了,所以在读取的时候用int类型接收,如果11111111会在其前面补上

             240凑足4个字节,那么byte类型的-1就变成int类型的255了这样可以保证整个数据读完,而结束标记的-1就是int类型


三、IO(拷贝图片)

 FileInputStream读取

 FileOutputStream写出

 

四、IO(拷贝音频文件画原理图)

      字节流一次读写一个字节复制音频

 弊端:效率太低

 

五、IO(字节数组拷贝之available()方法)

       int read(byte[] b):一次读取一个字节数组

       write(byte[] b):一次写出一个字节数组

      available()获取读的文件所有的字节个数

 弊端:有可能会内存溢出

      

六、IO(定义小数组)

 write(byte[] b)

 write(byte[] b, int off, int len)写出有效的字节个数

 

七、IO(定义小数组的标准格式)

       字节流一次读写一个字节数组复制图片和视频

             FileInputStreamfis = new FileInputStream("致青春.mp3");

             FileOutputStreamfos = new FileOutputStream("copy.mp3");

             intlen;

             byte[]arr = new byte[1024 * 8];                              //自定义字节数组

             

             while((len= fis.read(arr)) != -1) {

                    //fos.write(arr);

                    fos.write(arr,0, len);                                              //写出字节数组写出有效个字节个数

             }

             

             fis.close();

             fos.close();

八、IO(BufferedInputStreamBufferOutputStream拷贝)

 A:缓冲思想

       字节流一次读写一个数组的速度明显比一次读写一个字节的速度快很多,

       这是加入了数组这样的缓冲区效果,java本身在设计的时候,

       也考虑到了这样的设计思想(装饰设计模式后面讲解),所以提供了字节缓冲区流

 B.BufferedInputStream

       BufferedInputStream内置了一个缓冲区(数组)

       BufferedInputStream中读取一个字节时

       BufferedInputStream会一次性从文件中读取8192,存在缓冲区中,返回给程序一个

       程序再次读取时,就不用找文件了,直接从缓冲区中获取

       直到缓冲区中所有的都被使用过,才重新从文件中读取8192

 C.BufferedOutputStream

       BufferedOutputStream也内置了一个缓冲区(数组)

       程序向流中写出字节时,不会直接写到文件,先写到缓冲区中

       直到缓冲区写满, BufferedOutputStream才会把缓冲区中的数据一次性写到文件里

 D.拷贝的代码

 

             FileInputStreamfis = new FileInputStream("致青春.mp3");                    //创建文件输入流对象,关联致青春.mp3

             BufferedInputStreambis = new BufferedInputStream(fis);               //创建缓冲区对fis装饰

             FileOutputStreamfos = new FileOutputStream("copy.mp3");           //创建输出流对象,关联copy.mp3

             BufferedOutputStreambos = new BufferedOutputStream(fos);        //创建缓冲区对fos装饰

             

             intb;

             while((b= bis.read()) != -1) {            

                    bos.write(b);

             }

             

             bis.close();                                       //只关装饰后的对象即可

             bos.close();

       

 E.小数组的读写和带Buffered的读取哪个更快?

       定义小数组如果是8192个字节大小和Buffered比较的话

       定义小数组会略胜一筹,因为读和写操作的是同一个数组

       Buffered操作的是两个数组

 

九、IO(flushclose方法的区别)

 flush()方法

       用来刷新缓冲区的,刷新后可以再次写出

 close()方法

       用来关闭流释放资源的的,如果是带缓冲区的流对象的close()方法,不但会关闭流,还会再关闭流之前刷新缓冲区,关闭后不能再写出

十、IO(字节流读写中文)

 字节流读取中文的问题

 字节流在读中文的时候有可能会读到半个中文,造成乱码

 字节流写出中文的问题

       字节流直接操作的字节,所以写出中文必须将字符串转换成字节数组

 写出回车换行write("\r\n".getBytes());

 

十一、IO流的标准处理异常代码

A1.6版本及其以前

 tryfinally嵌套

 

             FileInputStreamfis = null;

             FileOutputStreamfos = null;

             try{

                    fis= new FileInputStream("aaa.txt");

                    fos= new FileOutputStream("bbb.txt");

                    intb;

                    while((b= fis.read()) != -1) {

                           fos.write(b);

                    }

             }finally {

                    try{

                           if(fis!= null)

                                  fis.close();

                    }finally{

                           if(fos!= null)

                                  fos.close();

                    }

             }

 

B1.7版本

 tryclose

 

             try(

                    FileInputStreamfis = new FileInputStream("aaa.txt");

                    FileOutputStreamfos = new FileOutputStream("bbb.txt");

                    MyClosemc = new MyClose();

             ){

                    intb;

                    while((b= fis.read()) != -1) {

                           fos.write(b);

                    }

             }

 原理

      try()中创建的流对象必须实现了AutoCloseable这个接口,如果实现了,try后面的{}(读写代码)执行后就会自动调用,流对象的close方法将流关掉

 

十二、IO(图片加密)

 给图片加密

 

             BufferedInputStreambis = new BufferedInputStream(new FileInputStream("a.jpg"));

             BufferedOutputStreambos = new BufferedOutputStream(new FileOutputStream("b.jpg"));

             

             intb;

             while((b= bis.read()) != -1) {

                    bos.write(b^ 123);

             }

             

             bis.close();

             bos.close();

 

十三、IO(拷贝文件)

在控制台录入文件的路径,将文件拷贝到当前项目下

 

             Scannersc = new Scanner(System.in);

             System.out.println("请输入一个文件路径");

             Stringline = sc.nextLine();                        //将键盘录入的文件路径存储在line

             Filefile = new File(line);                            //封装成File对象

             FileInputStreamfis = new FileInputStream(file);

             FileOutputStreamfos = new FileOutputStream(file.getName());

             

             intlen;

             byte[]arr = new byte[8192];                     //定义缓冲区

             while((len= fis.read(arr)) != -1) {

                    fos.write(arr,0,len);

             }

             

             fis.close();

             fos.close();

 

十四、IO(录入数据拷贝到文件)

 将键盘录入的数据拷贝到当前项目下的text.txt文件中,键盘录入数据当遇到quit时就退出

 

             Scannersc = new Scanner(System.in);

             FileOutputStreamfos = new FileOutputStream("text.txt");

             System.out.println("请输入:");

             while(true){

                    Stringline = sc.nextLine();

                    if("quit".equals(line))

                           break;

                    fos.write(line.getBytes());

                    fos.write("\r\n".getBytes());

             }

             

             fos.close();

 

十五、IO流字符流

1.字符流是什么

       字符流是可以直接读写字符的IO

       字符流读取字符,就要先读取到字节数据,然后转为字符.如果要写出字符,需要把字符转为字节再写出.   

 2.FileReader

       FileReader类的read()方法可以按照字符大小读取

3FileWriter)

 FileWriter类的write()方法可以自动把字符转为字节写出

4、字符流的拷贝

      FileReaderfr = new FileReader("a.txt");

      FileWriterfw = new FileWriter("b.txt");

      

      intch;

      while((ch= fr.read()) != -1) {

             fw.write(ch);

      }

      

      fr.close();

      fw.close();

5、什么情况下使用字符流

 字符流也可以拷贝文本文件,但不推荐使用.因为读取时会把字节转为字符,写出时还要把字符转回字节.

 程序需要读取一段文本,或者需要写出一段文本的时候可以使用字符流

 读取的时候是按照字符的大小读取的,不会出现半个中文

 写出的时候可以直接将字符串写出,不用转换为字节数组

6、字符流是否可以拷贝非纯文本的文件

 不可以拷贝非纯文本的文件

 因为在读的时候会将字节转换为字符,在转换过程中,可能找不到对应的字符,就会用?代替,写出的时候会将字符转换成字节写出去

 如果是?,直接写出,这样写出之后的文件就乱了,看不了了 

7、自定义字符数组的拷贝

      

             FileReaderfr = new FileReader("aaa.txt");                 //创建字符输入流,关联aaa.txt

             FileWriterfw = new FileWriter("bbb.txt");                 //创建字符输出流,关联bbb.txt

             

             intlen;

             char[]arr = new char[1024*8];                                      //创建字符数组

             while((len= fr.read(arr)) != -1) {                             //将数据读到字符数组中

                    fw.write(arr,0, len);                                               //从字符数组将数据写到文件上

             }

             

             fr.close();                                                                            //关流释放资源

             fw.close();     

8、带缓冲的字符流

 BufferedReaderread()方法读取字符时会一次读取若干字符到缓冲区,然后逐个返回给程序,降低读取文件的次数,提高效率

 BufferedWriterwrite()方法写出字符时会先写到缓冲区,缓冲区写满时才会写到文件,降低写文件的次数,提高效率

 

十六、IO(readLine()newLine()方法) 

 BufferedReaderreadLine()方法可以读取一行字符(不包含换行符号)

 BufferedWriternewLine()可以输出一个跨平台的换行符号"\r\n"

 

十七、IO(LineNumberReader)

 LineNumberReaderBufferedReader的子类,具有相同的功能,并且可以统计行号

       调用getLineNumber()方法可以获取当前行号

       调用setLineNumber()方法可以设置当前行号

 

十八、IO(装饰设计模式)

 

             interfaceCoder {

                    publicvoid code();

             }

             

             classStudent implements Coder {

             

                    @Override

                    publicvoid code() {

                           System.out.println("javase");

                           System.out.println("javaweb");

                    }

                    

             }

             

             classHeiMaStudent implements Coder {

                    privateStudent s;                                     //获取到被包装的类的引用

                    publicItcastStudent(Student s) {        //通过构造函数创建对象的时候,传入被包装的对象

                           this.s= s;

                    }

                    @Override

                    publicvoid code() {                                  //对其原有功能进行升级

                           s.code();

                           System.out.println("数据库");

                           System.out.println("ssh");

                           System.out.println("安卓");

                           System.out.println(".....");

                    }

                    

             }

 

十九、IO(使用指定的码表读写字符)

 FileReader是使用默认码表读取文件,如果需要使用指定码表读取,那么可以使用InputStreamReader(字节流,编码表)

 FileWriter是使用默认码表写出文件,如果需要使用指定码表写出,那么可以使用OutputStreamWriter(字节流,编码表)

 

二十、IO(内存输出流)

 1.什么是内存输出流

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

 2.使用方式

       创建对象: new ByteArrayOutputStream()

       写出数据: write(int), write(byte[])

       获取数据: toByteArray()

      

二十一、IO(打印流的概述和特点)

 1.什么是打印流

       该流可以很方便的将对象的toString()结果输出,并且自动加上换行,而且可以使用自动刷出的模式

       System.out就是一个PrintStream,其默认向控制台输出信息

 2.使用方式

       打印: print(), println()

       自动刷出: PrintWriter(OutputStream out, boolean autoFlush, String encoding)

       打印流只操作数据目的

                

二十二、IO(标准输入输出流概述和输出语句)

 1.什么是标准输入输出流(掌握)

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

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

 2.修改标准输入输出流(了解)

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

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

 

 

1 0
原创粉丝点击