java IO流 万字长文,建议收藏

2021/9/21 20:11:51

本文主要是介绍java IO流 万字长文,建议收藏,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

 一。流的概念和作用

流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。 

IO流中使用了大量的装饰者模式

二。流的分类:

只要是处理纯文本数据,就优先考虑使用字符流。 除此之外都使用字节流。

三。字节流:InputStream和OutputStream字节流用来处理媒体数据

1、字节流和字符流的基本操作是相同的,但是要想操作媒体流就需要用到字节流。

2、字节流因为操作的是字节,所以可以用来操作媒体文件。(媒体文件也是以字节存储的)

3、读写字节流:InputStream   输入流(读)和OutputStream  输出流(写)

4、字节流操作可以不用刷新流操作。

5、InputStream特有方法:

        int available();//返回文件中的字节个数

注:可以利用此方法来指定读取方式中传入数组的长度,从而省去循环判断。但是如果文件较大,而虚拟机启动分配的默认内存一般为64M。当文件过大时,此数组长度所占内存空间就会溢出。所以,此方法慎用,当文件不大时,可以使用。

处理8位的字节

(该类中所有的方法遇到错误时都会抛出异常)

InputStream的方法:

read()方法:从输入流中读取数据的下一个字节。返回0~255之间的int值、

read(byte[] b)方法 :从输入流中读取一定的字节长度,并以整数的形式返回字节数

mark(int readlimit)方法 :做标记

reset()方法:返回标记位

close()方法:关闭资源

复制一张图片F:\java_Demo\day9_28\1.BMP到F:\java_Demo\day9_28\2.bmp

import java.io.*;  
  
  
class CopyPic {  
    public static void main(String[] args){  
        copyBmp();  
        System.out.println("复制完成");  
    }  
  
    public static void copyBmp() {  
  
        FileInputStream fis = null;  
        FileOutputStream fos = null;  
        try {  
            fis = new FileInputStream("F:\\java_Demo\\day9_28\\1.bmp");             //写入流关联文件  
            fos = new FileOutputStream("F:\\java_Demo\\day9_28\\2.bmp");            //读取流关联文件  
            byte[] copy = new byte[1024];  
            int len = 0;  
            while((len=fis.read(copy))!=-1) {  
            fos.write(copy,0,len);  
            }  
        }  
        catch (IOException e) {  
            e.printStackTrace();  
            throw new RuntimeException("复制文件异常");  
        }  
        finally {  
            try {  
                if(fis!=null) fis.close();  
            }  
            catch (IOException e) {  
                e.printStackTrace();  
                throw new RuntimeException("读取流");  
            }  
        }  
          
    }  
  
}  

OutputStream的方法:

write()方法:将指定的字节写入流中

write(byte [] b)方法: 将b个字节从指定的byte 数组写入此流

write(byte [] b, int off,int len)方法:将指定byte数组从off开始的len 个字节写入此输出流。

flush() 方法:完成输出并清空缓存区

close()方法:关闭输出流。

四。文件流:FileInputStream和FileOutPutStream

只提供字节的读取方法。

用File类创建一个文本对象:

File file =new File(“D:/1.txt”)

五。数据输入输出流:DataInputStream和DataOutputStream

使用数据输入输出流,读取一个数据时不必在关心这个数值应当是那种字节

六。字符流:Reader和Writer

字符流只用来处理文本数据 处理16位的字符

* 写入文件后必须要用flush()刷新。

* 用完流后记得要关闭流

* 使用流对象要抛出IO异常

* 定义文件路径时,可以用“/”或者“\\”。

* 在创建一个文件时,如果目录下有同名文件将被覆盖。

* 在读取文件时,必须保证该文件已存在,否则出异常

Reader的方法:

read()方法:从输入流中读取数据的下一个字符。返回0~255之间的int值、

read(byte[] b)方法 :从输入流中读取一定的字符长度

mark(int readlimit)方法 :做标记

reset()方法:返回标记位

close()方法:关闭资源

writer的方法:

write()方法:将指定的字符写入流中

write(byte [] b)方法: 将b个字符从指定的byte 数组写入此流

