博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Java学习之路(十二):IO流
阅读量:4972 次
发布时间:2019-06-12

本文共 7099 字,大约阅读时间需要 23 分钟。

IO流的概述及其分类

  • IO流用来处理设备之间的数据传输,Java对数据的操作是通过流的方式
  • Java用于操作流的类都在IO包中

流按流向分为两种:输入流(读写数据)     输出流(写数据)

流按操作类型分为两种:

  • 字节流:字节流可以操作任何数据,因为在计算机中任何数据都是以字节的形式存储的
  • 字符流:字符流只能操作纯字符数据,比较方便

常用的IO流的类

字节流的抽象父类:InputStream     OutputStream

字符流的抽象方法:Reader   Writer

InputStream实现类FileInputStream

InputStream是抽象类,表示字节输入流

FileInputStream从文件系统中的某个文件中获得输入字节。FileInputStream用于读取图像数据之类的原始字节流。要读取字符流,就要用FileReader

构造方法:

  • FileInputStream(File file)
  • FileInputStream(String name)

FileInputStream的构造方法可以传一个File对象,也可以传一个字符串路径

成员方法:

  • int read()   从此输入流中读取到一个数据字节

案例:读取一个txt文件数据

package null08031628;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;public class Demo01 {    public static void main(String[] args) throws IOException {        // TODO Auto-generated method stub        File file = new File("C:/Users/Administrator/Desktop/baiduyunpan.txt");        FileInputStream fis = new FileInputStream(file);        int i = 0;        while((i = fis.read()) != -1){            System.out.println(i);        }
     fis.close();
} }

 

OutputStream实现类FileOutputStream文件输出流

文件输出流就是用于将数据写入File的输出流

案例:从一个文件读入数据写入另一个文件package null08031638;import java.io.File;

