JAVA语言入门教学系列之IO篇
本文主要向大家介绍了JAVA语言入门教学系列之IO篇,通过具体的内容向大家展示,希望对大家学习JAVA语言有所帮助。
前戏
有很多同学单纯的认为IO不就是一个读文件和写文件吗,不重要,只要简单的复制粘贴就OK,
会用个File以及什么流就算"熟练掌握 "了。
使用场景也就上传文件才用的到,仅此而已。
呵呵呵呵,那就大错特错了,IO的使用范围很广,最能体现IO价值的就是网络上的数据传递,
尤其是进入互联网时代后,各种常见的分布式架构,都少不了IO的体现。
并且很多大厂的面试题中都会体现出对IO的重视,包括衍生出来的NIO、序列化等等。
因此学好IO,变成了一件很重要的事情。
IO基本概念
IO可以简单的理解成INPUT和OUT,代表输入输出的意思。输入就是读,输出就是写。
IO可以读写硬盘、光盘、内存、键盘、网络等资源上的数据。
流
IO中的流就相当于现实生活中的水流一样,一打开自来水的龙头开关,水就从一头流向另一头。
可以理解成每个按顺序排列的水滴就是需要传输的字节。
把有序数据理解成流,流负责传输数据,以便于输入输出。数据是流动的,是有方向的流动。
流的分类
按数据的走向可以分为:输入流,输出流。
按数据的单位可以分为:字节流、字符流。
按装饰模式可以分为:节点流(底层)、处理流(上层)。
输入流与输出流
输入流:只能从中读取数据,而不能向其写入数据。一般用于将数据从网络、硬盘读取到内存中。
输出流:只能向其写入数据,而不能从中读取数据。一般用于将数据从内存中写入到网络、硬盘。
输入流主要由InputStream和Reader作为父类。
输出流主要由OutputStream和Writer作为父类。
他们都是抽象的,因此无法直接创建对象。
字节流与字符流
字节流与字符流的用法几乎完全一样,区别在于所操作的单位不同,字节流操作8位的字节,
而字符流操作16位的字符。
字节流主要由InputStream和OutputStream作为父类。
字符流主要由Reader和Writer作为父类。
节点流与处理流
节点流(上层):
向特定的节点写入&读取数据的流。程序连接到实际的数据源,和实际的输入输出节点连接。
处理流(底层):
对一个已存在的流进行连接或封装,通过封装后的流来实现数据读写功能。
使用处理流进行输入输出时,程序不会和实际的输入输出节点连接,对底层的处理流做了一层封装。
程序可以采用相同的输入输出代码来访问不同的数据源。(涉及到装饰器模式)
处理流使得java程序无需理会输入输出的节点是磁盘、网络还是其他,
只要将这些节点流包装成处理流,
就可以使用相同的输入输出代码来读写不同的输入输出设备的数据。
节点流用于和底层的物理存储节点直接关联,不同的物理节点获取节点流的方式可能存在差异。
程序可以把不同的物理节点流包装成统一的处理流,
允许程序使用统一的输入输出代码来读写不同的物理存储节点资源。
常用的输入输出流体系
io流按功能分成许多类,每个功能又提供字节流&字符流,
字节流与字符流又分别提供了输入流与输出流。
如果输入输出的是文本内容可以使用字符流,如果输入输出的是二进制内容,可以使用字节流。
字节流
字节流是IO最原始的方式,因为计算机处理数据总是以一个byte为基本单位的,
字节流就是每次读取的单位为byte。字节流是所有流的基础,也是其他高级流的前提。
字节流可以处理所有类型的数据,包括:音乐、图片、文字、视频、各种文件等等。
多数以"Stream"结尾的类都是字节流。
字符流只能处理文本,读写的单位是字符。多数以"Writer"与"Reader"结尾的类都是字节流。
java的基础字节流的类为:InputStream,OutputStream。
通过他们俩可以衍生出许多子类,常见的有:
FileInputStream,FileOutputStream,ObjectInputStream,ObjectOutputStream,BufferedInputStream,BufferedOutputStream等。
byte是计算机最基本的单位,所以字节流可以应付几乎所有的流的处理,只不过,在处理具体数据格式的时候,效率没有具体的实现类高,如字符格式,对象格式等。主要操作对象是byte数组,
通过read()和wirte()方法把byte数组中的数据写入或读出。
使用字节流复制文件
public class FileInputOutStreamDemo1 {
public static void main(String[] args) {
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis = new FileInputStream("enya恩雅-only time.mp3");
fos = new FileOutputStream("new-enya恩雅-only time.mp3");
byte[] temp = new byte[1024];
while(fis.read(temp)!=-1) {
fos.write(temp);
}
temp = new byte[1024];
//将字符串写入到文件
fos = new FileOutputStream("aaa.txt");
fos.write("我爱你亲爱的姑娘".getBytes());//直接覆盖,而不是追加。如果想追加怎么办?
fis = new FileInputStream("aaa.txt");
fis.read(temp);
System.out.println(new String(temp));
} catch (Exception e) {
e.printStackTrace();
} finally {
if(fis!=null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(fos!=null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
System.out.println("结束");
}
}
可以理解成把输入数据想象成存储在一个水管当中,
输入流的read()方法从水管中读取一个或多个水滴,
水滴的单位是字节或字符,当使用数组作为读取方法参数时,read(byte []),
这个数组相当于一个竹筒,
使用竹筒去水管中取水,程序重复这个取水的过程,直到read(byte [])返回-1为止。
字符流
针对文本文件,使用字符流来写入和读出字符数据。无需再使用字节流进行包装,
字符流是由字节流包装而来,
它包括:StringReader,StringWriter,BufferedReader,BufferedWriter。
对于前者,他们的使用方法和字节流类似,主要还是read()和wirte(),
而后者多加了一个readLine()方法,用于读取文章类型的文本。
FileReader、FileWriter,节点流,会直接和指定文件相关联。
使用字符流复制文本文件
public class FileWriterDemo1 {
public static void main(String[] args) {
FileReader fr = null;
FileWriter fw = null;
try {
char[] temp = new char[1024];
// 将字符串写入到文件
fw = new FileWriter("aaa.txt");
fw.write("我爱你亲爱的姑娘55555");// 直接覆盖,而不是追加。如果想追加怎么办?
fr = new FileReader("aaa.txt");
fr.read(temp);
System.out.println(new String(temp));
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fr != null) {
try {
fr.close();
} catch (IOException e) {
e.printStackTrace();
}
if (fw != null) {
try {
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
System.out.println("结束");
}
}
字符流对象在创建时,一般需要提供一个输入or输出流。
例如在创建BufferedReader或者BufferedWriter对象时,
需要提供InputStreamReader或OutputStreamWriter对象。
对于特定支付格式的文本内容,还需要在创建的时候提供字符格式类型作为构造参数。
小例子:字符输入流
File f = new File("D:\\VSS存放目录\\KOOF\\3-开发阶段\\3.3-数据库","koof30.sql");
FileReader fi = new FileReader(f);
BufferedReader in = new BufferedReader(fi);
String s ;
String total = "";
while((s=in.readLine())!=null){
total += s+"\n";
}
处理流(上层)与节点流(底层)
处理流隐藏底层设备上节点流的差异,并对外提供更加方便的输入输出方法,
让我们只关心上层流的操作,有点像应用层的感觉。
可以使用处理流来包装节点流,通过处理流执行输入输出功能,
节点流则负责与底层的IO设别、文件交互。
处理流的构造参数不是一个物理节点,而是已经存在的节点流,而节点流的构造参数都是物理节点。
上面的例子都是使用节点流(FileInputStream、FileOutputStream、FileReader、FileWriter)。
在使用节点流过程中比较繁琐,因此我们可以使用处理流。
public class PrintStreamDemo1 {
public static void main(String[] args) {
PrintStream ps = null;
try {
ps = new PrintStream(new FileOutputStream("bbb.txt"));
&nb
最后,如果你跟我一样都喜欢java,想成为一名优秀的程序员,也在学习java的道路上奔跑,欢迎你加入java学习群:72030155 群内每天都会分享java最新业内资料,分享java免费课程,共同交流学习,让学习变(编)成(程)一种习惯!