JAVA中IO流
1.IO流概述及其分类
-
IO流概述
- IO流用来处理设备之间的数据传输
- Java对数据的操作是通过流的方式
- Java用于操作流的对象都在IO包中 java.io
-
IO流分类
- 按照数据流向 (以内存为基准)
- 输入流 读入数据
- 输出流 写出数据
- 按照数据类型
- 字节流 可以读写任何类型的文件 比如音频 视频 文本文件
- 字符流 只能读写文本文件
- 如果数据所在的文件通过windows自带的记事本打开并能读懂里面的内容,就用字符流
- 按照数据流向 (以内存为基准)
-
IO流基类概述和FileOutputStream的构造方法
- IO流基类概述
- 字节流的抽象基类:
InputStream ,OutputStream。 - 字符流的抽象基类:
Reader , Writer。 - 由这四个类派生出来的子类名称都是以其父类名作为子类名的后缀。
- InputStream的子类FileInputStream。
- 字节流的抽象基类:
- FileOutputStream的构造方法
OutputStream,使用具体子类FileOutputStream
- IO流基类概述
-
Io流的分类:
-
按照流向进行划分
输入流 输出流
-
-
按照操作的数据类型进行划分
- 字节流
- 字节输入流 InputStream 读
- 字节输出流 OutputStream 写
- 字符流
- 字符输入流 Reader 读
- 字符输出流 Writer 写
- 字节流
-
需求: 往一个文本文件中写一串数据 Hello,IO
-
分析:
- 我们现在操作的是文本文件,所有按照我们的想法,我们优先现在字符流,但是字节流是优先于字符流. 所以先使用字节流
- 因为我们要写数据,所以我们应该使用字节流中输出流 OutputStream
2.FileOutputStream写出数据
-
构造方法
FileOutputStream(File file)
FileOutputStream(String name) -
注意事项:
-
调用系统资源创建a.txt文件
-
创建了一个fos对象
-
把fos对象指向这个文件
-
-
为什么一定要close()?
- a: 通知系统释放关于管理a.txt文件的资源
- b: 让Io流对象变成垃圾,等待垃圾回收器对其回收
-
案例演示
public class MyTest { public static void main(String[] args) { //流的异常处理 FileOutputStream out = null; out = new FileOutputStream("a.txt"); out.write("abc".getBytes()); //System.out.println(1 / 0); } }
-
三个write()方法)
- FileOutputStream的三个write()方法
- public void write(int b):写一个字节 超过一个字节 砍掉前面的字节
- public void write(byte[] b):写一个字节数组
- public void write(byte[] b,int off,int len):写一个字节数组的一部分
- FileOutputStream的三个write()方法
-
FileOutputStream写出数据实现换行和追加写入
- windows \r\n
- Linux \n
- Mac \r
-
加入异常处理
public class MyTest {
public static void main(String[] args) {
//流的异常处理
FileOutputStream out = null;
try {
out = new FileOutputStream("a.txt");
out.write("abc".getBytes());
//System.out.println(1 / 0);
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (out != null) {
System.out.println("进来了");
out.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
- FileInputStream读取数据(一次一个字节)
public class MyTest2 {
public static void main(String[] args) throws IOException {
FileInputStream in = new FileInputStream("a.txt");
//读取文件数据,
int by = in.read(); //一次读取一个字节数据,返回的是你读取到的那个字节
System.out.println(by);
//System.out.println((char) by);
by = in.read(); //一次读取一个字节数据
System.out.println(by);
by = in.read(); //一次读取一个字节数据
System.out.println(by);
//文件中数据读取完毕,然后读取不到了,返回 -1 我们可以使用 -1 来判断文件是否读取完毕。
by = in.read(); //一次读取一个字节数据
System.out.println(by);
}
}
- FileInputStream读取数据一次一个字节数组
public class MyTest3 {
public static void main(String[] args) throws IOException {
FileInputStream in = new FileInputStream("a.txt");
//我们创建一个字节数组,作为缓冲区,
byte[] bytes = new byte[100];
//返回的是你实际读取到的字节个数,
int len = in.read(bytes); //把文件中的字节一次读取满,你这个字节数组
System.out.println(len);
//len = in.read(bytes); //读取不到返回-1
//System.out.println(len);
System.out.println("================================");
/* for (byte aByte : bytes) {
System.out.println(aByte);
}*/
String s = new String(bytes, 0, len);
System.out.println(s);
// byte[] bytes1 = s.getBytes();
in.close(); //不要忘了
}
}
3.字节流复制文本文件(数组法常用)
public class MyTest3 {
public static void main(String[] args) throws IOException {
//很显然:读取一个字节,写入一个字节来复制 效率很低
//你 可以一次读取一个数组,写出一个字节数组,来复制。
byte[] arr=new byte[1024*8];
FileInputStream in = new FileInputStream("C:\\Users\\Administrator\\Desktop\\5.22\\课后作业day16.doc");
FileOutputStream out = new FileOutputStream("C:\\Users\\Administrator\\Desktop\\20210529-JavaSE-课件\\课后作业day16.doc");
try {
long start = System.currentTimeMillis();
int len = 0;
while ((len = in.read(arr)) != -1) {
out.write(arr, 0, len);
out.flush();
}
long end = System.currentTimeMillis();
System.out.println("复制完成耗时:" + (end - start) + "毫秒");
}catch(IOException e){
e.printStackTrace();
}try {
if (in != null) {
in.close();
}
if (out != null) {
out.close();
}
}catch(IOException e){
e.printStackTrace();
}
}
}
4.BufferedOutputStream写出数据(高效)
-
缓冲思想
- 字节流一次读写一个数组的速度明显比一次读写一个字节的速度快很多,这是加入了数组这样的缓冲区效果,java本身在设计的时候,也考虑到了这样的设计思想(装饰设计模式后面讲解),所以提供了字节缓冲区流
-
BufferedOutputStream的构造方法
BufferedOutputStream(OutputStream out) -
案例演示
public class MyTest { public static void main(String[] args) throws IOException { test(); //复制完成耗时:24962毫秒 14毫秒 } private static void test() throws IOException { FileInputStream in = new FileInputStream("C:\\Users\\ShenMouMou\\Desktop\\s.txt"); FileOutputStream out = new FileOutputStream("D:\\test\\s.txt"); BufferedInputStream bin = new BufferedInputStream(in); BufferedOutputStream bout = new BufferedOutputStream(out); byte[] bytes = new byte[1024 * 8]; int by = 0; long start = System.currentTimeMillis(); while ((by = bin.read(bytes)) != -1) { bout.write(bytes, 0, by); } long end = System.currentTimeMillis(); bin.close(); bout.close(); System.out.println("复制完成耗时:" + (end - start) + "毫秒"); } } }
-
测试效率
public class MyTest {
public static void main(String[] args) throws IOException {
test1(); //复制完成耗时:24962毫秒 14毫秒
test2(); // 复制完成耗时:188毫秒 复制完成耗时:12毫秒
}
private static void test2() throws IOException {
FileInputStream in = new FileInputStream("C:\\Users\\ShenMouMou\\Desktop\\x.txt");
FileOutputStream out = new FileOutputStream("D:\\test\\c.txt");
BufferedInputStream bin = new BufferedInputStream(in);
BufferedOutputStream bout = new BufferedOutputStream(out);
byte[] bytes = new byte[1024 * 8];
int by = 0;
long start = System.currentTimeMillis();
while ((by = bin.read(bytes)) != -1) {
bout.write(bytes, 0, by);
}
long end = System.currentTimeMillis();
bin.close();
bout.close();
System.out.println("复制完成耗时:" + (end - start) + "毫秒");
}
private static void test1() throws IOException {
FileInputStream in = new FileInputStream("C:\\Users\\ShenMouMou\\Desktop\\c.txt");
FileOutputStream out = new FileOutputStream("D:\\test\\x.txt");
byte[] bytes = new byte[1024 * 8];
int by = 0;
long start = System.currentTimeMillis();
while ((by = in.read(bytes)) != -1) {
out.write(bytes, 0, by);
out.flush();
}
long end = System.currentTimeMillis();
in.close();
out.close();
System.out.println("复制完成耗时:" + (end - start) + "毫秒");
}
}