IO流(FileInputStream, BufferedInputStream)字节流与 IO 异常处理——Java基础

1. FileInputStream :读取文件数据的输入字节流
字节流: 字节流读取的都是文件中的二进制数据,读取到二进制数据不会经过任何处理
字符流: 读取的数据以字符为单位,也是读取二进制数据,但是会把二进制数据转化成我们能识别的数据。

                字符流 = 字节流 + 解码

 使用FileInputStream 读取文件数据的步骤:
        1.  找到目标文件
        2.  建立数据的输入通道     
        3.  读取文件的数据

        4.  关闭资源   

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class test_1 {	
	public static void main(String[] args) throws IOException  {   		
	//	readtxt();
	//	readtxt2();
	//	readtxt3();
		readtxt4();
	}	
	
//  方式4 : 使用缓冲数组配合循环一起读取
	public static void readtxt4() throws IOException {
		long startime = System.currentTimeMillis();
	    File file = new File("C:\\Users\\fzx\\Desktop\\picture\\25.jpg");
		FileInputStream fileInputStream = new FileInputStream(file);
	
		int  flag = 0;	
		byte[] buf = new byte[1024*3];      //  缓冲数组的长度一般是1024的倍数,缓冲数组越大,效率越高
		while((flag = fileInputStream.read(buf) ) != -1) {			
			System.out.println(new String(buf, 0, flag));		
		}
		fileInputStream.close();
		long endtime = System.currentTimeMillis();
		System.out.println("读取的时间是: " + (endtime-startime));    //  3176 S
	}
	
// 方式3 : 使用缓冲数组读取, 缺点: 还是无法读取完整!!!!!
	public static void readtxt3() throws IOException {
	    File file = new File("J:\\a.txt");
	    FileInputStream fileInputStream = new FileInputStream(file);
	
		byte[] buf = new byte[4];     //  建立缓冲数组,读取文件数据
		int length = fileInputStream.read(buf);   //数据读取到字节数组中了,而read()返回的是本次读取了几个字节数据		
	        String content = new String(buf,0,length);    	// 字节数组构建一个字符串
		System.out.println(content);
		fileInputStream.close();
	}
			
//  方式2: 使用循环读取文件的数据
	public  static void readtxt2() throws IOException {
		long startime = System.currentTimeMillis();
	        File file = new File("C:\\Users\\fzx\\Desktop\\picture\\25.jpg");
		FileInputStream fileInputStream = new FileInputStream(file);
		int flag = 0;    //   如果因为已经到达文件末尾而没有更多的数据,则返回 -1。
		
		while((flag = fileInputStream.read() ) != -1) {			
			System.out.print((char)flag);	
		}
		fileInputStream.close();	
		long endtime = System.currentTimeMillis();
		System.out.println("读取的时间是: " + (endtime-startime));   // 7648 S
	}
	
//  方式1:    缺点:  无法完整读取完
	public static void readtxt() throws IOException{	
		File file = new File("J:\\a.txt");   	//  1. 找到目标文件
		FileInputStream fileInputStream = new FileInputStream(file);   	//  建立管道流
		int content = fileInputStream.read();  // 读取文件中的数据, 读取一个字节的数据	
		System.out.println("读到的是:  " + (char)content);
		fileInputStream.close();   	//  关闭资源, 实际上是释放资源
	}
}	
 *   问题1: 读取完不关闭资源,有什么影响???   其他程序无法对该资源进行其他操作  !!!!

 *   问题二:    缓冲数组覆盖的方式,,还是清除?  

2.  FileOutputStream
 注意的事项:
 *        1.  如果目标文件不存在,则会在FileOutputStream时自动创建该文件;
 *        2.  如果目标文件已经存在,会先清空目标文件中的数据,然后写入数据
 *        3.  如果在要原始数据追加,需要使用new FileOutputStream(file,true) 构造函数

 *        4.  write()方法写数据的时候,虽然接收的是一个int类型的数据,但是真正写出只是一个字节的数据, 只是把低8位的二进制数据写出,其他24位数据全部丢弃

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

public class test_1 {	
	public static void main(String[] args) throws IOException {   		  
		writetxt_1();
	}	
	public static void writetxt_1() throws IOException {
		File file = new File("J:/a.txt");
		FileOutputStream fileOutputStream = new FileOutputStream(file);
		String data = "abcdef";	
		byte[] buf = data.getBytes();    //  字符串转换成字节数组
		fileOutputStream.write(buf, 0, 2);    //  从指定字节数组的指定索引值开始写,2: 写出两个字节
		fileOutputStream.close();
	}
}	

