一. IO的引入和基本概念
学习前需要回顾的知识:
- 什么是内存,它的特点是什么?内存是计算机的数据存储设备之一,是计算机的工作场所,计算机中所有程序的运行都是在内存中进行的。它的特点是读取数据的速度快,但是内存的容量小,并且断电后内存中的信息会丢失。
- 什么是磁盘,它的特点是什么?硬盘是计算机重要的外部存储设备,它也是计算机存储数据的设备。它里面的数据信息必须要先传递给内存,然后计算机才能获取。它的特点是容量大、断电后仍能保存信息,但是读取数据的速度很慢。
举个简单的例子:在打编写一个Excel表格的时候,如果你忘记保存当前内容,突然断电了,那么当来电时你再次打开电脑,刚才编辑的那个表格还存在吗?显然是不存在的。因为我们在使用Excel程序时,编写进的数据那都是暂存在内存中,而内存的信息是会随着断电而丢失的。但是如果我们及时保存了编写的内容,那么这些数据就不会随着断电而消失。那是因为当我们按下了保存按钮,系统自动的将我们的数据从内存中保存进了磁盘里,而磁盘是可以永久保存数据的。当我们下次还想打开这个表格,系统就会自动地去找磁盘中对应信息,再导入进内存中供计算机使用。上述保存过程便代表着O,而再打开表格的过程代表着I。
我们通常说的I/O系统,I是Input的缩写,就是输入的意思;而O是Output的缩写,就是输出的意思。这里的IO是指在内存和外部系统之间互相传输大量数据的意思,将数据写入内存叫输入,从内存读取数据叫输出。其中,最常见的外部系统有:磁盘(文件)、数据库、键盘(只有输入过程)等等。既然数据的IO是内存和外部系统之间的信息交换,那么我们肯定要选择一个外部系统,以现阶段水平我们就以典型的内存和磁盘之间的数据传递作为以后学习IO的方式了。
数据是以文件的形式存储在磁盘上的。
二. 流的概念
流(Stream)是一种抽象、动态的概念,它代表了数据的无结构化传递。数据从一块地方传输到另一块地方就是一个动态、无结构化的过程,我们就用“流”来形容:
对于输入流而言,数据源就像水源头,流就像水管中流动着的水流,程序就是我们最终的用户。我们通过流将数据源(Source)中的数据(information)输送到程序(Program)中。
对于输出流而言,目标数据源就是目的地(destination),我们通过流将程序中的数据(information)输送到目的数据源中。
三. Java中流的分类
第一种: 按流的方向分类:
-
输入流:数据流向是数据源到程序(以InputStream、Reader结尾的流),如:磁盘–>内存。
-
输出流:数据流向是程序到目的地(以OutPutStream、Writer结尾的流),如:内存–>磁盘。
第二种: 按处理的数据单元分类:
- 字节流:以字节为单位获取数据,命名上以Stream结尾的流一般是字节流,如FileInputStream、FileOutputStream。
- 字符流:以字符为单位获取数据,命名上以Reader/Writer结尾的流一般是字符流,如FileReader、FileWriter。
一个字符一般为两个字节(B),一个字节又等于8位二进制数(bit)。
第三种: 按处理对象不同分类:
- 节点流:可以直接从数据源或目的地读写数据,如FileInputStream、FileReader、DataInputStream等。
- 处理流:不直接连接到数据源或目的地,是”处理流的流”。通过对其他流的处理提高程序的性能,如BufferedInputStream、BufferedReader等。处理流也叫包装流。
节点流处于IO操作的第一线,所有操作必须通过它们进行。
处理流可以对节点流进行包装,提高性能或提高程序的灵活性。
四. Java中IO流 相关类的体系
图示:
总结关键点:
-
InputStream/OutputStream:
字节流的抽象类。 -
FileInputStream/FileOutputStream:
节点流:以字节为单位直接操作“文件”。 -
ByteArrayInputStream/ByteArrayOutputStream:
节点流:以字节为单位直接操作“字节数组对象”。 -
ObjectInputStream/ObjectOutputStream:
处理流:以字节为单位直接操作“对象”。 -
DataInputStream/DataOutputStream:
处理流:以字节为单位直接操作“基本数据类型与字符串类型”。 -
BufferedInputStream/BufferedOutputStream
处理流:将InputStream/OutputStream对象进行包装,增加缓存功能,提高 读写效率。 -
Reader/Writer:
字符流的抽象类。 -
FileReader/FileWriter:
节点流:以字符为单位直接操作“文本文件”(注意:只能读写文本文件)。 -
BufferedReader/BufferedWriter:
处理流:将Reader/Writer对象进行包装,增加缓存功能,提高读写效率。 -
InputStreamReader/OutputStreamWriter:
处理流:将字节流对象转化成字符流对象。 -
PrintStream:
处理流:将OutputStream进行包装,可以方便地输出字符,更加灵活。
五. File类
既然我们的主要学习内容是程序和文件之间的数据传递(内存 <–> 磁盘),那么我们就有必要更加全面一下java.io.File类。
看相应API之前先来了解一些基本概念:
- 绝对路径:从盘符开始的完整路径。比如:D:\MyCode_Java\Java_Learning\a.txt。
- 相对路径:是从当前路径开始的路径。比如:Java_Learning\a.txt。那么这个当前路径就是D:\MyCode_Java,从当前路径开始的路径。
File类的构造方法:
package cn.zjb.test;
import java.io.File;
/**
* 测试文件类
* @author 张坚波
*
*/
public class TestFile {
public static void main(String[] args) {
/*
* 路径可以是文件结尾,也可以是文件夹结尾;
* 可以是存在的,也可以是不存在的;
* 可以是正确的,也可以是错误的。
*/
File file1 = new File("file1.txt"); //相对路径:现在只是创建好对象,还没生成该文件,如果用方法生成文件,那么它会被默认放到该项目的目录下面。
System.out.println(file1); //file1.txt
File file2 = new File("C:\\file2.txt"); //绝对路径 。'\'用转义字符'\\'表示。
System.out.println(file2); //C:\file2.txt
File file3=new File("C:\\","file3.txt"); //两个字符串的顺序组合
System.out.println(file3); //C:\file3.txt
File file4= new File(file3,"a.txt");
System.out.println(file4); //C:\file3.txt\a.txt
}
}
File类的静态属性:
不同系统中,文件分隔符和路径分隔符是不一样的,比如:
- windows: 路径分隔符—— 分号’ ; ’ 文件分隔符—— 反斜杠’ \ '。
- Linux: 路径分隔符—— 冒号 ’ : ’ 文件分隔符—— 正斜杠’ / '。
package cn.zjb.test;
import java.io.File;
/**
* 测试文件类
* @author 张坚波
*
*/
public class TestFile {
public static void main(String[] args) {
System.out.println(File.pathSeparator); //;
System.out.println(File.pathSeparatorChar); //;
System.out.println(File.separator); // \
System.out.println(File.separatorChar); // \
}
}
File类常用方法:
package cn.zjb.test;
import java.io.File;
import java.io.IOException;
/**
* 测试文件类
* @author 张坚波
*
*/
public class TestFile {
public static void main(String[] args) throws IOException {
File file1=new File("file1.txt");
file1.createNewFile();//该方法须抛出 IOException异常
System.out.println(file1.getAbsolutePath()); //D:\MyCode_Java\Java_Learning\file1.txt
System.out.println(file1.getCanonicalPath()); //D:\MyCode_Java\Java_Learning\file1.txt
File file2=new File("D:\\MyCode_Java\\Java_Learning\\a.txt"); //已存在的文件,内容是is empty,大小是8字节。
System.out.println(file2.exists()); //true
System.out.println(file2.createNewFile()); // false
System.out.println(file2.getName()); //a.txt
// file2.delete();
System.out.println(file2.length()); //8
}
}
相对路径是eclipse当前项目文件夹的相对路径。Java_Learning是该项目的文件夹名称。
File类中并没有相关IO的操作方法(当然创建和删除文件算是,不过没对文件的内容进行读写),在后续的IO流相关类中才有具体体现,但File类是它们的基础,找不到相应文件怎么进行读写!