write(byte [] b, int off,int len)方法:将指定byte数组从off开始的len 个字符写入此输出流。

flush() 方法:完成输出并清空缓存区

close()方法:关闭输出流。

示例1:在硬盘上创建一个文件,并写入一些文字数据

class FireWriterDemo {  
    public static void main(String[] args) throws IOException {             //需要对IO异常进行处理   
  
        //创建一个FileWriter对象,该对象一被初始化就必须要明确被操作的文件。  
        //而且该文件会被创建到指定目录下。如果该目录有同名文件,那么该文件将被覆盖。  
  
        FileWriter fw = new FileWriter("F:\\1.txt");//目的是明确数据要存放的目的地。  
  
        //调用write的方法将字符串写到流中  
        fw.write("hello world!");  
      
        //刷新流对象缓冲中的数据,将数据刷到目的地中  
        fw.flush();  
  
        //关闭流资源,但是关闭之前会刷新一次内部缓冲中的数据。当我们结束输入时候,必须close();  
        fw.write("first_test");  
        fw.close();  
        //flush和close的区别:flush刷新后可以继续输入,close刷新后不能继续输入。  
  
    }  
}  

示例2:FileReader的reade()方法.

要求:用单个字符和字符数组进行分别读取

class FileReaderDemo {  
    public static void main(String[] args) {  
        characters();  
    }  
  
  
/*****************字符数组进行读取*********************/  
    private static void characters() {  
  
        try {  
  
            FileReader fr = new FileReader("Demo.txt");  
            char []  buf = new char[6];   
            //将Denmo中的文件读取到buf数组中。  
            int num = 0;      
            while((num = fr.read(buf))!=-1) {  
  
                //String(char[] value , int offest,int count) 分配一个新的String,包含从offest开始的count个字符  
                sop(new String(buf,0,num));  
            }  
            sop('\n');  
            fr.close();  
        }  
        catch (IOException e) {  
            sop(e.toString());  
        }  
    }  
  
  
  
  
  
  
/*****************单个字母读取*************************/  
    private static void singleReader() {  
          
        try {  
  
            //创建一个文件读取流对象,和指定名称的文件关联。  
            //要保证文件已经存在,否则会发生异常:FileNotFoundException  
            FileReader fr = new FileReader("Demo.txt");  
  
          
            //如何调用读取流对象的read方法?  
            //read()方法,一次读取一个字符,并且自动往下读。如果到达末尾则返回-1  
            int ch = 0;  
            while ((ch=fr.read())!=-1) {  
                sop((char)ch);  
            }  
            sop('\n');  
            fr.close();  
  
  
            /*int ch = fr.read(); 
            sop("ch=" + (char)ch); 

            int ch2 = fr.read(); 
            sop("ch2=" + (char)ch2); 

            //使用结束注意关闭流 
            fr.close(); */    
              
  
  
        }  
        catch (IOException e) {  
            sop(e.toString());  
        }  
      
    }  
  
  
/**********************Println************************/  
    private static void sop(Object obj) {  
        System.out.print(obj);  
    }  
  
}  

示例3:对已有文件的数据进行续写

import java.io.*;  
  
class  FileWriterDemo3 {  
    public static void main(String[] args) {  
          
        try {  
            //传递一个参数,代表不覆盖已有的数据。并在已有数据的末尾进行数据续写  
            FileWriter fw = new FileWriter("F:\\java_Demo\\day9_24\\demo.txt",true);  
            fw.write(" is charactor table?");  
            fw.close();  
        }  
        catch (IOException e) {  
            sop(e.toString());  
        }  
          
    }  
  
/**********************Println************************/  
    private static void sop(Object obj)  
    {  
        System.out.println(obj);  
    }  
}  

练习:

将F盘的一个文件复制到E盘。 

思考:

其实就是将F盘下的文件数据存储到D盘的一个文件中。

步骤:

1.在D盘创建一个文件,存储F盘中文件的数据。

2.定义读取流和F:盘文件关联。

3.通过不断读写完成数据存储。

4.关闭资源。

源码:

import java.io.*;  
import java.util.Scanner;  
  
