字节流:
import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.PrintStream; import org.junit.Test; /** * 2018年5月3日 上午10:02:16 * @author <a href="mailto:[email protected]">宋进宇</a> * 演示 字节 流 */ public class IOStreamDemo { //认识系统的 in 和 out @Test public void t1() throws IOException { //获得系统的输入流:InputStream InputStream in = System.in; //获得系统的输出流:PrintStream PrintStream out = System.out; //只有输入ctrl+z 才退出循环 while(in.available() != -1){ //因为系统输入输出是字节流 所以定义一个字节数据来接收输入 byte[] buf = new byte[16]; //记录每次读入的字节个数 int len = in.read( buf ); //输出从0到len 的内容 out.write( buf, 0, len ); } //关流应该在catch块后面的finally里面关 , //这里为了流程看起来不乱 就省略了。。。 in.close(); out.close(); } //从控制台输入内容,输出到文件中 @Test public void t2() throws IOException { //获得控制台输入流 InputStream in = System.in; //创建一个文件 File outFile = new File( "testIO_Files/fileIn.txt" ); //判断文件存不存在 if ( !outFile.exists() ) { //获取所需父文件夹 File dir = outFile.getParentFile(); //预防空指针 if ( dir != null ) { //如果文件不存在先把需要的父文件夹全部创建 dir.mkdirs(); } //再创建一个文件 outFile.createNewFile(); } //创建一个 文件输出流 FileOutputStream fOut = new FileOutputStream( outFile ); //定义一个缓冲数组 byte[] buf = new byte[32]; int len = -1; while( ( len = in.read( buf ) ) != -1 ){ //把每次输入的内容输出到文件中 fOut.write( buf, 0, len ); } //关流应该在catch块后面的finally里面关 , //这里为了流程看起来不乱 就省略了。。。 in.close(); fOut.close(); } //把文件中的内容输出到控制台显示 @Test public void t3() throws IOException { //获得打印流 PrintStream out = System.out; //使用上面测试的文件 File inFile = new File( "testIO_Files/fileIn.txt" ); //判断文件存不存在 if ( !inFile.exists() ) { //获取所需父文件夹 File dir = inFile.getParentFile(); //预防空指针 if ( dir != null ) { //如果文件不存在先把需要的父文件夹全部创建 dir.mkdirs(); } //再创建一个文件 inFile.createNewFile(); } //创建一个文件输入流 FileInputStream fIn = new FileInputStream( inFile ); byte[] buf = new byte[8]; int len = -1; while ( ( len = fIn.read( buf ) ) != -1 ) { //打印到控制台 out.write(buf, 0, len); } //关流应该在catch块后面的finally里面关 , //这里为了流程看起来不乱 就省略了。。。 fIn.close(); out.close(); } //测试 文件拷贝 @Test public void t4() throws IOException { //使用上面测试的文件 File inFile = new File( "testIO_Files/fileIn.txt" ); File outFile = new File( "testIO_Files/fileOut.txt" ); //判断文件存不存在 if ( !inFile.exists() ) { //获取所需父文件夹 File dir = inFile.getParentFile(); File dir2 = outFile.getParentFile(); //预防空指针 if ( dir != null ) { //如果文件不存在先把需要的父文件夹全部创建 dir.mkdirs(); } if ( dir2 != null ) { dir2.mkdirs(); } //再创建一个文件 inFile.createNewFile(); outFile.createNewFile(); } //创建一个文件输出流 FileInputStream fis = new FileInputStream(inFile); //创建一个文件输出流 FileOutputStream fos = new FileOutputStream(outFile); byte[] buf = new byte[16]; int len = -1; while ( ( len = fis.read( buf ) ) != -1 ) { fos.write( buf, 0, len ); } //先关fis fis.close(); //再关fos fos.close(); //简单说 就是 从数据输出的源头开始关,逐步关直到目标 } }
字符流:
import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import org.junit.Test; /** * 2018年5月3日 上午10:58:31 * @author <a href="mailto:[email protected]">宋进宇</a> * 演示 字符流 */ public class ReadWriteDemo { //通过控制台输入 输出到文件中 /* 通过观察文件内容可以发现 汉字 出现乱码问题了 * 原因:MyEclipse我设置的是UTF-8编码,一个汉字的是3个字节 * 而我定义的buf是8个字节,这时在第3个汉字时只取了2个字节 * 进行转换成字符串,于是就出现了乱码。 * 解决方法有两个:一是把buf定义足够大,但是不现实。不可取 * 另一个是采用转换流 具体看 转换流 演示 */ @Test public void t1() throws IOException { //获得输入流 InputStream in = System.in; //获得文件字符输出流 FileWriter fw = new FileWriter( "testIO_Files/fileWrite.txt" ); byte[] buf = new byte[8]; int len = -1; while( ( len = in.read( buf ) ) != -1 ){ //这里不能像字节流那样直接写进文件,需要转换 String str = new String( buf, 0, len); fw.write(str); } //关流 in.close(); fw.close(); } //通过单纯的字符流实现 文件拷贝 //只能拷贝跟运行环境编码相同的文件,如果编码不同就会出现 乱码 @Test public void t3() throws IOException { //被拷贝的文件直接采用 演示字节流中产生的文件 File inFile = new File( "testIO_Files/fileIn.txt" ); //创建一个文件字符输入流 FileReader fr = new FileReader( inFile ); //创建一个文件字符输出流 FileWriter fw = new FileWriter( "testIO_Files/fileWrite.txt" ); char[] cbuf = new char[16]; int len = -1; while ( ( len = fr.read( cbuf ) ) != -1 ) { fw.write( cbuf, 0, len ); } //关流 fr.close(); fw.close(); } }
缓冲流:
1)有buffer比没有更快;
2)buffer放在中间层包装比放在外层更快;
3)按行或按块操作 比 按字节或字符操作更快(用Object流操作的速度 比 字节字符方式 更快)
4)缓冲区要结合流才可以使用,在流的基础上对流的功能进行了增强。
import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.BufferedWriter; import java.io.DataInputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; import java.util.Scanner; import org.junit.Test; /** * 2018年5月3日 上午11:24:03 * @author <a href="mailto:[email protected]">宋进宇</a> * 演示 缓冲流 * 缓冲流其实就是一种装饰设计模式,对各种输入输出流进行功能强化 */ public class BufferedDemo { //给字节流 加缓冲 @Test public void t1() throws IOException { //创建一个字节缓冲输入流 BufferedInputStream bis = new BufferedInputStream( System.in ); //创建一个字节缓冲输出流 BufferedOutputStream bos = new BufferedOutputStream( System.out ); while ( bis.available() != -1 ) { byte[] buf = new byte[8]; int len = -1; len = bis.read(buf); bos.write( buf, 0, len ); } bis.close(); bos.close(); } //给字符流 加缓冲 @Test public void t2() throws IOException { //获取输入流 Scanner sc = new Scanner(System.in); //给文件字符流加缓冲 BufferedWriter bw = new BufferedWriter( new FileWriter( "testIO_Files/fileBuffered.txt" ) ); while( sc.hasNext() ) { String str = sc.nextLine(); bw.write( str ); bw.newLine(); } sc.close(); bw.close(); } //测试缓冲是否真的有加强普通流的能力 //首先顺便搞1M字节内容写到文件中 //再测试有没有加缓冲的读取速度 /* * 测试结果:加缓冲比不加缓冲速度快! * 缓冲加在离数据源越近越快! */ @Test public void t3() throws IOException{ FileOutputStream fos = new FileOutputStream( "testIO_Files/testBuff.txt" ); int i = 0; while(i<1024){ byte[] buf = new byte[1024]; for (int j = 0; j < buf.length; j++) { buf[j] = (byte) j; } fos.write(buf); i++; } fos.close(); ////////////////没有加缓冲///////////////////////// long t1 = System.currentTimeMillis(); DataInputStream df = new DataInputStream( new FileInputStream( "testIO_Files/testBuff.txt" ) ); byte[] buf = new byte[1024]; int len = -1; while( ( len = df.read( buf ) ) != -1 ){ System.out.println( new String( buf, 0, len ) ); } long t2 = System.currentTimeMillis(); df.close(); //////////////////没有加缓冲///////////////////////// ////////////////在最外层加缓冲////////////////////////// long t3 = System.currentTimeMillis(); BufferedInputStream bdf = new BufferedInputStream( new DataInputStream( new FileInputStream( "testIO_Files/testBuff.txt" ) ) ); buf = new byte[1024]; len = -1; while( ( len = bdf.read( buf ) ) != -1 ){ System.out.println( new String( buf ) ); } long t4 = System.currentTimeMillis(); bdf.close(); ////////////////在最外层加缓冲////////////////////////// ////////////////在中间加缓冲////////////////////////// long t5 = System.currentTimeMillis(); DataInputStream dbf = new DataInputStream( new BufferedInputStream( new FileInputStream( "testIO_Files/testBuff.txt" ) ) ); buf = new byte[1024]; len = -1; while( ( len = dbf.read( buf ) ) != -1 ){ System.out.println( new String( buf ) ); } long t6 = System.currentTimeMillis(); dbf.close(); ////////////////在最外层加缓冲////////////////////////// System.out.println( "不加缓冲:" + ( t2 - t1 ) ); System.out.println( "加在外层:" + ( t4 - t3 ) ); System.out.println( "加在中间:" + ( t6 - t5 ) ); } //测试字符缓冲流 @Test public void t4() throws IOException{ long t1 = System.currentTimeMillis(); BufferedReader br = new BufferedReader( new BufferedReader( new InputStreamReader( new FileInputStream( "testIO_Files/test.txt" ) ) ) ); String str = null; while ( ( str = br.readLine() ) != null ) { System.out.println( str ); } long t2 = System.currentTimeMillis(); br.close(); /////////////////四层嵌套/////////////////////////// long t3 = System.currentTimeMillis(); BufferedReader br2 = new BufferedReader( new InputStreamReader( new BufferedInputStream( new FileInputStream( "testIO_Files/test.txt" ) ) ) ); str = null; while ( ( str = br2.readLine() ) != null ) { System.out.println( str ); } long t4 = System.currentTimeMillis(); br2.close(); System.out.println(t2-t1); System.out.println(t4-t3); } }