JavaIO流-1.字节流

字节流可以处理任意类型数据

字符流只能处理纯文本

在创建对象时,new后面报错,不是大圆形错,是小方块的错,就是异常,ctrl+1抛出异常信息

read()方法每次返回一个字节,为什么用int类型来接收?:

因为字节输入流可以操作任意类型的文件,比如图片文件,底层都是以二进制形式存储的,如果每次读取返回byte,有可能读到中间的时候读到11111111(是byte类型的-1)程序遇到-1就不读了,后面的就读不到了,如果用int类型接收,会在11111111前面补上24个0,凑足4个字节,那么byte类型的-1就变成了int类型的255,这样保证整个数据读完,而结束标记的-1就是int类型

write()的时候虽然是一个int数,但是会将前面的24个0去除,是一个byte数

package day20;

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

public class Dk1CopyImage {

	//拷贝图片(有多少个字节就有多少个来回,效率低,但是不占内存)
	public static void main(String[] args) throws IOException {
		FileInputStream fis = new FileInputStream("1.jpg");    //创建输入流对象,关联1.jpg
		FileOutputStream fos = new FileOutputStream("2.jpg");  //创建输出流对象,关联2.jpg不用创建
		
		int b;
		while ((b = fis.read())!= -1) {
			fos.write(b);
		}
		fis.close();
		fos.close();

	}

}

IO流字节读写原理:
在这里插入图片描述

package day20;

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

public class Dk2CopyArray {

	//以字节数组的形式将文件拷贝(只有一个来回,效率高,但是费内存不合适)
	public static void main(String[] args) throws IOException {
		FileInputStream fis = new FileInputStream("1.jpg");    //创建输入流对象,关联1.jpg
		FileOutputStream fos = new FileOutputStream("2.jpg");  //创建输出流对象,关联2.jpg不用创建

		byte[] arr = new byte[fis.available()];           //根据文件大小做一个字节数组
		//如果read方法没有写参数,返回的就是读到的码表值,比原文件大得多,比如a对应的97,如果有参数读的就是字节个数
        fis.read(arr);              //将文件上的所有字节读取到数组中
		fos.write(arr);             //将数组上的所有字节写到文件上
		
		fis.close();
		fos.close();
	}

}

package day20;

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

public class Dk3CopySplitArray {

	//以固定字节数组的形式将文件拷贝(推荐使用)
	public static void main(String[] args) throws IOException {
		FileInputStream fis = new FileInputStream("1.jpg");    //创建输入流对象,关联1.jpg
		FileOutputStream fos = new FileOutputStream("2.jpg");  //创建输出流对象,关联2.jpg不用创建
		int x;
		byte[] arr = new byte[1024 *8];           //定义1024*8个大小做一个字节数组
		//如果read方法没有写参数,返回的就是读到的码表值,比原文件大得多,比如a对应的97,如果有参数读的就是字节个数
        while((x = fis.read(arr)) != -1) {              //将文件上的两个字节读取到数组中,返回的x是字节个数
			fos.write(arr,0,x);        //从0开始取,到剩余的元素个数结束
		}
		
		fis.close();
		fos.close();

	}

}

在这里插入图片描述
上图中read()方法执行一次,就会将文件中的字节数据一次读取8192个字节存储在BufferedInputStream的缓冲区中,从缓冲区中返给一个一个字节返给b,如果write()一次先将缓冲区装满,然后再写到文件中,都是在内存中操作,减少了硬盘的操作次数。

Buffered会比自己定义字节数组(8192)稍慢一点,因为Buffered中读和写操作两个数组,自己定义是一个数组。

flush()和close()区别:

  1. flush刷新之后还可以继续写

    close在关闭之前会刷新一次,把缓冲区剩余的字节刷到文件中去,但是调用之后不能再写。使用缓冲区如果拷贝文件之后发现拷贝之后的文件比原文件小,那么可能是没有用close()方法。

  2. 需要实时刷新缓冲区内容的时候用flush(),close可以清空缓冲区。

字节流读取中文(需要进行转换)有弊端,可能会读到半个中文,解决办法有:

  1. 用字符流读(编码表+字节流)
  2. 将文件上所有字节一次读到内存上,在内存将所有字节转化为对应的字符串ByteArrayOutputStream

字节流写中文时必须转化为字节数组

注:在拷贝过程中中文不会出现问题(字节流可以拷贝任意数据,任意数据都是以字节形式存在的)

package day20;

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

public class Dk4IoException {

	//jdk1.6和1.7版本处理异常过程
	public static void main(String[] args) throws IOException {
		exception16();
		exception17();

	}
	
	//jdk1.6
	public static void exception16() throws IOException {
		FileInputStream fis = null;
		FileOutputStream fos = null;
		try {
			fis = new FileInputStream("1.jpg");
			fos = new FileOutputStream("2.jpg");
			int b;
			while ((b = fis.read())!= -1) {
				fos.write(b);
			}
		} finally {
			try {
				if (fis != null) {
					fis.close();
				}
			} finally {
				if (fos != null) {
					fos.close();
				}
				
			}
		}
	}
	
	//jdk1.7
	public static void exception17() throws IOException {
		try (FileInputStream fis = new FileInputStream("1.jpg"); // 创建输入流对象,关联1.jpg
				FileOutputStream fos = new FileOutputStream("2.jpg"); // 创建输出流对象,关联2.jpg不用创建
		) {
			int b;
			while ((b = fis.read()) != -1) {
				fos.write(b);
			}
		}//会自动关闭fis和fos
		//FileInputStream和FileOutputStream实现了AutoClosable接口,会自动关闭
	}

}

package day20;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Scanner;

public class Dk5ScannerWrite {

	//将键盘录入的数据写到文件中,遇到quit就退出
	public static void main(String[] args) throws IOException {
		Scanner scanner = new Scanner(System.in);
		FileOutputStream fos = new FileOutputStream("test.txt");
		while(true) {
			String line = scanner.nextLine();
			if ("quit".equals(line)) {
				break;
			}
			fos.write(line.getBytes());     //转化为字节数组
			fos.write("\r\n".getBytes());              //每输入一次就换行
		}
		fos.close();
	}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值