IO概念
当使用集合持有数据时,这些数据都存在于内存中,一旦程序运行结束,这些数据将会从内存中清除,下次再想使用这些数据,已经没有了。
如果希望将运算永久地保存下来,可以使用IO,将这些数据持久化存储起来。要把数据持久化存储就需要把内存中的数据存储到内存以外的其他持久化设备(硬盘、光盘、U盘等)上。此时需要数据的输入(in)输出(out)。
数据输入输出相关的类均在io包下。
数据本质
在数据传输过程中,一切数据(文本、图像、声音等)最终存储的均为一个个字节,即二进制数字。所以数据传输过程中,使用二进制数据可以完成任意数据的传递。
字节输出流
输出流:
OutputStream(抽象类)
FileOutputStream(基本输出流)
构造方法:
public FileOutputStream(String name):创建输出流操作的目标
public FileOutputStream(String name,boolean append):append为true代表每次写入都向文件末尾追加,为false则每次都是覆盖写入
操作方法:
write(int n):输出一个字节;
write(byte[] b):输出一个字节数组;
write(byte[] b, int off , int len):输出字节数组的一部分;
close(): 释放IO占用的windows底层资源;
package com.IO;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.Array;
import java.util.Arrays;
/**
* @author :Andy
* @date :Created in 2019/6/16 19:28
* @description:读一个字节数组的数据
*/
public class InputStreamDemo2 {
public static void main(String[] args) throws IOException {
//创建IO流对象,绑定IO资源
FileInputStream fis = new FileInputStream("D:/test.txt");
/* //读取资源
byte[] bytes = new byte[3];
int len = fis.read(bytes);
System.out.println(len);
System.out.println(Arrays.toString(bytes));
System.out.println(fis.read(bytes));
//定义数组用于接收每次读取到的字节次数,一般用于长度为1024或者其整数倍*/
byte[] bytes1 = new byte[3];
//定义常量,用于记录每次读取到的字符长度
int len1 = -1;
//循环读取,知道文件的末尾
while((len1=fis.read(bytes1))!=-1){
//将字节数据变换成字符串,方便观察(通过字符串的构造方法)
//本次读取到几个字节就转换几个字节成字符串
String s = new String(bytes1,0,len1);
System.out.println(len1);
//打印字符串
System.out.println(s);
}
fis.close();
}
}
文件复制与高效流
文件复制不使用字节数组
利用字节流将当前工程下的ASCII码表完整版.doc复制到当前工程下的ASCII码表完整版(副本).doc
package com.IO;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* @author :Andy
* @date :Created in 2019/6/16 20:37
* @description:文件赋值不适用字节数组
*/
public class CopyFileDemo {
public static void main(String[] args) throws IOException {
//使用一次一个字节的方式完成复制
//创建IO流对象绑定IO资源
FileInputStream fis = new FileInputStream("ASCII码表完整版.doc");
FileOutputStream fos = new FileOutputStream("ASCII码表完整版(副本).doc");
//读取数据,读一个字节,写一个字节
//先读
//定义变量c,用于存储每次读取到的字节
int c = -1;
while((c=fis.read())!=-1){
//后写
fos.write(c);
}
//关闭流
fis.close();
fos.close();
}
}
文件复制使用字节数组
利用字节流和字节数组将当前工程下的ASCII码表完整版.doc复制到当前工程下的ASCII码表完整版(副本).doc
package com.IO;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* @author :Andy
* @date :Created in 2019/6/16 20:43
* @description:文件复制使用数组
*/
public class CopyFileDemo2 {
public static void main(String[] args) throws IOException {
//创建一个数组使用IO流
//使用一次一个字节数组的方式完成复制
FileInputStream fis = new FileInputStream("ASCII码表完整版.doc");
FileOutputStream fos = new FileOutputStream("ASCII码表完整版(副本).doc");
//读取数据,读一个字节,写一个字节
//定义字节数组,用于存储每次读到的数据
byte[] bytes = new byte[1024];
//定义字节变量,用来记录每次读到的字节长度
int len = -1;
//先读
while((len=fis.read(bytes))!=-1){
//后写
fos.write(bytes,0,len);
}
fis.close();
fos.close();
}
}
高效流
Java在常规IO流的基础上,提供了更为高效的缓冲流,如下:
高效字节缓冲流:BufferedInputStream/BufferedOutputStream
高效流使用普通流对象作为构造方法参数。将普通流包装,提供高效的装饰。
高效流write写出数据时,写出位置为缓冲区,并非目标资源。需要通过flush刷新方法将缓冲区的内容写出到目标文件中。
高效输出流的关闭方法会自动调用flush方法。
package com.IO;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* @author :Andy
* @date :Created in 2019/6/16 21:56
* @description:高校字节流
*/
public class BufferedStreamDemo {
public static void main(String[] args) throws IOException {
//以高校字节输出流为例
//创建普通输出流对象
FileOutputStream fos = new FileOutputStream("D:/test.txt");
//通过普通流对象创建高校流对象,这个过程加入了缓冲区
BufferedOutputStream bos = new BufferedOutputStream(fos);
//高校流的方法与普通流的方法一致,写出数据
bos.write(97);
bos.write(new byte[]{98,99,100});
//关闭流,关闭高校流即可,普通流会随着一起关闭
bos.close();
}
}