class CopyText {  
    public static void main(String[] args) throws IOException {  
        sop("请输入要拷贝的文件的路径:");  
        Scanner in = new Scanner(System.in);  
        String source = in.next();  
        sop("请输入需要拷贝到那个位置的路径以及生成的文件名:");  
        String destination = in.next();  
        in.close();  
        CopyTextDemo(source,destination);  
  
    }  
  
/*****************文件Copy*********************/  
    private static void CopyTextDemo(String source,String destination) {  
  
        try {  
            FileWriter fw = new FileWriter(destination);  
            FileReader fr = new FileReader(source);  
            char []  buf = new char[1024];   
            //将Denmo中的文件读取到buf数组中。  
            int num = 0;      
            while((num = fr.read(buf))!=-1) {  
                               //String(char[] value , int offest,int count) 分配一个新的String,包含从offest开始的count个字符  
                fw.write(new String(buf,0,num));  
            }  
            fr.close();  
            fw.close();  
        }  
        catch (IOException e) {  
            sop(e.toString());  
        }  
    }  
  
  
  
/**********************Println************************/  
    private static void sop(Object obj) {  
        System.out.println(obj);  
    }  
}  

六,转换流:

InputStreamReader 将字节输入流转化成字符输入流

OutputStreamReader 将字节输出流转化成字符输出流

七,缓冲区:

1. 字符流的缓冲区:BufferedReader和BufferedWreiter

* 缓冲区的出现时为了提高流的操作效率而出现的.

* 需要被提高效率的流作为参数传递给缓冲区的构造函数

* 在缓冲区中封装了一个数组,存入数据后一次取出

BufferedReader示例:

读取流缓冲区提供了一个一次读一行的方法readline,方便对文本数据的获取。

readline()只返回回车符前面的字符,不返回回车符。如果是复制的话,必须加入newLine(),写入回车符

newLine()是java提供的多平台换行符写入方法。

class BufferedReaderDemo {  
    public static void main(String[] args)  throws IOException {  
  
        //创建一个字符读取流流对象,和文件关联  
        FileReader rw = new FileReader("buf.txt");  
  
        //只要将需要被提高效率的流作为参数传递给缓冲区的构造函数即可  
        BufferedReader brw = new BufferedReader(rw);  
  
          
        for(;;) {  
            String s = brw.readLine();  
            if(s==null) break;  
            System.out.println(s);  
        }  
          
        brw.close();//关闭输入流对象  
  
    }  
}  

BufferedWriter示例:

import java.io.*;  
  
  
class BufferedWriterDemo {  
    public static void main(String[] args)  throws IOException {  
  
        //创建一个字符写入流对象  
        FileWriter fw = new FileWriter("buf.txt");  
  
        //为了提高字符写入效率,加入了缓冲技术。  
        //只要将需要被提高效率的流作为参数传递给缓冲区的构造函数即可  
        BufferedWriter bfw = new BufferedWriter(fw);  
  
        //bfw.write("abc\r\nde");  
        //bfw.newLine();               这行代码等价于bfw.write("\r\n"),相当于一个跨平台的换行符  
        //用到缓冲区就必须要刷新  
        for(int x = 1; x < 5; x++) {  
            bfw.write("abc");  
            bfw.newLine();                  //java提供了一个跨平台的换行符newLine();  
            bfw.flush();  
        }  
  
  
  
        bfw.flush();                                                //刷新缓冲区  
        bfw.close();                                                //关闭缓冲区,但是必须要先刷新  
  
        //注意,关闭缓冲区就是在关闭缓冲中的流对象  
        fw.close();                                                 //关闭输入流对象  
  
    }  
}  

八,流操作的基本规律。  

一、两个明确:(明确体系)  
1. 明确源和目的  
    源:输入流  InputStream  Reader  
    目的:输出流  OutputStream Writer  
  
2. 操作的数据是否是纯文本  
    是: 字符流  
    否: 字节流  
二、明确体系后要明确具体使用的对象  
    通过设备区分:内存,硬盘,键盘  
    目的设备:内存,硬盘,控制台  
  
  
