IO流_02(字节流)

FileInputStream

用字节流复制一张图片

public class CopyPicture {
	public static void main(String[] args) {
		
		FileInputStream fis = null;
		FileOutputStream fos = null;
		try {
			fis = new FileInputStream("D:\\1.png");
			fos = new FileOutputStream("D:\\2.png");
			
			byte[] buf = new byte[1024];
			
			int len = 0;
			
			while((len = fis.read(buf)) != -1){
				fos.write(buf,0,len);
			}
			
		} catch (IOException e) {
			throw new RuntimeException("复制文件失败");
		} finally {
			try {
				if(fis != null)
					fis.close();
			} catch (IOException e) {
				throw new RuntimeException("读取文件关闭失败");
			}
			try {
				if(fos != null)
					fos.close();
			} catch (IOException e) {
				throw new RuntimeException("写入文件关闭失败");
			}
		}
	}
}

BufferedInputStream

原理:

缓冲区里面有一个数组,每次抓取一批数据存入数组中,并返回数据长度。定义一个指针,从数组中一个一个读出数据,当数据读完时,再抓取一批数据。自定义缓冲区代码如下:

public class MyBufferedInputStream {
	InputStream is;
	byte[] buf = new byte[1024];
	int count;//抓取的数据长度
	int pos;//指针
	MyBufferedInputStream(InputStream is){
		this.is = is;
	}
	public int myRead() throws IOException {
		if(count == 0) {
			count = is.read(buf);
			if(count == -1)
				return -1;
			pos = 0;	
		}
		byte b = buf[pos];
		count--;
		pos++;
		return b&255;//注释如下
	}
}

注意 read读一个字节可能读到-1,导致不再继续往下读,所以read把byte类型提升为一个int类型,但还是-1,是-1的原因是因为在8个1前面补的都是1导致的。那么我只要在前面补0,即可以保留原字节数据不变,又可以避免-1的出现
read方法在提升,write方法在强转

测试如下

public class CopyMp3 {
	public static void main(String[] args) throws IOException {
		long start = System.currentTimeMillis();
		copy();
		long end = System.currentTimeMillis();
		System.out.println((end - start) + "毫秒");
	}

	private static void copy() throws IOException {
		FileInputStream fis = new FileInputStream("D:\\1.png");
		FileOutputStream fos = new FileOutputStream("D:\\2.png");
		MyBufferedInputStream mbis = new MyBufferedInputStream(fis);
		int lin = 0;
		while((lin = mbis.myRead()) != -1) {
			fos.write(lin);
		}
		fis.close();
		fos.close();	
	}
}

读取键盘录入

  • System.out:对应的是标准的输出设备,控制台
  • System.in:对应的是标准输出设备:键盘
  • 当录入一行数据后,就将该行数据打印
  • 如果录入的数据是over,那么停止录入
public class ReadIn {
	public static void main(String[] args) throws IOException {
		InputStream in = System.in;
		StringBuilder sb = new StringBuilder();
		while(true) {
			int ch = in.read();
			if(ch == '\r')
				continue;
			if(ch == '\n') {
				String s= sb.toString();
				if(s.equals("over"))
					break;
				System.out.println(s);
				sb.delete(0, sb.length());
			}else {
				sb.append((char)ch);
			}
		}
	}
}

既然是录入一行一行打印,可以想到字符流缓冲区的readLine()方法,所以需转换流,代码如下

public class 转换流 {

	public static void main(String[] args) throws IOException {
		//字节流转字符流
		InputStream in = System.in;
		InputStreamReader isr = new InputStreamReader(in);
		BufferedReader bufr = new BufferedReader(isr);
		//字符流转字节流
		PrintStream out = System.out;
		OutputStreamWriter osr = new OutputStreamWriter(out);
		BufferedWriter bufw = new BufferedWriter(osr);
		
		String line = null;
		while((line = bufr.readLine()) != null) {
			if(line.equals("over"))
				break;
			bufw.write(line);
			bufw.newLine();
			bufw.flush();
		}
	}
}

转换流

流的操作规律:

想要知道

  1. 明确源和目的(汇)
    源:inputStream Reader
    目的:OutputStream Writer

  2. 明确数据是否是纯文本数据
    源:是纯文本:Reader 否则:InputStream
    目的:是纯文本:Writer 否则:OutputStream

  3. 明确具体的设备
    源设备:

    • 硬盘:File
    • 键盘:System.in
    • 内存:数组
    • 网络:Socket流

    目的设备:

    • 硬盘:File
    • 控制台:System.out
    • 内存:数组
    • 网络:Socket流
  4. 是否需要其他额外功能

    1. 是否需要高效(缓冲区)
      是,就加上buffer
    2. 流转换

什么时候使用流转换呢?

  1. 源或者目的对应的设备是字节流,但是操作的却是文本数据,可以使用转换作为桥梁。提供对文本操作的便捷
  2. 一但文本设计到具体的指定编码表时,就必须使用转换流
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值