JavaSE小笔记--21(IO流初识)

时间:2022-10-26 21:37:26
1.概念
IO流用来处理设备之间的数据传输
Java对数据的操作是通过流的方式
Java用于操作流的类都在IO包中
流按流向分为两种:输入流,输出流。
流按操作类型分为两种
字节流:字节流可以操作任何数据,因为在计算机中任何数据都是以字节的形式存储的
字符流:字符流只能操作纯字符数据,比较方便
IO常用父类
字节流的抽象父类
InputStream
OutputStream
字符流的抽象父类
Reader
Writer
IO程序书写
使用前,导入IO包中的类
使用时,进行IO异常处理

使用后,释放资源

2.FileInputStream

由于InputStream是抽象的,不能直接创建对象,所以先以它的子类FileInputStream为例学习IO相关知识

read方法

返回值是int,从此输入流中读取一个数据字节,到达流的末尾没有字节了返回-1

public static void main(string[] args)throws IOException{

	FileInputStream fis= new FileInputStream("xxx,txt");	//创建流对象
	int x =fis.read();					//从硬盘上读取一个字节
	System.out.printin(x);
        int y =fis.read();
        System.out.println(y);
        int z= fis.read();
        System.out.printin(z);
        int a= fis.read();
	System.out.println(a);
	int b= fis.read();	
        System.out.println(b);

	fis.close ();						//关流释放资源

}

其中xxx.txt中的内容是:abc

所以上面代码的输出结果是:97

                                            98

  99

  -1

  -1

上面的代码可以由循环来实现:

FileInputStream fis= new FileInputStream("xxx.txt");	//创建一个文件输入流对象,并关联xxx.txt

int b;							//定义变量,记录每次读到的字节

while((b= fis.read()!=-1){				//将每次读到的字节赋值给b并判断是否是-1
	System. out. println (b);                        //打印每一个字节
}

fis.close();						 //关闭流释放资源

思考:read()方法读取的是一个字节,为什么返回是int,而不是byte?

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

3.FileOutputStream

write方法

public static void main(string[] args)throws IOException{
	
    FileOutputStream fos= new FileOutputStream("yyy,txt");		//创建字节输出流对象,
								        //如果没有就自动创建一个yyy.txt出来
	fos.write(97);							//虽然写的是一个int数,但是到文件上的是一个字节,会自动去除前3个8位
	fos.write(98);
	fos.write(99);

	fos.close();							//关流释放资源
}


FileOutputStream在创建对象的时候,如果没有这个文件会自动创建,如果有这个文件,就会先将文件清空,如果向续写这个文件,要在FileOutputStream的构造方法中传入第二个参数true来实现

FileOutputStream fos= new FileOutputStream("yyy,txt",true);

4.图片的拷贝

public static void main(string[] args)throws IOException{

	FileInputStream fis= new FileInputStream("aa.jpg");		//创建输入流对象,关联aa.jpg
        FileOutputStream fos= new FileOutputStream("copy.jpg");		//创建字节输出流对象,关联copy.jpg						
	int b;								//定义变量,记录每次读到的字节

	while((b= fis.read()!=-1){					//将每次读到的字节赋值给b并判断是否是-1
		fos.write(b);						//将每一个字节写出
	}
	
	fis.close();
	fos.close();
}

上面的拷贝是逐个字节拷贝,效率很慢 ;下面介绍一些方法,让拷贝更加效率,也是以后常用的


int read(byte[] b):一次读取一个字节数组

write(byte [] b ):一次写出一个字节数组

write(byte [] b,int off,int len):写出有效个字节个数

public static void main(string[] args)throws IOException{

	FileInputStream fis= new FileInputStream("xxx.txt");		//创建输入流对象,关联xxx.txt
	FileOutputStream fos= new FileOutputStream("yyy.txt");		//创建字节输出流对象,关联yyy.txt						
	byte [] arr = new byte[1024*8];
	int len ;

	while((len= fis.read(arr)!=-1){					//将每次读到的字节数组赋值给len并判断是否是-1
		fos.write(arr,0,len);					//将读到的字节数组的有效字节写出
	}
	
	fis.close();
	fos.close();
}

上面的arr的大小最好定义为1024的整数倍。

上面的拷贝代码可以说是IO流的核心了,要深刻理解