示例1:将一个文本文件中的数据存储到另一个文件中: 复制文件  
    一、明确体系  
        源:文件-->读取流-->(InputStream和Reader)  
        是否是文本:是-->Reader  
          
          
        目的:文件-->写入流-->(OutputStream Writer)  
        是否纯文本:是-->Writer  
      
    二、 明确设备  
        源:Reader  
            设备:硬盘上一个文本文件 --> 子类对象为:FileReader  
                FileReader fr = new FileReader("Goods.txt");  
              
            是否提高效率:是-->加入Reader中的缓冲区:BufferedReader  
                BufferedReader bufr = new BufferedReader(fr);  
                  
        目的:Writer  
            设备:键盘上一个文本文件 --> 子类对象:FileWriter  
                FileWriter fw = new FileWriter("goods1.txt");  
            是否提高效率:是-->加入Writer的缓冲区:BufferedWriter  
                BufferedWriter bufw = new BufferedWriter(fw);  
              
              
              
示例2:将一个图片文件数据复制到另一个文件中:复制文件  
    一、明确体系  
        源:文件-->读取流-->(InputStream和Reader)  
        是否是文本:否-->InputStream  
          
          
        目的:文件-->写入流-->(OutputStream Writer)  
        是否纯文本:否-->OutputStream  
      
    二、 明确设备  
        源:InputStream  
            设备:硬盘上一个媒体文件 --> 子类对象为:FileInputStream  
                FileInputStream fis = new FileInputStream("Goods.txt");  
              
            是否提高效率:是-->加入InputStream中的缓冲区:BufferedInputStream  
                BufferedInputStream bufi = new BufferedInputStream(fis);  
                  
        目的:OutputStream  
            设备:键盘上一个媒体文件 --> 子类对象:FileOutputStream  
                FileOutputStream fos = new FileOutputStream("goods1.txt");  
            是否提高效率:是-->加入OutputStream的缓冲区:BufferedOutputStream  
                BufferedOutputStream bufo = new BufferedOutputStream(fw);  
  
示例3:将键盘录入的数据保存到一个文本文件中  
    一、明确体系  
        源:键盘-->读取流-->(InputStream和Reader)  
        是否是文本:是-->Reader  
          
          
        目的:文件-->写入流-->(OutputStream Writer)  
        是否纯文本:是-->Writer  
      
    二、 明确设备  
        源:InputStream  
            设备:键盘 --> 对用对象为:System.in --> InputStream  
                为了操作方便,转成字符流Reader --> 使用Reader中的转换流:InputStreamReader  
                InputStreamReader isr = new InputStreamReader(System.in);  
              
            是否提高效率:是-->加入Reader中的缓冲区:BufferedReader  
                BufferedReader bufr = new BufferedReader(isr);  
                  
        目的:Writer  
            设备:键盘上一个文本文件 --> 子类对象:FileWriter  
                FileWriter fw = new FileWriter("goods1.txt");  
            是否提高效率:是-->加入Writer的缓冲区:BufferedWriter  
                BufferedWriter bufw = new BufferedWriter(fw);  

5.指定编码表(转换流可以指定编码表)

要求:用UTF-8编码存储一个文本文件

  1. import java.io.*;  
    public class IOStreamLaw {  
      
        /** 
         * @param args 
         */  
        public static void main(String[] args) throws IOException {  
                    //键盘的最常见写法  
                    BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in));  
                    BufferedWriter bufw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("goods1.txt"),"UTF-8"));  
                    String line = null;  
                    while((line=bufr.readLine())!=null){  
                        if("over".equals(line)) break;  
                        bufw.write(line.toUpperCase());  
                        bufw.newLine();  
                        bufw.flush();  
                    }  
                    bufr.close();  
        }  
      
      
    }  

八。格式化的输入输出。

stream 系列用来处理二进制数据

read write系列用来处理文本

判断方法:

九。流的应用

十。对象串行化

  对象的寿命通常随着生成该对象的程序的终止而终止。有时候,可能需要将对象的状态保存下来,在需要时再将对象恢复。我们把对象的这种能记录自己的状态以便将来再生的能力。叫作对象的持续性(persistence)。对象通过写出描述自己状态的数值来记录自己,这个过程叫对象的串行化



这篇关于java IO流 万字长文,建议收藏的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程