应用:   复制一张图片  (复制:读取 与 写入

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class test_1 {	
	public static void main(String[] args) throws IOException {   		  
		File file = new File("C:\\Users\\fzx\\Desktop\\picture\\2.jpg");
		FileInputStream fileInputStream =new FileInputStream(file);
		File file2 = new File("J:/a.jpg");
	// 每创建一个 FileOutputStream 的时候,默认情况下FileOutputStream指针指向文件的开始位置。 每写一次,指针都会相应移动
		FileOutputStream fileOutputStream = new FileOutputStream(file2);
		
		int length = 0;
		byte[] buf = new byte[1024];
		while ((length = fileInputStream.read(buf))!=-1) {	//  边读边写				
			 fileOutputStream.write(buf, 0, length);	
		}	 
		fileOutputStream.close();   //  关闭资源原则: 先关闭后关,后开先关!!!!!  
		fileInputStream.close();
	}	
}
3.  IO 异常处理

        //  首先要阻止后面的代码执行return,  或者 throw ,而且需要通知调用者这里出错了
// return ;       这个可以阻止后面的代码执行,但是异常信息显示不了
// throw e ;     方法必须声明, 而且调用者 需要try{}catch{}
//  把IOException 传递给  RuntimeException 包装一层,然后再抛出,目的是为了让调用者使用变得灵活,方法不需要声明,调用者想处理或者不处理;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class test_1 {	
	public static void main(String[] args) throws IOException {   		  
		copeimage();
	}		
	public static void copeimage() {
		FileInputStream fileInputStream = null;
		FileOutputStream fileOutputStream  = null;
		try {			
			File file = new File("C:\\Users\\fzx\\Desktop\\picture\\2.jpg");
			fileInputStream =new FileInputStream(file);
			File file2 = new File("J:/a.jpg");
			fileOutputStream = new FileOutputStream(file2);
			
			int length = 0;
			byte[] buf = new byte[1024];
			while ((length = fileInputStream.read(buf))!=-1) {					
				 fileOutputStream.write(buf, 0, length);	
			}	 						
		} catch (IOException e) {
			System.out.println("拷贝图片失败");
			throw new RuntimeException(e);	  //  第一个 RuntimeException			
		}finally {
			try {
				if(fileOutputStream !=null) {
					fileOutputStream.close(); // 执行失败,后面的fileInputStream.close()则没机会执行
					System.out.println("关闭输出流成功");
				}		
			} catch (Exception e2) {
			 System.out.println("关闭输出流资源失败");
			 throw new RuntimeException(e2);     //   第二个 RuntimeException
		}finally {
			try {
				if(fileInputStream !=null) {
					fileInputStream.close();
					System.out.println("关闭输入流成功");
				}				
			} catch (Exception e3) {
			 System.out.println("关闭输入流资源失败");
			 throw new RuntimeException(e3);      //  第三个 RuntimeException
		}						
	  }											
	}		
  }
}
****************************************************************************************************
Exception in thread "main" 读取文件失败
java.lang.RuntimeException: java.io.FileNotFoundException: J:\aaaaa.txt (系统找不到指定的文件。)
	at test.test_1.test_1.read(test_1.java:43)
	at test.test_1.test_1.main(test_1.java:18)
Caused by: java.io.FileNotFoundException: J:\aaaaa.txt (系统找不到指定的文件。)
	at java.base/java.io.FileInputStream.open0(Native Method)
	at java.base/java.io.FileInputStream.open(Unknown Source)
	at java.base/java.io.FileInputStream.<init>(Unknown Source)
	at test.test_1.test_1.read(test_1.java:27)
	... 1 more
4.  BufferedInputStream:  缓冲输入字节流
 *   输入字节流体系:
 *      InputStream  输入字节流的基类。 抽象
 *             FileInputStream  读取文件数据的输入字节流
 *             BufferedInputStream  缓冲输入字节流    该类内部只不过是 维护了一个8kb的字节数组    
源码: 
public synchronized int read() throws IOException {
        if (pos >= count) {
            fill();
            if (pos >= count)
                return -1;
        }
        return getBufIfOpen()[pos++] & 0xff;
    }     
     private byte[] getBufIfOpen() throws IOException {
        byte[] buffer = buf;
        if (buffer == null)
            throw new IOException("Stream closed");
        return buffer;
    }    
 *    注意: 凡是缓冲流都不具备读写文件的能力,自己创建数组感觉更好!!!!!    
    //  为什么创建 BufferedInputStream 要传递   fileInputStream
