1:Java语言定义了许多类专门负责各种方式的输入或者输出,这些类都被放在java.io包中。其中,
所有输入流类都是抽象类InputStream(字节输入流),或者抽象类Reader(字符输入流)的子类;
而所有输出流都是抽象类OutputStream(字节输出流)或者Writer(字符输出流)的子类。
【首先需要明白的是:流是干什么的???(为了永久性的保存数据)
根据数据流向的不同分为输入流和输出流;
根据处理数据类型的不同分为字符流和字节流;
】
【然后需要明白的是输入模式和输出模式是谁流向谁:
InputStream(字节输入流)和Reader(字符输入流)通俗的理解都是读(read)的。
OutputStream(字节输出流)和Writer(字符输出流)通俗的理解都是写(writer)的。
】
最后下面搞清楚各种流的类型的该怎么用,谁包含谁,理清思路。
2:InputStream类是字节输入流的抽象类,是所有字节输入流的父类,InputStream类具有层次结构如下图所示;
3:java中的字符是Unicode编码的,是双字节的。InputStream是用来处理字节的,在处理字符文本时很不方便。Java为字符文本的输入提供了专门的一套类Reader。Reader类是字符输入流的抽象类,所有字符输入流的实现都是它的子类。
4:输出流OutputStream类是字节输出流的抽象类,此抽象类表示输出字节流的所有类的超类。
5:Writer类是字符输出流的抽象类,所有字符输出类的实现都是它的子类。
6:下面以一些字节输入输出流具体的案例操作(操作的时候认清自己使用的是字节流还是字符流):
注意:read()方法读取的是一个字节,为什么返回是int,而不是byte。
字节输入流可以操作任意类型的文件,比如图片音频等,这些文件底层都是以二进制形式的存储的,如果每次读取都返回byte,有可能在读到中间的时候遇到111111111;那么这11111111是byte类型的-1,我们的程序是遇到-1就会停止不读了,后面的数据就读不到了,所以在读取的时候用int类型接收,如果11111111会在其前面补上;24个0凑足4个字节,那么byte类型的-1就变成int类型的255了这样可以保证整个数据读完,而结束标记的-1就是int类型
FileInputStream的单个字节读取:
FileOutputStream的单个字节写入:
import java.io.FileInputStream; import java.io.FileOutputStream; //输出流 public class fos_demo { public static void main(String[] args) throws Exception { FileInputStream fis = new FileInputStream("a.txt"); FileOutputStream fos = new FileOutputStream("b.txt", true); //FileOutputStream()后面加true指文件后面可追加 int a = fis.read();//单个读取输入流字节 System.out.println(a); int b = fis.read(); System.out.println(b); int c = fis.read(); System.out.println(c); fos.write(97);//单个读出字节 fos.write(98); fos.write(99); fis.close();//关闭输出流 fos.close();//关闭输出流 } }
FileInputStream和FileOutputStream进行拷贝文本或者图片或者歌曲(以图片为例):
方法一:package IO; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; //拷贝图片 public class copy_demo { public static void main(String[] args) throws IOException { copy(); } public static void copy() throws IOException { FileInputStream fis = new FileInputStream("aaa.jpg"); FileOutputStream fos = new FileOutputStream("copy.jpg"); byte[] bytes = new byte[fis.available()];//将图片转为字节数组,这样会浪费空间 fis.read(bytes); fos.write(bytes); fis.close(); fos.close(); } }
方法二: package IO; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class copy_demo1 { public static void main(String[] args) throws IOException{ copy_2(); } public static void copy_2() throws IOException{ FileInputStream fis= new FileInputStream("aaa.jpg"); FileOutputStream fos = new FileOutputStream("copy1.jpg"); int b; while((b=fis.read())!=-1){ fos.write(b); } fis.close(); fos.close(); } }
FileInputStream和FileOutputStream定义小数组进行操作:
//拷贝图片 package IO; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class Array_copy { public static void main(String[] args) throws IOException { FileInputStream fis= new FileInputStream("aaa.jpg"); FileOutputStream fos= new FileOutputStream("copy3.jpg"); byte[] bytes = new byte[1024 * 8];//自定义字节大小 int len; while ((len=fis.read(bytes))!=-1){ fos.write(bytes,0,len); } fis.close(); fos.close(); } }
//进行读写操作 package IO; import java.io.FileInputStream; import java.io.IOException; public class Array_copy1 { public static void main(String[] args) throws IOException { test(); } public static void test() throws IOException{ FileInputStream fis = new FileInputStream("b.txt"); byte[] bytes = new byte[3];//自定义读取字节的个数 int len=fis.read(bytes); System.out.println(len); for(byte a:bytes){ System.out.println(a); } System.out.println("************"); int len1=fis.read(bytes);//没读完的接着读,依然是每次以上面自定义的读取的个数读 System.out.println(len1); for(byte b:bytes){ System.out.println(b); } fis.close(); } }
IO流(BufferedInputStream和BufferOutputStream拷贝)
* A:缓冲思想
* 字节流一次读写一个数组的速度明显比一次读写一个字节的速度快很多,这是加入了数组这样的缓冲区效果,java本身在设计的时候,也考虑到了这样的设计思想,所以提 供了字节缓冲区流。
* B.BufferedInputStream
* BufferedInputStream内置了一个缓冲区(数组), 从BufferedInputStream中读取一个字节时, BufferedInputStream会一次性从文件中读取8192个, 存在缓冲区中, 返回 给程序,程序再次读取时, 就不用找文件了, 直接从缓冲区中获取,直到缓冲区中所有的都被使用过, 才重新从文件中读取8192个。
* C.BufferedOutputStream
* BufferedOutputStream也内置了一个缓冲区(数组),程序向流中写出字节时, 不会直接写到文件, 先写到缓冲区中,直到缓冲区写满, BufferedOutputStream才会把缓冲区 中的数据一次性写到文件里。
package IO; import java.io.*; //Buffer 相当于缓冲池 输入输出的转化 public class Buffer_demo { public static void main(String[] args) throws IOException { BufferedInputStream bis = new BufferedInputStream(new FileInputStream("ren.jpg")); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("copy.jpg")); int len; while((len=bis.read())!=-1){ bos.write(len); } bis.close(); bos.close(); } }
注意:
IO流(字符流是否可以拷贝非纯文本的文件)
* 不可以拷贝非纯文本的文件
* 因为在读的时候会将字节转换为字符,在转换过程中,可能找不到对应的字符,就会用?代替,写出的时候会将字符转换成字节写出去
* 如果是?,直接写出,这样写出之后的文件就乱了,看不了了
原文地址:https://www.cnblogs.com/rfj123/p/10566209.html