前言 大多数应用程序都需要实现与设备之间的数据传输,例如键盘可以输入数据,显示器可以显示程序的运行结果等。在Java中,将这种通过不同输入输出设备(键盘,内存,显示器,
前言
大多数应用程序都需要实现与设备之间的数据传输,例如键盘可以输入数据,显示器可以显示程序的运行结果等。在Java中,将这种通过不同输入输出设备(键盘,内存,显示器,网络等)之间的数据传输抽象的表述为“流”,程序允许通过流的方式与输入输出设备进行数据传输。Java中的“流”都位于Java.io包中,称之为IO(输入输出)流。 IO流:即InputOutput的缩写。
一、了解IO流
编辑
1.IO流的特点
IO流用来处理设备间的数据传输。
Java对数据的操作是通过流的方式。
Java用于操作流的对象都在IO包中。
流按操作数据分为两种:字节流和字符流。
流按流向分为:输入流和输出流
2.流的三种分类方式
按流的方向分为:输入流和输出流
按流的数据单位不同分为:字节流和字符流
按流的功能不同分为:节点流和处理流
3.流的层次结构
IO流的常用基类:
- 字节流的抽象基流:InputStream和OutputStream
- 字符流的抽象基流:Reader和Writer
二、字节流
1.什么是字节流
二进制数字的形式保存,都一个一个的字节,那么传输时一样如此。所以,字节流可以传输任意文件数据。在操作流的时候,我们要时刻明确,无论使用什么样的流对象,底层传输的始终为二进制数据。
2.使用字节流实现文件拷贝
无论是音视频文件还是文本文件底层都是字节组成,因此可以使用字节输入流&字节输出流完成任何形式文件拷贝(只要保证前后文件格式、编码一致没有任何问题)
注意: 字节流不适合读取中文内容输出,(在UTF-8编码中,一个中文字符是3个字节)容易出现截断导致乱码
public static void main(String[] args) {
try {
//创建字节输入流管道
InputStream is = new FileInputStream("E:\\Pictures\\wx_camera_1654694320902.mp4");
//创建字节输入流管道
OutputStream os = new FileOutputStream("C:\\Users\\小茵\\Desktop\\lhy.mp4");
//定义一个1024大小字节数组,用来转移数据
byte[] buffer = new byte[1024];
int len;
while((len = is.read(buffer)) != -1){
os.write(buffer,0,len);
}
System.out.println("复制完成!~~~~~");
//关闭流
os.close();
is.close();
} catch (Exception e) {
e.printStackTrace();
}
}
3.使用try - catch - finally 优化资源释放
finall代码块是最终一定会执行的,可以在在这里完成最后释放资源
public static void main(String[] args) {
InputStream is = null;
OutputStream os = null;
try {
//创建字节输入流管道
is = new FileInputStream("E:\\Pictures\\wx_camera_1654694320902.mp4");
//创建字节输入流管道
os = new FileOutputStream("C:\\Users\\小茵\\Desktop\\lhy.mp4");
//定义一个1024大小字节数组,用来转移数据
byte[] buffer = new byte[1024];
int len;
while((len = is.read(buffer)) != -1){
os.write(buffer,0,len);
}
System.out.println("复制完成!~~~~~");
} catch (Exception e) {
e.printStackTrace();
}finally {
//无论代码正常结束还是出现异常都要执行这里
try {
//先判断非空,然后关闭流
if (os != null)os.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
try {
if (is != null)is.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
4.使用try - catch - resource 进一步优化资源释放
public static void main(String[] args) {
try (
//此处只能放置资源对象,使用完毕后即使出现异常也会自动调用资源对象的close方法关闭资源
//创建字节输入流管道
InputStream is = new FileInputStream("E:\\Pictures\\wx_camera_1654694320902.mp4");
//创建字节输入流管道
OutputStream os = new FileOutputStream("C:\\Users\\小茵\\Desktop\\lhy.mp4");
){
//定义一个1024大小字节数组,用来转移数据
byte[] buffer = new byte[1024];
int len;
while((len = is.read(buffer)) != -1){
os.write(buffer,0,len);
}
System.out.println("复制完成!~~~~~");
} catch (Exception e) {
e.printStackTrace();
}
}
三、字符流
1.什么是字符流
由于字节流读取中文有可能会应截断导致乱码,所以,java就提供了转换流。字符流=字节流+编码表。
编码表:由字符及其对应的数值组成的一张表
2.文件字符输入流 - 每次读取单个字符
读取中文字符不会出现乱码
但性能较慢
public static void main(String[] args) throws IOException {
Reader fr = new FileReader("D:\\IDEA\\untitled1\\练习草稿\\Test1\\src\\data.txt");
int code;
while ((code = fr.read()) != -1){
System.out.print((char) code);
}
}
3. 文件字符输入流 - 每次读取一个字符数组
性能相对于读取单个字符得到了提升
public static void main(String[] args) throws IOException {
Reader fr = new FileReader("D:\\IDEA\\untitled1\\练习草稿\\Test1\\src\\data.txt");
char[] buffer = new char[1024];
int len;
while ((len = fr.read(buffer)) != -1){
String rs = new String(buffer,0,len);
System.out.print(rs);
}
}
4.字符输出流
public static void main(String[] args) throws IOException {
//创建字符输出流管道与目标文件接通
Writer fw = new FileWriter("D:\\IDEA\\untitled1\\练习草稿\\Test1\\src\\data.txt");
//写一个字符出去
fw.write(1);
fw.write('a');
fw.write('哈');
//写一个字符串出去
fw.write("哈哈哈哈哈");
//写一个字符数组出去
char[] chars = "abcdef".toCharArray();
fw.write(chars);
//只写一部分字符数组、字符串
fw.write(chars,0,3);
fw.write("哈哈哈哈哈",0,3);
//关闭
fw.close();
}
总结
- 字节流适合做一切文件数据拷贝
- 字节流不适合读取中文内容输出
- 字符流适合做文本文件的操作(读、写)