IO(3)----字节输入流InputStream

版权声明:未经同意,严禁转载 https://blog.csdn.net/pengchengliu/article/details/82890136

一、字节输入流InputStream                                                                                                                点击此处返回总目录

二、FileInputStream类

三、案例:使用字节输入流和字节输出流,实现文件复制

一、字节输入流InputStream 

是所有字节输入流的超类。是个抽象类。

作用:读取任意文件,每次只读取1个字节。

常用的方法:

1. int read()                         //读取1个字节。返回的是读取到的字节。将读取的字节转成int返回(高三个字节补0)。【例1】

                                           //每调用一次read(),就会自动读取下一个字节。当读取到结尾再读时返回-1。【例2】【例3】

2. int read(byte[] b)             //读取一定量的字节,存储到数组b中。

                                           //每调用一次read(),就会自动读取下一批字节,放入到b中。

                                           //返回值表示成功读取了多少个字节。当读取到结尾再读时返回-1。【例4】【例5】

3. close()

InputStream是抽象类,需要使用子类来演示父类的方法。我们关注一下FileInputStream.

二、FileInputStream类

1)构造方法

作用:为这个流对象绑定数据源

1. FileInputStream(File file)                  //参数是File类型对象

2. FileInputStream(String name)          //参数是String类型对象

2)继承过来的方法演示

例1:使用read()读取1个字节。

package cn.itcast.demo04;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class Test {
    public static void main(String[] args) throws IOException {
        InputStream is = new FileInputStream("e:\\aaa.txt");         //aaa.txt中内容为"abc"
        int i = is.read();
        System.out.println(i);                                                         //97。
        System.out.println((char)i);                                                //a

        is.close();
    }
}

运行结果:(假设e:\\aaa.txt中内容为"abc")

97

a

分析:

读取了第一个字节"a",将字节转化成了int返回。所以输出了97。要想看真实内容,可以强转成char类型。

例2:每调用一次read(),就会自动读取下一个字节。当读到最后,再读的时候,返回-1。

package cn.itcast.demo04;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class Test {
    public static void main(String[] args) throws IOException {
        InputStream is = new FileInputStream("e:\\aaa.txt");                //aaa.txt中内容为"abc"
        int i = is.read();
        System.out.println((char)i);      //a
        i = is.read();
        System.out.println((char)i);      //b。每次调用read()时,会自动读取下一个字节。
        i = is.read();
        System.out.println((char)i);      //c
        i = is.read();
        System.out.println(i);               //-1。读完了再读就返回-1
        
        is.close();
    }
}

例3:循环读取文件

package cn.itcast.demo04;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class Test {
    public static void main(String[] args) throws IOException {
        InputStream is = new FileInputStream("e:\\aaa.txt");             //aaa.txt中内容为"abc"
        int i = 0;       
        while ((i = is.read()) !=-1){
            System.out.print((char)i);
        }
        
        is.close();
    }
}

运行结果:

abc

例4:

package cn.itcast.demo05;

import java.io.FileInputStream;
import java.io.IOException;

public class Test {
    public static void main(String[] args) throws IOException{
        FileInputStream fos = new FileInputStream("e:\\aaa.txt");               //文件的内容为"abcde"
        byte[] b = new byte[2];    //创建数组,能放两个byte.


        int i = fos.read(b);
        System.out.println(i);                         //2     成功读取2个,读到"ab",放入到b中。
        System.out.println(new String(b));     //ab   b中的内容为"ab",也可以用遍历查看b的内容。
        
        i= fos.read(b);
        System.out.println(i);                         //2      有读了两个,放到了b中。
        System.out.println(new String(b));     //cd
        
        i= fos.read(b);
        System.out.println(i);                         //1       只成功读取了1个,放到了b中。
        System.out.println(new String(b));     //ed     覆盖掉了b中的第一个,所以显示ed
        
        i= fos.read(b);
        System.out.println(i);                         //-1      显示-1,说明结束了。
        System.out.println(new String(b));     //ed     数组不变。还是上一次的值。
        
        fos.close();
    }
}

例5:循环读取文件的标准代码。

package cn.itcast.demo06;

import java.io.FileInputStream;
import java.io.IOException;

public class Test {
    public static void main(String[] args) throws IOException {
        FileInputStream fis = new FileInputStream("e:\\aaa.txt");
        byte[] b = new byte[1024];        //这个地方写多少都不合适,一般写1024或者他的整数倍。
        
        int len =0;
        //读取文件的标准代码,就这么两行。
        if( (len = fis.read(b))!=-1){
                System.out.print(new String(b,0,len));    //也可以遍历
        }
        
        fis.close();
    }
}

三、案例:使用字节输入流和字节输出流,实现文件复制

1. 要求

有一个文件c:\\a.txt,作为数据源。要求:

1.采用IO流技术,进行文件复制,将c:\\a.txt复制到d盘下。

2.增加异常处理的代码。

2. 原理

复制就是把一个文件中的内容放入到另一个文件中,可以使用一个字节输入流读文件,然后通过一个字节输出流写文件。

3. 实现

实现方式一:通过read()、write(int b)一个字节一个字节地传输。

package cn.itcast.demo07;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class Test {
    public static void main(String[] args) {
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try{
            fis = new FileInputStream("d:\\a.txt");
            fos = new FileOutputStream("e:\\a.txt");
            int i = 0;
            while((i = fis.read())!=-1){
                fos.write(i);
            }
        }catch(IOException e){
            e.printStackTrace();
            throw new RuntimeException("复制失败");
        }finally{
            try{
                if (fos!=null)                                                            //先关谁都可以。好像有个不成文的约定:先开后关,后开先关。
                    fos.close();
            }catch(IOException e){
                throw new RuntimeException("资源关闭失败");
            }finally{                                                                        //只有在finally中嵌套处理,才能保证fos.close()和fis.close()都执行。
                try{
                    if(fis!=null)
                        fis.close();
                }catch(IOException e){
                    throw new RuntimeException("资源打开失败");
                }
            }
        }
        
    }
}

这种方式可以传输任意的文件,但是缺点就是慢。比如4M的文件,有4*1024*1024个字节,需要循环400多万次。效率很低。

方式二:采用数组的方式来传输

package cn.itcast.demo08;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class Test {
    public static void main(String[] args) {
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try{
            fis = new FileInputStream("d:\\a.exe");
            fos = new FileOutputStream("e:\\a.exe");
            
            byte[] b = new byte[1024];
            int len = 0;
            while((len = fis.read(b))!=-1){
                fos.write(b, 0, len);
            }
        }catch(IOException e){
            e.printStackTrace();
            throw new RuntimeException("复制失败");
        }finally{
            try{
                if(fos !=null)
                    fos.close();
            }catch(IOException e){
                throw new RuntimeException("资源关闭失败");
            }finally{
                try{
                    if(fis !=null)
                        fis.close();
                }catch(IOException e){
                    throw new RuntimeException("资源关闭失败");
                }
            }
        }
    }
}

第二种方式很快,传输50M的东西,只需要一百多毫秒。

应当使用第二种方式。

猜你喜欢

转载自blog.csdn.net/pengchengliu/article/details/82890136