//  BufferedInputStream 本身不具备读文件的能力,所以需要借助  fileInputStream 
 *    使用 BufferedInputStream 步骤:
 *      找到目标文件;  建立数据的输入通道;  建立缓冲输入字节流;  关闭资源

、、、、

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class test_1 {	
	public static void main(String[] args) throws IOException  {   		
		readtxt_2();			
  }
// bufferedInputStream  读取进行对比
	public static void readtxt_2() throws IOException {
	    File file = new File("J:\\a.txt");
	    FileInputStream fileInputStream = new FileInputStream(file);
	    BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
	    int content = 0;

	    while ( (content = bufferedInputStream.read() ) !=-1) {
			System.out.println((char)content);			
		}
	    bufferedInputStream.close();   // 调用 bufferedInputStream 的 close()方法实际上是关闭fileInputStream  
	}
//  fileInputStream 读取进行对比
	public static void readtxt() throws IOException {
		File file = new File("J:/a.txt");
		FileInputStream fileInputStream = new FileInputStream(file);
		byte[] buf = new byte[1024];
		int length = 0;
		while((length = fileInputStream.read(buf)) !=-1) {
			System.out.println(new String(buf, 0, length));			
		}
		fileInputStream.close();		
	}
}

//  bufferedInputStream 和  fileInputStream 都是每次读一个字节,为什么bufferedInputStream效率高 

5. BufferedOutputSream  缓冲输出字节流
/*   输出字节流
 *      OutputStream    所有输出字节流的基类,  抽象类
 *             FileOutputSream  
 *             BufferedOutputSream    缓冲输出字节流   内部维护一个8KB的字节流          
 *   注意事项:
 *      1. 使用BufferedOutputSream写数据的时候,它write()方法是先把数据写到它内部维护的字节数组中
 *      2. 如果要将数据写到硬盘,则需要调用flush()方法或者close()方法,或者内部维护的字节数组已经填满数据的时候
 */
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

public class test_1 {	
	public static void main(String[] args) throws IOException {   		
		File file = new File("J:/a.txt");
		FileOutputStream fileOutputStream = new FileOutputStream(file);
		BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
		bufferedOutputStream.write("\r\n付祖贤女侠".getBytes());
	//	bufferedOutputStream.flush();
		bufferedOutputStream.close();		
	}
}

应用: 用缓冲字节流复制一张图片

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class test_1 {	
	public static void main(String[] args) throws IOException  {   	
		copyimage ();
	}
	public static void copyimage () throws IOException {
		File file = new File("C:\\Users\\fzx\\Desktop\\picture\\2.jpg");
		File file2 = new File("J:/a.jpg");
		
		FileInputStream fileInputStream = new FileInputStream(file);
		FileOutputStream fileOutputStream = new FileOutputStream(file2);
		
		BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
		BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
			
		int content = 0;
	    //  int length = bufferedInputStream.read(buf);   // 传入缓冲数组,内容是存储在缓冲数组中,返回值是存储到缓冲数组中的字节个数
		while((content = bufferedInputStream.read()) != -1) { //read()里面没有缓冲数组,返回值为读取到的内容
			bufferedOutputStream.write(content);	
		//	bufferedOutputStream.flush();       // 有这句代码 效率反而低			
		}
		bufferedOutputStream.close();
		bufferedInputStream.close();	
	}
}

应用: 使用字节流读取中文

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;

public class test_1 {	
	public static void main(String[] args) throws IOException {			
	//	write();
		read_2();
	}	
// 使用字节流  读取 中文	
	public static void read_2() throws IOException {
		File file = new File("J:/a.txt");
		FileInputStream fileInputStream = new FileInputStream(file);
		int content = 0;
		byte[] buf = new byte[2];
		
		while ((content = fileInputStream.read(buf))!=-1) {
			System.out.println(new String(buf,0,content));			
		}	
		fileInputStream.close();		
	}
// 使用字节流  写入 中文
	public static void write() throws IOException {
		
		File file = new File("J:/a.txt");
		FileOutputStream fileOutputStream = new FileOutputStream(file);
		String data = "付祖贤女侠";
		byte[] data_1 = data.getBytes(); //字节流之所以能够写中文是因为借助了字符串的getBytes()方法对字符串进行编码
		System.out.println(Arrays.toString(data_1));
		fileOutputStream.write(data_1);			
		fileOutputStream.close();		
	}
}

//

//

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值