Java高级特性
第三章 输入和输出(一)
1、无论是变量、数组、集合还是对象等数据结构,其存储的数据都是在计算机的内存中,内存中存储数据的最大特征:一旦内存断电,存储的数据将会消失,数据无法进行持久保存。
2、为了能够将数据持久化保存,那么需要将数据存储在硬盘上,我们将数据存储在硬盘的过程就称之为数据持久化。
一、操作文件或目录
1、File类
(1)数据在硬盘上会以文件的形式进行存储。
(2)在Java中,所有硬盘上的文件都会以一个个独立的java.io.File对象存在,通过java.io.File对象来操作硬盘上的相关文件数据。
(4)在程序中一个File对象可以表示一个文件或者目录。
2、File分类
分别存储文件和文件夹(目录)。
但无论是文件还是目录,对应到Java世界中,都是一个个File对象。
3、相对路径和绝对路径
无论是创建文件还是目录的File对象,都需要设定该文件或者目录的路径,因此产生了绝对路径和相对路径。
(1)绝对路径:指的是从根目录下开始计算该文件或者目录的路径。无论在哪个路径下,都可以通过绝对路径找到某个文件或者文件夹。
(2)相对路径:指的是相对于现在所在的文件或者是目录开始计算的路径,只有从现在所处的文件或者是目录开始,根据相对路径才能够找到对应的文件或者目录;当现在所处的文件或者目录一旦发生改变,那么按照原来的相对路径进行查找,将无法找到对应的文件或者目录。
4、对File对象的操作
public class FileDemo01 {
public static void main(String[] args) {
//1、 要想操作硬盘上任何一个文件,那么需要设定该文件的所在路径
String filePath = "E:\\hello.txt";
// 2、根据该文件的路径,创建该文件所对应的 java.io.File 对象
File file = new File(filePath);
// 3、当获得该 File 对象之后,就可以完成对该文件的操作
// 判断该文件是否存在,通过 exists() 能够进行判断
boolean isExists = file.exists();
System.out.println("该文件是否存在:" + isExists);
try {
// 要想在硬盘上创建一个文件,那么使用 createNewFile() 完成
// 在创建文件时,如果该文件已经存在,那么不会再二次创建
boolean isCreateSuccess = file.createNewFile();
System.out.println("该文件是否创建成功:" + isCreateSuccess);
// 获得该文件的文件名
String fileName = file.getName();
System.out.println("这个文件的文件名是:" + fileName);
// 获得该文件的绝对路径
String absFilePath = file.getAbsolutePath();
System.out.println("这个文件的绝对路径是:" + absFilePath);
// 获得该文件的大小
// 系统保留给该文件在操作时的记录数据空间
long freeSpace = file.getFreeSpace();
// 系统在创建该文件时,文件内容空间加上用于记录的空间和保留空间
long totalSpace = file.getTotalSpace();
// 系统操作时,所占用的记录空间
long useableSpace = file.getUsableSpace();
System.out.println("freeSpace = " + freeSpace);
System.out.println("totalSpace = " + totalSpace);
System.out.println("usableSpace = " + useableSpace);
// 该文件的内容大小,单位是字节
long fileSize = file.length();
System.out.println("该文件的大小:" + fileSize);
// 如果操作完毕后,需要删除该文件,则通过 delete() 完成
boolean isDelete = file.delete();
System.out.println("该文件是否删除:" + isDelete);
} catch (IOException e) {
e.printStackTrace();
}
}
}
5、File类的常用方法
补充:
mkdir() :只能够创建一级目录,如果该目录的外层目录不存在,那么该目录是无法创建的。
mkdirs() :能够创建多级目录,如果该目录的外层目录不存在,那么会一起进行创建。
注意:目录相当于路径,而文件则是存储数据的。
获得目录下面的所有文件/子文件:
File[] files = folder.listFiles();
for (File file : files) {
System.out.println(file.getName());
}
二、Java中的I/O流
- 想要将程序中所产生的数据写入到文件中,或者是将文件中的数据读入到程序中,那么需要使用I(Input输入)/O(Output输出)流来实现。
- “流”指一连串流动的字符,是以先进先出的方式发送和接收数据的通道。
1、Java所提供的流的分类
(1)按照流的方向:
(2)按操作的数据:
(3)对于计算机来说,最基本的单位就是字节,因此最基本的流就是字节流。字符流只是在字节流的基础之上,完善了对字符的编码,因此可以对字符进行更好的操作。
2、字节输入流 FileInputStream
要想将文件中的数据传输到 Java 程序中,那么借助于输入流即可,对于输入流就来说,最基本的FileInputStream。
(1)将程序从文件中读取到程序中
// 1、设定需要读取的文件路径
String filePath = "E:\\HelloWorld.txt";
//2、 根据文件路径,创建其对应 File 对象
File file = new File(filePath);
// 3、初始化 FileInputStream 类型的变量 in
FileInputStream in = null;
try {
// 4、根据 File 对象创建 FileInputStream
in = new FileInputStream(file);
// 当创建完成 FileInputStream 对象之后,此时文件到程序的管道铺设完成,
// 下面就可以借助于输入流完成对文件数据的读取
// FileInputStream 在读取文件时,是一个字节一个字节的读取,所读到的就是这个字节的编码
// 5、声明一个 int 类型变量 i 用于存储此时所读取到的字节
int i;
// 由于一个文件中会存在多个数据,那么会读取多次
// 6、因为文件数据大小未知,只要当文件未读取完毕,就需要进行循环,如果读取完毕循环停止,当读取到的编码为 -1 时,
// 标志着文件读取完毕
while ((i = in.read()) != -1) {
// 此时 i 的值就是当前所读到数据的字节编码,也就是 ASCII
System.out.println(i);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
// 7、无论是否在数据传输过程中产生异常,都必须将流进行关闭
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
(2)缓冲区
当文件过大时,如果一个个字节进行读取,效率极低。为了提高效率,可以使用一个byte[]作为缓冲区,所谓缓冲区就是首先江都区的字节存储到缓冲区中,当缓冲区中的数据存满时,再一次性交给程序使用。
// 根据 File 对象创建 FileInputStream
in = new FileInputStream(file);
// 声明 int 类型变量 i
int i;
byte[] buffers = new byte[1024];
// 循环读取文件数据
// 有了缓冲区后,就可以首先将内容存储到缓冲区中
while ((i = in.read(buffers)) != -1) {
// 当存在缓冲区之后,那么 i 就不再是一个个字节的编码,
// 而是此时缓冲区中所存储字节的个数,
// 也就是此时 byte[] 中有元素的个数。
System.out.println(i);
3、字节输出流 FileOutputStream
(1)将程序中所产生的数据存储到文件中
public static void main(String[] args) {
// 1、根据文件路径创建 File 对象
File file = "E:\\test.txt";
//2、 初始化 FileOutputStream 类型变量
FileOutputStream out = null;
try {
// 3、根据 File 对象创建 FileOutputStream
out = new FileOutputStream(file);
// 4、对于输出流来说,可以一次性的将所有的数据都写到文件中,
// 此时所写出的数据必须是 byte 编码或者是 byte[]
String message = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
//5、 如果需要将 message 写入到文件中,那么需要将其变为 byte[]
byte[] bytes = message.getBytes();
// 6、通过 FileOutputStream 将数据写入到文件中
out.write(bytes);
} catch (IOException e) {
e.printStackTrace();
} finally {
// 7、无论在写入过程中是否有异常,都需要关闭输出流
try {
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
注意:对于输出流来说,写入时,如果文件不存在,会自动创建文件。
(2)默认情况下,向文件中写数据时将覆盖原文件中的数据。
如果需要在原文件的基础上进行内容的追加,则需要在创建FileOutputStream对象时,进行设定。
out = new FileOutputStream(file, true);
其中boolean类型的值为true表示进行追加,值为false表示进行覆盖。如果不添加boolean类型的值,则默认是false。