IO流用来处理设备之间的数据传输
Java对数据的操作是通过流的方式
Java用于操作流的类都在IO包中
流按流向分为两种:输入流,输出流。
流按操作类型分为两种
字节流:字节流可以操作任何数据,因为在计算机中任何数据都是以字节的形式存储的字符流:字符流只能操作纯字符数据,比较方便
IO常用父类
字节流的抽象父类
InputStreamOutputStream
字符流的抽象父类
ReaderWriter
IO程序书写
使用前,导入IO包中的类使用时,进行IO异常处理使用后,释放资源
2.FileInputStream
由于InputStream是抽象的,不能直接创建对象,所以先以它的子类FileInputStream为例学习IO相关知识
read方法
返回值是int,从此输入流中读取一个数据字节,到达流的末尾没有字节了返回-1
public static void main(string[] args)throws IOException{ FileInputStream fis= new FileInputStream("xxx,txt"); //创建流对象 int x =fis.read(); //从硬盘上读取一个字节 System.out.printin(x); int y =fis.read(); System.out.println(y); int z= fis.read(); System.out.printin(z); int a= fis.read(); System.out.println(a); int b= fis.read(); System.out.println(b); fis.close (); //关流释放资源 }
其中xxx.txt中的内容是:abc
所以上面代码的输出结果是:97
98
99
-1
-1
上面的代码可以由循环来实现:
FileInputStream fis= new FileInputStream("xxx.txt"); //创建一个文件输入流对象,并关联xxx.txt int b; //定义变量,记录每次读到的字节 while((b= fis.read()!=-1){ //将每次读到的字节赋值给b并判断是否是-1 System. out. println (b); //打印每一个字节 } fis.close(); //关闭流释放资源
思考:read()方法读取的是一个字节,为什么返回是int,而不是byte?
因为字节输入流可以操作任意类型的文件,比如图片音频等,这些文件底层都是以二进制形式的存储的,如果每次读取都返回byte,有可能在读到中间的时候遇到11111111。那么这11111111是byte类型的-1,我们的程序是遇到-1就会停止不读了,后面的数据就读不到了,所以在读取的时候用int类型接收,如果遇见11111111会在其前面补上24个0凑足4个字节,那么byte类型的-1就变成int类型的255了,这样可以保证整个数据读完,而结束标记的-1就是int类型。
3.FileOutputStream
write方法
public static void main(string[] args)throws IOException{ FileOutputStream fos= new FileOutputStream("yyy,txt"); //创建字节输出流对象, //如果没有就自动创建一个yyy.txt出来 fos.write(97); //虽然写的是一个int数,但是到文件上的是一个字节,会自动去除前3个8位 fos.write(98); fos.write(99); fos.close(); //关流释放资源 }
FileOutputStream在创建对象的时候,如果没有这个文件会自动创建,如果有这个文件,就会先将文件清空,如果向续写这个文件,要在FileOutputStream的构造方法中传入第二个参数true来实现
FileOutputStream fos= new FileOutputStream("yyy,txt",true);
4.图片的拷贝
public static void main(string[] args)throws IOException{ FileInputStream fis= new FileInputStream("aa.jpg"); //创建输入流对象,关联aa.jpg FileOutputStream fos= new FileOutputStream("copy.jpg"); //创建字节输出流对象,关联copy.jpg int b; //定义变量,记录每次读到的字节 while((b= fis.read()!=-1){ //将每次读到的字节赋值给b并判断是否是-1 fos.write(b); //将每一个字节写出 } fis.close(); fos.close(); }
上面的拷贝是逐个字节拷贝,效率很慢 ;下面介绍一些方法,让拷贝更加效率,也是以后常用的
int read(byte[] b):一次读取一个字节数组
write(byte [] b ):一次写出一个字节数组
write(byte [] b,int off,int len):写出有效个字节个数
public static void main(string[] args)throws IOException{ FileInputStream fis= new FileInputStream("xxx.txt"); //创建输入流对象,关联xxx.txt FileOutputStream fos= new FileOutputStream("yyy.txt"); //创建字节输出流对象,关联yyy.txt byte [] arr = new byte[1024*8]; int len ; while((len= fis.read(arr)!=-1){ //将每次读到的字节数组赋值给len并判断是否是-1 fos.write(arr,0,len); //将读到的字节数组的有效字节写出 } fis.close(); fos.close(); }
上面的arr的大小最好定义为1024的整数倍。
上面的拷贝代码可以说是IO流的核心了,要深刻理解