l IO 流的分类
- IO流的分类
l 流向:(不管是输入流还输出流都是相对于你当前的程序而言的)
输入流:读进来数据: read
输出流 写出去数据: write
l 输出的内容分:
字节数据:图片.视频.音频
字节输入流: InputStream(抽象类)
字节输出流: OutputStream
字符数据:abcd,你我他(底层也是字节数据存储,但是已经经过了解码)
字符输出流: Reader
字符输出流: Writer
不管是字符流还是字节流,底层流动的都是字节
FileOutputStream(File file)创建一个向指定 File 对象表示的文件中写入数据的文件输出流。
FileOutputStream(String name)创建一个向具有指定名称的文件中写入数据的输出文件流。
1 /**
2 *
3 FileOutputStream(File file)创建一个向指定 File 对象表示的文件中写入数据的文件输出流。
4
5 FileOutputStream(String name)创建一个向具有指定名称的文件中写入数据的输出文件流。
6 */
7 public class FileOutputStreamDemo01 {
8 public static void main(String[] args) throws Exception {
9 //创建流对象
10 FileOutputStream output = new FileOutputStream("a.txt");
11 //上面代码干了两件事1创建了管道2把管道搭到了a.txt文件上(流对象会帮我们创建a.txt文件)
12
13 //创建数据
14 String data = "hello,IO";//可以调用String的getBytes()方法转化为字节数组
15 byte[] bytes = data.getBytes();
16
17 //通过管道把数据写进文件
18 output.write(bytes);
19
20 //关闭资源
21 output.close();
22 }
23 }
1 /**
2 * 3种output.write的重载方法
3 */
4 public class FileOutputStreamDemo02 {
5 public static void main(String[] args) throws Exception {
6
7 FileOutputStream output = new FileOutputStream("b.txt");
8
9 String data = "hello,IO";
10
11 //byte[] bytes = data.getBytes();
12 //output.write(bytes);
13
14 /* output.write(97);
15 output.write(98);
16 output.write(99);*/ //结果写入abc
17
18 /*byte[] bs = data.getBytes();
19 output.write(bytes,0,4);*/ //结果写入hello
20
21
22 output.close();
23
24 }
25 }
inputStream
FileInputStream(String name)通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的路径名 name 指定。
FileInputStream(File file)通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的 File 对象 file 指定。
1 /**
2 *FileInputStream(String name)通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的路径名 name 指定。
3 FileInputStream(File file)通过打开一个到实际文件的连接来创建一个 FileInputStream,该文件通过文件系统中的 File 对象 file 指定。
4 */
5 public class FileOutputStreamDemo01 {
6 public static void main(String[] args) throws IOException {
7 //创建流对象
8 FileInputStream input = new FileInputStream("a.txt");
9
10 //开辟空间读取数据
11 byte[] date = new byte[1024];
12 int len = input.read(date);//将输入流的内容读取到字节数组中,并返回文件的字节长度
13 String str = new String(date,0,len);//调用String的构造方法,将字节数组返回string类型
14
15 //打印读取内容
16 System.out.println(str);//输出:hello,IO
17 //关闭资源
18 input.close();
19 }
20
21 }
字符输出流: Writer
Writer:
FileWriter.在使用Writer类进行输出的时候最大的做操特点在于其可以直接进行字符串的数据处理
重点输出方法
void write(String str, int off, int len)写入一部分字符串。
public FileWriter(String fileName,boolean append)throws IOException
构造一个FileWriter对象,给出一个带有布尔值的文件名,表示是否附加写入的数据。
参数
fileName - String系统相关的文件名。
append - boolean如果是 true ,那么数据将被写入文件的末尾而不是开头。
总结:使用Writer可以实现与OutputStream类似的功能,但是其最大的优势在于可以直接进行字符转数据的输出!
void write(String str, int off, int len)写入一部分字符串。
public FileWriter(String fileName,boolean append)throws IOException
构造一个FileWriter对象,给出一个带有布尔值的文件名,表示是否附加写入的数据。
参数
fileName - String系统相关的文件名。
append - boolean如果是 true ,那么数据将被写入文件的末尾而不是开头。
总结:使用Writer可以实现与OutputStream类似的功能,但是其最大的优势在于可以直接进行字符转数据的输出!
1 /**
2 * void write(String str, int off, int len)写入一部分字符串。
3 */
4 public class FileWriterDemo01 {
5
6 public static void main(String[] args) throws IOException {
7 //实例化write类对象
8 FileWriter out = new FileWriter("a.txt");
9
10 //调用write方法写出
11 out.write("IO,hello!");//输出
12 out.append("Good");//追加
13
14 //关闭资源
15 out.close();
16
17 }
18 }
Reader(抽象):
FileReader.
重点方法:
int read(char[] cbuf, int off, int len)将字符读入数组的某一部分。
1 /**
2 * int read(char[] cbuf, int off, int len)将字符读入数组的某一部分。
3 */
4 public class FileReaderDemo01 {
5
6 public static void main(String[] args) throws IOException {
7
8 //创建FileReader对象
9 FileReader in = new FileReader("a.txt");
10
11 char[] data = new char[1024];
12 /*int len = in.read(data);//读取的字符数组中
13 String str = new String(data,0,len);
14
15 //输出读取内容
16 System.out.println(str);
17 //关闭资源
18 in.close();*/
19 try {
20
21 int len = in.read(data);//读取的字符数组中
22 String str = new String(data,0,len);
23
24 //输出读取内容
25 System.out.println(str);
26
27 }catch (Exception e){
28
29 }
30 }
31
32 }
区别主要在于字节和字符的读取,写入方式
到此为止发现四个类实际上都是AutoCloseable的子类,所以对于打开和关闭资源可以利用自动关闭.即将执行代码放入try块中执行.可自动关闭资源,无需在手工调用close方法;
- 以上4种基本流介绍完毕
总结一下字节流和字符流的区别:
1字节操作属于基础的二进制数据流的操作形式,在网络,文件等操作之中几乎都是以字节数据为主的,但是不方便对中文处理,所以涉及中文的操作应该使用字符流.
2在进行网络传输或者磁盘数据进行存储的时候,都是字节数据
在字符输出流中.(writer)最后如果不调用close或者flush(强制清空缓冲区的方法)方法,则输出内容可能不会写入的文件中,因为这些内容还保存在缓冲区,并没有被真正的写入;
所以本质上传递的所有内容只有字节,而字符是程序对字节的包装,功过之前的分析可以发现,字节流和字符流的使用非常相似,重点以字节流处理为主,除非有中文操作
对于两种数据流
字节流和字符流对比可知,字符流在进行中文操作的时候更加方便,所以为了方便实现字节流与字符流的转换处理,又提供了两个类:
转换流
OutputStreamWriter
InputStreamReader
字节流和字符流对比可知,字符流在进行中文操作的时候更加方便,所以为了方便实现字节流与字符流的转换处理,又提供了两个类:
转换流
OutputStreamWriter
InputStreamReader
继承结构:
OutputStreamWriter
InputStreamReader
通过两者继承的关系发现,InputStreamReader,OutputStreamWriter 都是字符流的子类,同时又可以通过构造方法接收InputStream和OutputStream类的实例.
FileWriter.FileReader的继承关系
可见转换流是字符输出输入流的父类!
附完成复制粘贴功能的实现
1 package com.wzy.io.copyDemo;
2
3
4 import java.io.*;
5
6 class CopyUtil{
7 private File srcFile;//拷贝的源文件路径
8 private File desFile;//拷贝的目标文件路径
9
10 public CopyUtil(String[] args){
11 if(args.length!=2){
12 System.out.println("参数不正确,正确格式为:“源文件路径 目标文件路径”");
13 System.exit(1);//程序结束
14 }
15 this.srcFile = new File(args[0]);
16 this.desFile = new File(args[1]);
17 }
18 /**实现拷贝的操作处理
19 * @return 返回本次拷贝所花费的时间,如果拷贝失败如下返回结果
20 * -1:表示源文件不存在
21 * -2:表示目标物件无法拷贝
22 */
23 public int copy() throws IOException {
24 if(!srcFile.exists()){
25 return -1;
26 }
27 if(!desFile.getParentFile().exists()){
28 desFile.getParentFile().mkdirs();
29 }
30 long start = System.currentTimeMillis();
31 InputStream input = null;
32 OutputStream output = null;
33 try {
34 input = new FileInputStream(this.srcFile);
35 output = new FileOutputStream(this.desFile);
36
37 byte[] data = new byte[1024];
38 int len = 0;
39
40 while ((len=input.read(data))!=-1){
41 output.write(data,0,len);
42 }
43
44 }finally {
45
46 try {
47 if (input != null)
48 input.close();
49 } catch (IOException e) {
50 e.printStackTrace();
51 }
52 try {
53 if (output != null)
54 output.close();
55 } catch (IOException e) {
56 e.printStackTrace();
57 }
58
59 }
60 long end = System.currentTimeMillis();
61
62 return (int) (end-start);
63 }
64 }
65
66
67 public class Demo {
68 public static void main(String[] args) throws IOException {
69
70 CopyUtil cu = new CopyUtil(args);//实例化对象
71 System.out.println(cu.copy());//调用拷贝方法
72 }
73 }