JAVA - IO 流
字节流
FileOutputStream
import java.io.FileOutputStream;
import java.io.IOException;
public class FileOutPutStreamDemo {
/*
FileOutputStream 使用细节:
1.write方法 写出的数字: 是ASCCI表中字符对应的数字,因此97 =>a
2.创建FileOutputStream 对象时 “E:\javaProject\myio\a.txt”,a.txt 可以不存在,但是父级路径一定要存在
3.如果a.txt 已经存在会产生覆盖的效果
*/
public static void main(String[] args) throws IOException {
FileOutputStream fos = new FileOutputStream("E:\\javaProject\\myio\\a.txt");
byte[] b = {97,98,99,100}; //文件中是 abcd
fos.write(b);
fos.close();
}
}
重载的write方法:

思考: write 方法传入一个 char类型'a' 为什么也可以写入到文件中?

续写功能:

FileInputStream
import java.io.FileInputStream;
import java.io.IOException;
public class FileInputStreamDemo {
/*
读取的文件内容: abc
*/
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("E:\\javaProject\\myio\\a.txt");
int read = fis.read();
System.out.println(read); //97
int read1 = fis.read();
System.out.println(read1); // 98
int read2 = fis.read();
System.out.println(read2); //99
int read3 = fis.read(); //
System.out.println(read3); //-1:代表结束
}
}
细节:
1.创建字节输入流对象
- 如果文件不存在,就直接报错
2.读取数据
- 一次读一个字节,读出来得数据是在ASCCI上对应得数字
- 读到文件末尾了,read方法返回 -1
3.释放资源
- 每次使用完流必须要释放资源
文件copy
FileInputStream:一次读取一个字节
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileInputStreamDemo2 {
//读取文件的大小:25.8 MB (27,096,467 字节)
public static void main(String[] args) throws IOException {
long start = System.currentTimeMillis();
// 文件拷贝
FileInputStream fis = new FileInputStream("F:\\葵花宝典\\书籍\\HTML5权威指南.pdf");
FileOutputStream fos = new FileOutputStream("E:\\javaProject\\myio\\COPY_HTML5权威指南.pdf");
int b;
while ((b = fis.read()) != -1) {
fos.write(b);
}
//释放资源,规则:先打开的流后释放
fos.close();
fis.close();
long end = System.currentTimeMillis();
System.out.println("copy 耗时:" + ( end - start)); //copy 耗时:192676ms
}
}
一个字节一个字节读取数据很慢,25.6M = 27096467 字节, 相当于要读取27096467 次,如何优化?
FileInputStream:一次读取多个字节
import java.io.FileInputStream;
import java.io.IOException;
public class FileInputeDemoStream3 {
/*
FileInputStream:一次读取多个字节
*/
public static void main(String[] args) throws IOException {
byte[] bytes = new byte[2]; //数组的大小定义了一次读取数据的多少
FileInputStream fis = new FileInputStream("E:\\javaProject\\myio\\a.txt");
//len:读取到的字节个数
int len = fis.read(bytes); //将数据读取到字节数组当中
System.out.println(len); //2
System.out.println(new String(bytes)); //ab
int len2 = fis.read(bytes); //覆盖数组当中的ab,此时装入数组的数据是cd
System.out.println(len2); //2
System.out.println(new String(bytes)); //cd
int len3 = fis.read(bytes); //读取到e,覆盖数组中的c,此时数组中的数据是ed
System.out.println(len3); //1
System.out.println(new String(bytes)); //ed
int len4 = fis.read(bytes); // 没有读到数据,因此数组中还是ed
System.out.println(len4); //-1
System.out.println(new String(bytes)); //ed
}
}

