javaIO流中的字节字符流整理

总结:
File 类 仅能获取文件的属性数据或者是修改文件的属性数据而已,不能读取文件内容数据。
如果需要操作文件内容数据,那么就需要学习”IO流”技术

IO流类别:
1. 流向划分
输入流
输出流
什么时候使用输入流什么时候使用输出流?
以当前程序作为参照物,数据流入 则使用输入流, 数据流出则使用输出流。

  1. 处理单位:
    字节流:字节流就是用于读取文件的字节数据的,读取到的数据不会经过任何的处理。
    字符流: 读取到的字节数据还会帮你转换成你看得懂的字符数据,读取的是以字符作单位 的数据。 字符流 = 字节流+ 解码

1字节流

1.1 InputStream

输入字节流:
———|InputStream 抽象类 输入字节流的基类。
————| FileInputStream 读取文件数据 的输入字节流

使用FileInputStream 读取文件数据步骤:

  1. 找到目标文件

  2. 建立数据的输入通道

  3. 读取文件数据

1.1.1 常用的读取文件数据方式:使用循环配合缓冲 数组读取 能读取完一个文件数据,速度快

public static void read() throws IOException{
        //找到目标文件
        File file = new File("F:\\a.txt");
        //建立数据的通道
        FileInputStream fileInputStream= new FileInputStream(file);
        //读取数据
        byte[] buf = new byte[1024];   //缓冲字节数组的长度一般都是1024的倍数。      缓冲字节数组一般越大效率越高
        int length = 0 ; //记录本次读取的自己个数。 
        while((length = fileInputStream.read(buf))!=-1){
            System.out.print(new String(buf,0,length));
        }
        //关闭资源(释放资源文件)
        fileInputStream.close();    
    }

1.2 OutputStream

输出字节流:

——–| OutputStream 抽象类,所有输出字节字节流的父类。
————| FileOutputStream 向文件输出数据的输出字节流。

使用FileOutputStream步骤:
1. 找到目标文件
2. 建立数据的输出通道
3. 准备数据,把数据写出
4. 把字符串转成字节数组
5. 字节数组写出
6. 关闭资源
FileOutputStream要注意的细节:
1. new FileOutputStream 的时候,如果目标文件不存在,那么会先创建目标 文件,然后再写入。
2. new FileOutputStream(file) 如果目标文件已经存在,那么会先清空 目标文件的数据,然后再写入新的数据.
3. 写入数据的时候如果需要以追加的形式写入,那么需要使用new FileOutputStream(file,true) 这个构造函数。
4. 使用write(int b)方法的时候,虽然参数接受的一个int类型的数据,但是实际上只会把数据的低八位写出,其他24位丢弃。

00000000-00000000-00000001-10000000
write(byte[] b, int off, int len) 

1.2.1常用写出的三种方式

    //方式一: 先把数据转成字节数组然后再写出。
    public static void write1() throws IOException{
        //找到目标文件
        File file = new File("F:\\a.txt");
        //建立数据的输出通道
        FileOutputStream fileOutputStream = new FileOutputStream(file,true); //第二个参数为true时,写入文件数据就是以追加的形式写入的
        //准备数据, 把数据写出
        String str  = "\r\nhello world";
        //把字符串转成字节数组
        byte[] buf = str.getBytes();
        //把字节数组写出
        fileOutputStream.write(buf);
        //关闭资源
        fileOutputStream.close();
    }


  //方式二
public static void write2() throws IOException {
        // 找到目标文件
        File file = new File("F:\\a.txt");
        // 建立数据的输出通道
        FileOutputStream fileOutputStream = new FileOutputStream(file);
        String data = "abcd";
        byte[] buf = data.getBytes(); // 97 98 99 100
        fileOutputStream.write(buf, 0, 2); // 指定开始的索引值与字节个数写出。
        fileOutputStream.close();
    }

//方式三: 每次只能写 一个字节的数据 。 
    public static void write3() throws IOException{
        //找到目标文件
        File file = new File("f:\\a.txt");
        //建立数据的输出通道
        FileOutputStream fileOutputStream = new FileOutputStream(file);
        //把数据写出
        fileOutputStream.write('h');
        fileOutputStream.write('e');
        fileOutputStream.write('l');
        fileOutputStream.write('l');
        fileOutputStream.write('o');
        //关闭资源
        fileOutputStream.close();
    }

/*
4. 使用write(int b)方法的时候,虽然参数接受的一个int类型的数据,但是实际上只会把数据的低八位写出,其他24位丢弃。
00000000-00000000-00000001-10000000
*/

public static void writeTest() throws FileNotFoundException, IOException {
        File file = new File("F:\\b.txt");
        //建立数据输出通道
        FileOutputStream fileOutputStream = new FileOutputStream(file);
        //把数据写出
        fileOutputStream.write(384);
        //关闭资源
        fileOutputStream.close();
    }

1.3 字节流文件拷贝

