File与Io流
一、File类的使用
1.File类的理解
File类位于java.io包下,本章中涉及到的相关流也都声明在java.io包下
File类的一个对象,对应与操作系统下的一个文件或一个文件目录(或文件夹)
File类中声明了新建、删除、获取名称、重命名等方法,并没有涉及到文件内容的读写操作,要想实现文件内容的读写,我们需要IO流
File类的对象,通常是作为io流的文件的端点出现的。
2.内部api使用说明
- 构造器:
public File(String pathname):以pathname为路径创建File类对象,可以是绝对路径或者相对路径
public File(String parent , String child):以parent为父路径,child为子路径创建File对象。
public File(File parent , String child):根据一个父File对象和子文件路径创建File对象
- 方法
获取文件和目录基本信息
public String getName():获取名称
public String getPath():获取路径
public String getAbsolutePath():获取绝对路径
public File getAbsoluteFile():获取绝对路径表示的文件
public String getParent():获取上层文件目录路径。若无,返回null
public long length():获取文件长度(即:字节数)。不能获取目录的长度
public long lastModified():获取最后一次的修改时间,毫秒值列出目录的下一级
public String[] list():返回一个String数组,表示该File目录中的所有子文件或目录。
public File[] listFiles():返回一个File数组,表示该File目录中的所有的子文件或目录。File类的重命名+移动文件功能
public boolean renameTo(File dest):把文件重命名为指定的文件路径并移动到指定的文件路径
判断功能的方法
public boolean exists():此File表示的文件或目录是否实际存在。
public boolean isDirectory():此File表示的是否为目录。
public boolean isFile():此File表示的是否为文件。
public boolean canRead():判断是否可读
public boolean canWrite():判断是否可写
public boolean isHidden():判断是否隐藏创建删除功能
public boolean createNewFile():创建文件。若文件存在,则不创建,返回false
public boolean mkdir():创建文件目录。如果此文件存在,就不创建了。如果此文件目录的上级目录不存在则创建失败
public boolean mkdirs():创建文件目录。如果上层文件目录不存在,一并创建。
public boolean delete():删除文件或者文件夹
删除注意:
Java中的删除不走回收站
要删除一个文件目录,请注意该文件目录内不能包含文件或者文件目录。
- 文件的路径表示方式
方式一:绝对路径,以windows操作系统为例,包括盘符在内的文件或文件目录的完整路径。
方式二、相对路径:相对于某一个文件目录来讲的相对的位置。
- 在IDEA中
如果使用单元测试方法:相对于当前的module来讲
如果使用main()方法:相对于当前的project来讲
二、IO流概述与文件流的使用
1.IO流的分类
流向的不同:输入流、输出流
处理单位的不同:字节流、字符流
流的角色不同:节点流、处理流
2.基础IO流的框架
抽象基类 | 4个节点流(也称为文件流) |
---|---|
InputStream | FileInputStream |
OutputStream | FileOutputStream |
Reader | FileReader |
Writer | FileReader |
3.FileReader\FileWriter的使用
- 执行步骤
第一步:创建读取或写出的File类对象
第二步:创建输入流或输出流
第三步:具体的读入或写出的过程
读入:read(char[] cbuffer)
写出:write(String str)/write(char[] cbffer , int off , int len)
第四步:关闭流资源,避免内存泄露
FileWriter案例:
@Test
public void test2(){
//1.创建File类的对象,指明要写出的文件的名称
File file = new File("info.txt");
FileWriter fileWriter = null;
try {
//2,创建File类的对象,指名要写出的文件的名称
/*构造器一:.覆盖文件,使用的构造器
fileWriter = new FileWriter(file);
fileWriter = new FileWriter(file , false);
构造器二:.在现有文件的基础上,追加内容使用的构造器*/
fileWriter = new FileWriter(file, true);
//3、写出的具体过程!
fileWriter.write("嘿嘿嘿\n");
fileWriter.write("沃茨\n");
fileWriter.write("哈哈哈!\n");
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
//4、关闭资源
if (fileWriter != null){
fileWriter.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
- 注意点:
因为涉及到流资源的关闭操作,所以出现异常的话,需要使用try-catch-finally的方式来处理异常
对于输入流来讲,要求File类的对象对应的物理磁盘上的文件必须存在。否则,会报FileNotFoundExcepton
对于输出流来讲,File类的对象对应物理磁盘上的文件可以不存在,如果不存在则自动创建,如果存在则根据构造器中的append真值进行覆盖或追加操作
3.FileInputStream\FileOutputStream的使用
- 执行步骤
第一步:创建读取或写出的File类对象
第二步:创建输入流或输出流
第三步:具体的读入或写出的过程
读入:read(byte[] buffer)
写出:write(String str)/write(char[] bffer , int off , int len)
第四步:关闭流资源,避免内存泄露
- 注意点
对于字符流,只能用来操作文本文件,不能用来处理非文本文件。
对于字符流,通常用来操作非文本文件,但是,如果涉及到文本文件的复制操作,也可以使用字节流
三、缓冲流的使用
1.基础框架
抽象基类 | 4个节点流(也称为文件流) | 缓冲流 |
---|---|---|
InputStream | FileInputStream | BufferedInputStream |
OutputStream | FileOutputStream | BufferedOutputStream |
Reader | FileReader | BufferedReader |
Writer | FileReader | BufferedWriter |
2.缓冲流的作用
- 提升文件读写的效率
3.四个缓冲流的使用
- 处理非文本文件的字节流:
BufferedInputStream read(byte[] buffer)
BufferedOutputStream write(byte[] buffer , 0 , len) 、 flush()刷新,主动将内存保存的数据写入磁盘
- 处理文本文件的字符流:
BufferedReader read(char[] cbuffer) / readLine() 读入一行,返回的字符串不包含换行符
BufferedWrite write(char[] cbuffer, 0 , len ) 、 flush()
4.实现的步骤
- 第一步:创建File的对象、流的对象(包括文件流、缓冲流)
- 第二步:使用缓冲流实现 读取数据或写出数据的过程(重点)
读取:
int read(char[] cbuf / byte[] buffer):每次将数据读入到cbuf / buffer数组中,并返回读入数组中
写出:
void write(String str) / write(char[] cbuf):将str或cbuf写出到文件中
void write(byte[] buffer) :将byte[]写出到文件中
- 第三步:关闭资源
四、转化流的使用
1.复习编码解码
- 字符编码:字符、字符串、字符数组---->字节、字节数组(从看得懂的---->看不懂的)
- 字符解码:字节、字节数组------>字符、字符串、字符数组(从看不懂的->看不懂的)
2.程序在读取文本时不出现乱码需要注意什么
- 解码时使用的字符集必须与当初编码时使用的字符集得相同。
3.转换流
- 作用:实现字节与字符之间的转换
- API:
InputStreamReader:将一个输入型的字节流转换为输入型的字符流
OutputStreamWriter;将一个输出型的字符流转换为输出型的字节流
五、对象流的使用
- 数据流及其作用
DataOutputStream:可以将内存中的基本数据类型的变量、String类型的变量写出到具体的文件中
DataInputStream:将文件中保存的数据还原为内存中的基本数据类型的变量、String类型的变量
- 对象流及作用:
ObjectInputStream
ObjectOutputStream
作用:可以读写基本数据类型的变量、引用数据类型的变量。
- 对象的序列化机制是什么
对象的序列化机制允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种二进制流永久的保存在磁盘上,或通过网络将这种二进制流传输到另一个网络节点。当其他程序获取了这种二进制流。就可以恢复成原来的Java对象
- 如下两个过程使用的流:
序列化过程:使用ObjectOutputStream流实现。将内存中的Java对象保存在文件中或通过网络传输出去
反序列化过程:使用ObjectInputStream流实现。将文件中的数据或网络传输过来的数据还原为内存中的Java对象
- 自定义类要想实现序列化机制,需要满足:
自定义类需要实现接口:Serializable
要求自定义类声明一个全局常量:static final long serialVersionUID = 42234234L;
要求自定义类的各个属性也必须是可序列化的,对于基本数据类型的属性,默认就是可以序列化的;对于引用数据类型的属性,要求实现Serializable接口
- 注意点:
如果不声明全局常量serialVersionUID,系统会自动声明生成一个针对于当前类的serialVersionUID
如果修改此类的话,会导致serialVersionUID变化,进而导致反序列化时,出现InvalidClassException异常
类中的属性如果声明为transient或static,则不会实现序列化
六、其他流的使用
1.标准输入、输出流
- System.in:标准的输入流,默认从键盘输入
- System.out:标准的输出流,默认从显示器输出(理解为控制台输出)
可通过调用如下的方法,修改输入流和输出流的位置
setIn(InputStream is)
setOut(PrintStream ps)