### IO流概述及其分类
- IO流概述
IO流用来处理设备之间的数据传输
Java对数据的操作是通过流的方式
Java用于操作流的对象都在IO包中 - IO流分类
- 按照数据流向
输入流 读入数据
输出流 写出数据 - 按照数据类型
字节流 可以读写任何类型的文件 比如音频 视频 文本文件
字符流 只能读写文本文件 - 什么情况下使用哪种流呢?
如果数据所在的文件通过windows自带的记事本打开并能读懂里面的内容,就用字符流。其他用字节流。
如果你什么都不知道,就用字节流
FileOutputStream写出数据
- 构造方法
FileOutputStream(File file)
FileOutputStream(String name)
- 案例演示
FileOutputStream向文件写出数据
public class MyTest {
public static void main(String[] args) throws IOException {
// FileOutputStream(File file)
// 创建一个向指定 File 对象表示的文件中写入数据的文件输出流。
//
// FileOutputStream(String name)
// 创建一个向具有指定名称的文件中写入数据的输出文件流。
File file = new File("a.txt");
//file.createNewFile();
//文件输出流所关联的文件,如果不存在会自动帮你创建
FileOutputStream out = new FileOutputStream(file);
System.out.println("---------------------------");
//可以关联一个字符串形式的路径文件
FileOutputStream out2 = new FileOutputStream("b.txt");
}
}
FileOutputStream的三个write()方法
- FileOutputStream的三个write()方法
public void write(int b):写一个字节 超过一个字节 砍掉前面的字节
public void write(byte[] b):写一个字节数组
public void write(byte[] b,int off,int len):写一个字节数组的一部分 - 案例演示: FileOutputStream的三个write()方法
public class MyTest {
public static void main(String[] args) throws IOException {
//文件输出流,所关联的文件,如果不存在,会帮你自动创建
FileOutputStream out = new FileOutputStream("b.txt");
//一次写入一个字节
out.write(97);
out.write(98);
out.write(99);
out.write(100);
//一次写入一个字节数组
out.write(new byte[]{101, 102, 103, 104});
//一次写入字节数组的一部分
out.write(new byte[]{105, 106, 107, 108}, 0, 2);
//流使用完毕后,记得释放资源
out.close();
}
}
- 将字符串转化为字符数组写入
public class MyTest3 {
public static void main(String[] args) throws IOException {
FileOutputStream out = new FileOutputStream("c.txt");
out.write(97);
// \r\n windows平台的换行符
//Linux \n
//Mac \r
out.write("\r\n".getBytes());
byte[] bytes = "于是于是于是爱恨纠缠人憔悴".getBytes();
out.write(bytes, 0, 18); //写人字节数组的一部分
out.write("\r\n".getBytes());
byte[] bytes2 = "于是于是于是爱恨纠缠人憔悴".getBytes();
out.write(bytes2);
out.close();
}
}
- 注意事项:
- 创建字节输出流对象了做了几件事情?
a:调用系统资源创建a.txt文件
b:创建了一个fos对象
c:把fos对象指向这个文件 - 为什么一定要close()?
a: 通知系统释放关于管理a.txt文件的资源
b: 让Io流对象变成垃圾,等待垃圾回收器对其回收
FileOutputStream写出数据实现换行和追加写入
- 实现数据换行
public class MyTest3 {
public static void main(String[] args) throws IOException {
FileOutputStream out = new FileOutputStream("c.txt");
out.write(97);
// \r\n windows平台的换行符
//Linux \n
//Mac \r
out.write("\r\n".getBytes());
byte[] bytes = "于是于是于是爱恨纠缠人憔悴".getBytes();
out.write(bytes, 0, 18); //写人字节数组的一部分
out.write("\r\n".getBytes());
byte[] bytes2 = "于是于是于是爱恨纠缠人憔悴".getBytes();
out.write(bytes2);
out.close();
}
}
- 追加写入
public class MyTest {
public static void main(String[] args) throws IOException {
//追加写入,
//FileOutputStream(String name, boolean append)
//创建一个向具有指定 name 的文件中写入数据的输出文件流。
//参数2 是否是追加写入,true 表示追加写入,false 就是不追加每次运行都会覆盖
FileOutputStream out = new FileOutputStream("d.txt",true);
out.write("江畔何人初见月".getBytes());
out.write("\r\n".getBytes());
out.write("江月何年初照人".getBytes());
out.write("\r\n".getBytes());
out.close();
}
}
FileInputStream读取数据
- 从文件中一次读取一个字节
public class MyTest {
public static void main(String[] args) throws IOException {
// FileInputStream 从文件系统中的某个文件中获得输入字节。
// FileInputStream(String name)
// 通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的路径名 name 指定。
//
// FileInputStream(File file)
// 通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的 File 对象 file 指定。
//输入流所关联的文件如果没有找到,就会报错
// FileInputStream in2 = new FileInputStream("b.txt");
FileInputStream in = new FileInputStream(new File("a.txt"));
//从文件中读取数据,如果读取不到会返回-1,我们要用这个-1来判断这个文件是否读取完了
int read = in.read();
System.out.println(read);
read = in.read();
System.out.println(read);
read = in.read();
System.out.println(read);
read = in.read();
System.out.println(read);
read = in.read();
System.out.println(read);
read = in.read();
System.out.println(read);
read = in.read();
System.out.println(read);
//用完记得关闭流
in.close();
}
}
- 从文件中一次读取一个字节数组
public class MyTest2 {
public static void main(String[] args) throws IOException {
FileInputStream in = new FileInputStream("c.txt");
//一次读取一个字节数组
byte[] bytes = new byte[1024]; //创建一个指定长度的一个容器
int len = in.read(bytes); //把这个传给他,他就可以把读取到的数据,放到容器中,返回值是他读取到的有效字节个数
System.out.println(len);
//for (byte aByte : bytes) {
// System.out.println(aByte);
//}
System.out.println(new String(bytes));
}
}
- 读取数组的一部分
public class MyTest3 {
public static void main(String[] args) throws IOException {
FileInputStream in = new FileInputStream("c.txt");
byte[] bytes = new byte[6]; //创建一个指定长度的一个容器
//一次读取字节数组的一部分
//读的时候,从头读取,读取后要放到容器中,就是从0开始放,放3个字节
int len = in.read(bytes, 0, 3); //把这个传给他,他就可以把读取到的数据,放到容器中,返回值是他读取到的有效字节个数
System.out.println(len);
for (byte aByte : bytes) {
System.out.println(aByte);
}
System.out.println(new String(bytes).trim());
in.close();
}
}
使用IO流进行文件复制
- 一次复制一个字节
public class MyTest {
public static void main(String[] args) throws IOException {
//采用读取一个字节,写入一个字节的方式,来复制文件
FileInputStream in = new FileInputStream("D:\\a.txt");
FileOutputStream out = new FileOutputStream("E:\\aa.txt");
//int read = in.read();
//out.write(read);
int len = 0;
while ((len = in.read()) != -1) {
out.write(len);
}
in.close();
out.close();
}
}
- 一次复制一个字节数组
public class MyTest3 {
public static void main(String[] args) throws IOException {
//很显然,一次读取一个字节,写一个字节,复制文件太耗时了,所以不推荐使用
//我们推荐一次读取一个字节数组,写入一个字节数组
FileInputStream in = new FileInputStream("D:\\夜夜夜夜.mp3");
FileOutputStream out = new FileOutputStream("E:\\夜夜夜夜.mp3");
//创建一个字节数组,充当缓冲区
byte[] bytes = new byte[1024 * 8];
//定义一个变量,记录每次读取到的有效字节个数
int len = 0;
while ((len = in.read(bytes)) != -1) {
out.write(bytes, 0, len);
}
in.close();
out.close();
}
}
- 手动捕获异常
public class MyTest {
public static void main(String[] args) {
//字节流
//FileInputStream
//FileOutputStream
FileInputStream in = null;
FileOutputStream out = null;
try {
in = new FileInputStream("D:\\夜夜夜夜.mp3");
out = new FileOutputStream("E:\\\\夜夜夜夜.mp3");
byte[] bytes = new byte[1024 * 8];
int len = 0;
while ((len = in.read(bytes)) != -1) {
out.write(bytes, 0, len);
out.flush();//刷新缓冲区
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (in != null) {
in.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (out != null) {
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
~
- 使用高效字节输入输出流进行复制
public class MyTest {
public static void main(String[] args) throws IOException {
//高效的字节输入输出流
// BufferedInputStream
// BufferedOutputStream
// "D:\\夜夜夜夜.mp3"
//BufferedInputStream(InputStream in, int size)
//创建具有指定缓冲区大小的 BufferedInputStream 并保存其参数,即输入流 in,以便将来使用。
long start = System.currentTimeMillis();
//copyFile();
copyFile2();
long end = System.currentTimeMillis();
System.out.println("耗时" + (end - start) + "毫秒");
}
private static void copyFile2() throws IOException {
FileInputStream in = new FileInputStream("D:\\夜夜夜夜.mp3");
FileOutputStream out = new FileOutputStream("E:\\夜夜夜夜.mp3");
int len2 = 0;
byte[] bytes = new byte[1024 * 10];
while ((len2 = in.read(bytes)) != -1) {
out.write(bytes, 0, len2);
}
in.close();
out.close();
}
private static void copyFile() throws IOException {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("D:\\夜夜夜夜.mp3"), 1024 * 10);
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("E:\\夜夜夜夜.mp3"), 1024 * 10);
int len2 = 0;
byte[] bytes = new byte[1024 * 10];
while ((len2 = bis.read(bytes)) != -1) {
bos.write(bytes, 0, len2);
}
bis.close();
bos.close();
}
}~