一次读取多个字节copy 文件:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileCopyDemo {
public static void main(String[] args) throws IOException {
long start = System.currentTimeMillis();
FileInputStream fis = new FileInputStream("F:\\葵花宝典\\书籍\\HTML5权威指南.pdf");
FileOutputStream fos = new FileOutputStream("E:\\javaProject\\myio\\COPY_HTML5权威指南.pdf");
int len;
byte[] bytes = new byte[1024 * 1024 * 5]; //数组的大小一般选择 1024 的整数倍,需要结合具体电脑的内存选择
while((len = fis.read(bytes)) != -1){
fos.write(bytes,0,len); //从数组中写出len个长度的字节
}
fos.close();
fis.close();
long end = System.currentTimeMillis();
System.out.println("copy 消耗:" + (end - start)); //copy 消耗:29
}
}
IO异常
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class IOExceptionDemo1 {
/*
JDK1.7: try 的写法
try后面的小括号中写创建对象的对象,不同对象之间用分号隔开
注意:只有实现了AutoCloseable接口的类,才能在小括号中创建对象。
*/
public static void main(String[] args) throws IOException {
try(FileInputStream fis = new FileInputStream("F:\\葵花宝典\\书籍\\HTML5权威指南.pdf");
FileOutputStream fos = new FileOutputStream("E:\\javaProject\\myio\\COPY_HTML5权威指南.pdf")){
int len;
byte[] bytes = new byte[1024 * 1024 * 5]; //数组的大小一般选择 1024 的整数倍,需要结合具体电脑的内存选择
while((len = fis.read(bytes)) != -1){
fos.write(bytes,0,len); //从数组中写出len个长度的字节
}
}catch (IOException e){
e.printStackTrace();
}
}
}

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class IOExceptionDemo2 {
/*
JDK1.9: try 的写法
*/
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("F:\\葵花宝典\\书籍\\HTML5权威指南.pdf");
FileOutputStream fos = new FileOutputStream("E:\\javaProject\\myio\\COPY_HTML5权威指南.pdf");
try (fis; fos) {
int len;
byte[] bytes = new byte[1024 * 1024 * 5]; //数组的大小一般选择 1024 的整数倍,需要结合具体电脑的内存选择
while ((len = fis.read(bytes)) != -1) {
fos.write(bytes, 0, len); //从数组中写出len个长度的字节
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
字符流
字符流 = 字节流 + 编码表
FileReader
文件内容:

一次读取一个字符:
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class FileReaderDemo {
public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("E:\\javaProject\\myio\\a.txt");
int a;
//read()细节:
//1.默认也是一个字节一个字节读取的,如果遇到中文就会一次读取多个字节
//2.在读取之后,方法的底层还会进行解码并转换成十进制.
// 最终把这个十进制作为返回值,对应字符集上的数字
// 中文:文件里面的二进制数据:11100110 10110001 1001001
// read 方法进行读取,解码并转换成十进制27721
while ((a = fr.read()) != -1) {
System.out.print((char) a);
/*
你好啊
哈哈哈
喜时之言多失信,
怒时之言多失体。
*/
}
}
}
一次读取多个字符:
import java.io.FileReader;
import java.io.IOException;
public class FileReaderDemo2 {
public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("E:\\\\javaProject\\\\myio\\\\a.txt");
char[] chars = new char[2];
int len;
/*
read(char[] chars) 细节:
读取数据,解码,强转三步合并了,把强转之后的字符放到数组当中
相当于空参的read() + 强制类型转换
*/
while ((len = fr.read(chars)) != -1) {
System.out.print(new String(chars, 0, len));
}
fr.close();
}
}
FileWrite
构造方法:

成员方法:

import java.io.FileWriter;
import java.io.IOException;
public class FileWriterDemo1 {
public static void main(String[] args) throws IOException {
FileWriter fw = new FileWriter("E:\\javaProject\\myio\\a.txt",true);
//写入一个int
fw.write(25105);//按照UTF-8的方式进行编码,并写入到文件中去,25105 在UniCode码表中对应
//中文 ‘我’,因此写入的数据就是我
//写入一个字符串
fw.write("我");
fw.close();
}
}
写入结果:

字符流原理
字符输入流:

创建完FileReader对象后,会有一个8192长度的字节数组作为缓冲区:

第一次读取时会将文件中读取8192个a全部放入到字节数组,然后每次从缓冲求拿数据:

缓冲区数据读取完毕后,最后一次从硬盘取到最后一个字符b放入到缓冲区:

字符输出流: 内部同样维护的有一个8192个字节的缓冲区

本文来自博客园,作者:chuangzhou,转载请注明原文链接:https://www.cnblogs.com/czzz/p/17281376.html

浙公网安备 33010602011771号