1. 流的分类
在java.io包中流分为两类:
字节流(byte):
InputStream OutputStream
字符流(char):
Reader Writer
从下面的图我们来看看字节流与字符流的区别:
字节流与字符流的区别:
字节流是原生操作无需转换,字符流是处理后的操作。
字节流可以处理文本文件、图像、音乐、视频等资源
一般使用字节流(无论是网络传输还是磁盘数据保存均以字节为单位)
只有处理中文文本时才会用到字符流。
2. 流操作流程
无论是字节流还是字符流,操作流程几乎一样
1.取得终端对象
2.根据终端对象取得输入输出流
3.根据输入输出流进行数据读取与写入
4.关闭流
IO操作属于资源处理,所有的资源操作在使用后一定要关闭
3. 字节输出流
字节输出流有三个核心输出方法:
- 将指定的字节数组全部输出
public void write(byte[ ] b) throws IOException; - 将部分字节数组输出
public void write(byte[ ] b,int offset, int len) throws IOException - 输出单个字节
public abstract void write(int b) throws IOException;
在IO操作这里,要想使用某个终端,这个终端一定有一个类实现了Outputstream这个类(Outputstream是抽象类)。
- 文件内容覆盖
public FileOutputStream(File file) throws FilenotFoundException - 文件内容追加(boolean返回是否允许追加文件内容)
public FileOutputStream(File file, boolean append)
当使用FileOutputStream进行文件输出时,只要文件的父路径存在,FileOutputStream会自动创建文件。
看一个例子:
public class IO1{
public static void main(String[] args) {
//1.取得终端对象
File file = new File("C"+File.separator+"Users"+File.separator+"Administrator"
+File.separator+"Desktop"+File.separator+"Test.txt"); //在桌面创建Test.txt的文件夹
if(!file.exists()){
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
//2.取得终端对象的输出流
try {
//多次运行内容不变,覆盖上次运行结果
OutputStream out = new FileOutputStream(file); //向上转型
//允许文件内容的追加OutputStream out = new FileOutputStream(file,"true");
// 3. 进行数据的输出
String msg = "java\n"; //所创建文件夹内容为"java"
out.write(msg.getBytes());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
{
//4.关闭流
out.close();
}
}
}
}
4.字节输入流
输入方法 read :
a. 读取数据到字节数组b中
public int read(byte[ ] b) throws IOException
返回值三种情况(喝稀饭,开始稀饭多,勺子一勺只能喝一勺的量,后来只剩下不足一勺子的量,再后来吃完了):
- 返回b的长度 : 当读取的数据大小 > 字节数组大小,返回字节数组大小
- 返回一个大于0的数,但是小于b长度 : 读取数据大小 < 字节数组大小,返回真正读取个数
- 返回 -1 :数据读取完毕
b. public int read( ) throws IOException:读取单个字节
栗子:
public class IO1{
public static void main(String[] args) {
File file = new File("C"+File.separator+"Users"+File.separator+"Administrator"
+File.separator+"Desktop"+File.separator+"新建文本文档.txt"); //从桌面中的新建文本文档读取文件内容
try {
InputStream in = new FileInputStream(file);
byte[] data = new byte[1024];
int resylt = in.read(data);
System.out.println(new String(data));
in.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
5.字符流
字符输出流Writer-适用于处理中文文本
除了参数为字符数组外,多了一个传入String对象的方法
可以直接支持字符串的输出
public void write (String str) throws IOException
字符流若为关闭,数据在缓冲区存放,不会输出目标终端。要想将数据输出,要么将输出流关闭,要么使用flush强制刷新缓冲区。
public class IO1{
public static void main(String[] args) throws IOException {
File file = new File("C"+File.separator+"Users"+File.separator+"Administrator"
+File.separator+"Desktop"+File.separator+"新建文本文档.txt");
Writer writer = new FileWriter(file);
String str = "hello";
writer.write(str);
writer.close();
}
}
字符输入流Reader
Reader类中没有方法可以直接读取字符串,只能通过字符数组来读取
public int read(char cbuf[]) throws IOException
public class IO1{
public static void main(String[] args) throws IOException {
File file = new File("C"+File.separator+"Users"+File.separator+"Administrator"
+File.separator+"Desktop"+File.separator+"新建文本文档.txt");
Reader reader = new FileReader(file);
char[] data = new char[1024];
int result = reader.read(data); //此时文件内容小于数组开辟大小,返回文件内容
System.out.println(result);
System.out.println(new String(data,0,result)); //文件内容
}
}
6 转换流:字节流 -> 字符流
转换流用于将底层的字节流转为字符流供子类使用,单向操作
OutputStreamWriter : 字节输出流 -> 字符输出流
InputStreamReader : 字节输入流 -> 字符输入流
字符流的具体子类大都是通过转换流将字节流转为字符流的(FileWriter继承转换流)
public class fileTes{
public static void main(String[] args) throws IOException {
//1.取得终端对象
File file = new File("C:"+File.separator+"Users"+File.separator+
"Administrator"+File.separator+"Desktop"+File.separator+"Test.txt");
//2.取得终端输出流
OutputStream outputStream = new FileOutputStream(file);
//3.进行数据的输入输出
OutputStreamWriter out = new OutputStreamWriter(outputStream);
out.write("你好");
//4. 关闭流
out.close();
}
}