一、字节输入流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的东西,只需要一百多毫秒。 应当使用第二种方式。 |