File inFile = new File("F:\\美女\\1.mp3");
        File outFile = new File("E:\\拷贝.mp3");
        //建立数据通道
        FileInputStream fileInputStream = new FileInputStream(inFile);
        FileOutputStream fileOutputStream = new FileOutputStream(outFile);
        //建立缓冲字节数组,边读边写
        byte[] buf = new byte[1024];
        int length = 0 ; //用于记录每次读取的字节个数
        while((length=fileInputStream.read(buf))!=-1){   // 700   300
            fileOutputStream.write(buf,0,length);
        }
        //关闭资源(关闭资源的原则:先开后关,后开先关)
        fileOutputStream.close();
        fileInputStream.close();

1.4 字节流的异常处理

    //拷贝图片
    public static void copyImage(){
        FileInputStream fileInputStream = null;
        FileOutputStream fileOutputStream = null;
        try{
            //找到目标文件
            File inFile = new File("F:\\美女\\1.jpg");
            File outFile = new File("F:\\拷贝.jpg");
            //建立数据的输入输出通道
            fileInputStream = new FileInputStream(inFile);
            fileOutputStream = new FileOutputStream(outFile);
            //建立缓冲字节数组,边读边写
            byte[] buf = new byte[1024];
            int length = 0 ; 
            while((length = fileInputStream.read(buf))!=-1){
                fileOutputStream.write(buf,0,length);
            }
        }catch(IOException e){
            System.out.println("拷贝出错了...");
            throw new RuntimeException(e);
        //关闭资源的原则: 先开后关, 后开先关。
        }finally{
            try{
                if(fileOutputStream!=null){
                    //关闭资源
                    fileOutputStream.close();
                }
            }catch(IOException e){
                throw new RuntimeException(e);
            }finally{
                try{
                    if(fileInputStream!=null){
                        fileInputStream.close();
                    }
                }catch(IOException e){
                    throw new RuntimeException(e);
                }
            }
        }           
    }

1.5 字节缓冲流

使用FileInputStream读取文件数据的时候如何读取效率是最高?
使用字节数组作为缓冲区读取的效率是最高的。

1.5.1 输入字节缓冲流

我们知道使用缓冲字节数组读取文件的效率最高,sun也知道使用缓冲字节数组读取的效率高,这时候sun为了方便我们工作,编写一个缓冲输入字节流给我去使用。

缓冲输入字节流的作用: 提高我们读取文件数据的效率。

输入字节流的体系:
———-| InputStream 抽象类 所有输入字节流的基类
————–| FileInputStream 读取文件数据的输入字节流
————–|BufferedInputStream 缓冲输入字节流 该类的本质其实只是在内部维护了一个8kb的字节数组而已。 主要是为了提高我们的读取文件 的效率。

凡是缓冲流都没有读写文件的能力。

BuffereInputStream注意的事项:
1. BuffereInputStream 的close方法实际上关闭的就是你传递进去的FileInputStream对象。

    public static void readTest() throws  IOException {
        //第一步:找到目标文件
        File file = new File("F:\\a.txt");
        //第二步:建立文件与程序的输入通道
        FileInputStream fileInputStream = new FileInputStream(file);
        //第三部:建立缓冲输入字节流
        /*
            疑问: 为什么创建BufferedInputStream对象需要传入一个InputStream的对象呢?
                BufferedInputStream没有读取文件 数据的能力,但是又要读取文件的数据,这时候只能依赖一个具备
                读取文件数据能力的对象。            
         */
        BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
        //读取文件数据
        int content = 0; 
        /*
            疑问: BufferedInputStream 的read方法每次只是读取一个字节的数据,FileInputStream的read方法每次也是读取一个字节的数据
            那么为什么说BufferedInputStream提高了读取的效率呢?
InputStream流是指将字节序列从外设或外存传递到应用程序的流
BufferedInputStream流是指读取数据时,数据首先保存进入缓冲区,其后的操作直接在缓冲区中完成。
         */
        while((content = bufferedInputStream.read())!=-1){
            System.out.print((char)content);
        }   
        //关闭资源       实际上关的是inputStream 的close方法
        bufferedInputStream.close();
    }   这里写代码片

1.5.2 输出字节缓冲流

缓冲输出字节流: 为了提高写文件的效率。

———| OutputStream 抽象类, 所有输出字节流的基类。
————-| FileOutputStream 向文件写出数据的输出字节流对象。
————-| BufferedOutputStream 缓冲输出字节流, 为了提高写文件数据的效率。

BufferedOutputStream 需要注意的事项: BufferedInputStream

1. 使用BufferedOutputStream的write方法时候,数据其实是写入了BufferedOutputStream内部维护的字节数组中,只有你调用BufferedOutputStream的close方法或者是flush方法数据才会真正的写到硬盘上去或者内部维护的字节数组已经存储满数据了,这时候 数据才会写到硬盘上去。

2/. BufferedOutputStream 的close方法实际上关闭的就是你传入的OutputStream对象的close方法。
 //找到目标文件对象
        File file = new File("f:\\a.txt");
        //建立数据的输出通道
        FileOutputStream fileOutputStream = new FileOutputStream(file);
        //建立缓冲输出字节流
        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
        //写数据
        String data = "hello world";
        bufferedOutputStream.write(data.getBytes());        