import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;public class Demo01 {    public static void main(String[] args) throws IOException {        // TODO Auto-generated method stub        File filein = new File("C:/Users/Administrator/Desktop/baiduyunpan.txt");                InputStream fis = new FileInputStream(filein);   //创建一个输入流                File fileout = new File("C:/Users/Administrator/Desktop/baiduyunpan-2.txt");                OutputStream fos = new FileOutputStream(fileout);   //创建一个输出流                int i = 0;        while((i=fis.read())!=-1){            fos.write(i);        }      fos.close();      fis.close();     }}

 

通过available()方法,进行字节数组拷贝(错误的,不推荐的,如果文件超级大怎么办?)

package null08031700;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;public class Demo01 {    public static void main(String[] args) throws IOException {        // TODO Auto-generated method stub        FileInputStream input = new FileInputStream("C:/Users/Administrator/Desktop/baiduyunpan.txt");                FileOutputStream out = new FileOutputStream("C:/Users/Administrator/Desktop/baiduyunpan-3.txt");                byte[] bs = new byte[input.available()];//定义一个文件输入流那么大的字节数组        input.read(bs); //一次性将数据写入到字节数组中                out.write(bs); //一次性将文件写入        input.close();        out.close();                            }}

 

自定义一个大小的数组,进行一个流的读写(正确的方法)

package null08031707;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;public class Demo01 {    public static void main(String[] args) throws IOException {        // TODO Auto-generated method stub        FileInputStream input = new FileInputStream("C:/Users/Administrator/Desktop/baiduyunpan.txt");                FileOutputStream out = new FileOutputStream("C:/Users/Administrator/Desktop/baiduyunpan-3.txt");                byte[] bs = new byte[8*1024];                int i = 0;        while((i=input.read(bs))!=-1){            out.write(i);        }        out.close();        input.close();            }}

 

通过字节数组的方法操作流,其实就是相当于是创建了一个缓冲区

自带缓冲区的实现类BufferedInputStream和BufferedOutputStream

BufferedInputStream

  • 内置了一个缓冲区(就是之前定义的那个数组)
  • 从BufferedInputStream中读取一个字节时,BufferedInputStream会一次性的读入8192个,放在缓冲区,在返回给程序
  • 程序再次读取时,就不会再从文件中取了,直接从缓冲区获取
  • 知道缓冲区中的所有都被用过了,BufferedInputStream才重新从文件中读取8192个

BufferedOutputStream

  • 内置了一个缓冲区(数组)
  • 程序向流中写入字节时,不会直接写到文件,而是先写入缓冲区当中
  • 知道缓冲区写满,BufferedOutputStream才会把缓冲区中的数据一次性写入文件

一个小小的例子:

package null08031732;import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;public class Demo01 {    public static void main(String[] args) throws IOException {        // TODO Auto-generated method stub        FileInputStream fis = new FileInputStream("C:/Users/Administrator/Desktop/baiduyunpan.txt");        BufferedInputStream bis = new BufferedInputStream(fis);                FileOutputStream fos = new FileOutputStream("C:/Users/Administrator/Desktop/baiduyunpan-4.txt");        BufferedOutputStream bos = new BufferedOutputStream(fos);                int i;        while((i=bis.read())!=-1){            bos.write(i);        }        bis.close();        bos.close();    }}

 

带Buffered的流和自己写的字节数组缓冲对比

  • 字节写的数组在速度上回略胜一筹,因为自己写的读和写的操作都是在同一个数组之中
  • 而Buffered操作的是两个数组,所以效率低于一个的

BufferedOutputStream中的一些方法

  • flush()方法:用来刷新缓冲区,刷新后就可以再次写入了
  • close()方法:关闭流,而且在关闭前后会刷新一次缓冲区

补充 

字节流读写中文时乱码的问题

字节流读取中文:

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

字节流写入中文的问题:

  • 字节流直接操作的字节,所以写入中文的时候必须将字符串转换成字节数组
  • 写出回车换行write("\r\n".getBytes())

流的标准处理异常代码1.6版本前

package null08041019;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;public class Demo01 {    public static void main(String[] args) throws IOException {        // TODO Auto-generated method stub        FileInputStream fis = null;        FileOutputStream fos = null;                try{            fis = new FileInputStream("");            fos = new FileOutputStream("");                        int b;            while((b=fis.read())!=-1){                fos.write(b);            }        }finally{            try{                fis.close();            }finally{                fos.close();            }        }    }}

 

流的处理1.7版本

package null08041024;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;public class Demo01 {    public static void main(String[] args) throws IOException {        // TODO Auto-generated method stub        try(            //写在括号中的代码,执行完成后,会自动调用对象的close方法            //能写在括号中的代码的类一定是要继承AutoCloseable接口的类            FileInputStream fis = new FileInputStream("");            FileOutputStream fos = new FileOutputStream("");                        ){            int i;            while((i=fis.read())!=-1){                fos.write(i);            }        }    }}

一个图片加密的例子:

package null08041031;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.util.Scanner;public class Demo01 {    public static void main(String[] args) throws IOException {        Scanner sc = new Scanner(System.in);         System.out.println("请将图片放到和此文件的同级目录下");        System.out.println("请输入要加密的文件名:");        String fileName = sc.nextLine();        System.out.println("请输入加密后的文件名:");        String endFileName = sc.nextLine();        System.out.println("请输入密码:");        String pwd = sc.nextLine();        int pwdInt = Integer.parseInt(pwd);                try(            FileInputStream fis = new FileInputStream(fileName);            FileOutputStream fos = new FileOutputStream(endFileName);            ){            int i;            while((i=fis.read())!=-1){                fos.write(i^pwdInt);            }        }finally{            System.out.println("加密结束");        }    }}
代码

 

转载于:https://www.cnblogs.com/smiling-crying/p/9404965.html

你可能感兴趣的文章
DevExpress的Web控件汉化方法
查看>>
js中escape,encodeURI,encodeURIComponent 区别(转)
查看>>
结对编程项目-四则运算整体总结
查看>>
Android studio怎么修改文件名
查看>>
sass学习笔记-安装
查看>>
多缓存并存
查看>>
Flask (二) cookie 与 session 模型
查看>>
修改添加网址的教程文件名
查看>>
hdu 1045:Fire Net(DFS经典题)
查看>>
[BZOJ 1017][JSOI2008]魔兽地图DotR(树形Dp)
查看>>
裁剪图片
查看>>
数据结构实习 problem L 由二叉树的中序层序重建二叉树
查看>>
VS中展开和折叠代码
查看>>
如何确定VS编译器版本
查看>>
设置PL/SQL 快捷键
查看>>
个人阅读作业7
查看>>
转载:深入浅出Zookeeper
查看>>
GMA Round 1 新程序
查看>>
node anyproxy ssi简易支持
查看>>
编译预处理指令:文件包含指令、宏定义指令、条件编译指令
查看>>