//      bufferedOutputStream.flush(); //把缓冲字节数组的数据写到硬盘上去。
        bufferedOutputStream.close();   

1.5.3 使用缓冲输入输出字节流拷贝数据

public class CopyImage {
    public static void main(String[] args) throws IOException {
        long startTime = System.currentTimeMillis();
        //找到目标文件
        File inFile = new File("F:\\美女\\1.jpg");
        File outFile = new File("E:\\拷贝.jpg");
        //建立数据的输入输出通道
        FileInputStream fileInputStream = new FileInputStream(inFile);
        FileOutputStream fileOutputStream = new FileOutputStream(outFile);
        //建立缓冲输入输出字节流
        BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
        //边读边写
        int content = 0 ; 
        while((content = bufferedInputStream.read())!=-1){
            bufferedOutputStream.write(content);
//          bufferedOutputStream.flush();
        }
        //关闭资源
        bufferedOutputStream.close();
        bufferedInputStream.close();                
        long endTime = System.currentTimeMillis();
        System.out.println(endTime-startTime);      
    }

2 字符流

2.1 Reader

输入字符流:

———-| Reader 抽象类 所有输入字符流的基类。
—————-| FileReader 读取文件数据的输入字符流。

FileReader的 使用步骤:
1. 找到目标文件。

读文件的两种方式

    //方式二:使用缓冲字符数组读取文件的数据     推荐
    public static void readTest2() throws IOException{
        //找到目标文件
        File file = new File("F:\\Demo1.java");
        //建立数据的输入通道
        FileReader fileReader = new FileReader(file);
        //建立缓冲字符数组,读取文件的数据
        char[] buf = new char[1024];
        int length = 0; 
        while((length = fileReader.read(buf))!=-1){  // read(char[] buf) 读取到的字符数组存储到了字符数组中,返回了本次读取到的字符个数。 
            System.out.print(new String(buf,0,length));
        }
        //关闭资源
        fileReader.close();
    }

    //方式一:每次只会读取一个字符的数据
    public static void readTest() throws IOException{
        //找到目标对象
        File  file = new File("f:\\a.txt");
        //建立数据的输入通道
        FileReader fileReader = new FileReader(file);
        //读取文件数据
        int content= 0;
        while((content=fileReader.read())!=-1){   // FileReader的read()方法每次读取一个字符的数据,如果读到 了文件末尾返回-1表示。 
            System.out.print((char)content);
        }
        //关闭资源
        fileReader.close();
    }

2.2 writer

输出字符流 :

——–| Writer 抽象类 输出字符流的基类。
————| FileWriter 向文件写出数据输出字符流.

FileWriter 使用步骤: FileReader
1. 找到目标文件
2. 建立数据的输出通道
3. 写出数据
4. 关闭资源

FileWriter 要注意的事项:
1. new FileWriter(file)的时候 , 如果目标文件不存在,那么会创建目标文件对象, 如果目标文件已经存在了,那么则不再重新创建。
2. 使用new FileWriter(file) 这个构造方法的时候,默认是会先清空文本的数据,然后再写入新的数据。如果需要追加数据则需要使用 new FileWriter(file,true)这个构造方法。
3. 使用FileWriter的write方法的时候,数据是写入了FileWriter内部维护的字符数组中,如果需要把数据真正的写到硬盘上去,需要调用flush方法或者 是close方法或者是内部维护的字符数组已经满了,这时候也会写到硬盘上。

    public static void writerTest() throws IOException{
        //找到目标文件
        File  file = new File("F:\\a.txt");
        //建立数据 的输出通道
        FileWriter fileWriter = new FileWriter(file); //第二个参数为true的意义是指追加数据。
        //准备数据,把数据写出
        String data = "现在雨停了";
        fileWriter.write(data);     
        //刷新输出字符流
        fileWriter.flush();     
    }

2.3 输入输出字符流的拷贝数据

总结 :
需求:使用输入输出字符流拷贝java文件.
何时使用字符流:何时使用字节流:

  • 如果操作的是文本数据时,这时候就应该使用字符流。
  • 如果操作的是非文本数据时,这时候则应该使用字节流。 图片 、 视频 、 音频、 word
public class CopyJava {
    public static void main(String[] args) throws IOException {
        //找到目标文件
        File inFile =  new File("F:\\Demo1.java");
        File outFile = new File("E:\\Demo2.java");
        //建立数据 的输入输出通道
        FileReader fileReader = new FileReader(inFile);
        FileWriter fileWriter = new FileWriter(outFile);
        //边写边读      
        char[] buf = new char[1024];
        int length = 0 ; 
        while((length= fileReader.read(buf))!=-1){
            fileWriter.write(buf,0,length);
        }
        //关闭资源
        fileWriter.close();
        fileReader.close();
    }   
}

你可能感兴趣的:(java)