【动力节点 Java进阶学习笔记】第六章 IO流
- IO流和FIle类总结
- IO流和FIle类学习笔记
- 1、Java流概述和IO流的分类
- 2、FileInputStream的使用:按字节和byte数组两种方式读取文件内容
- 3、FileOutputStream的使用:覆盖方式和追加方式写入数组中内容
- 4、FileReader的使用
- 5、FileWriter的使用
- 6、缓冲流BufferedReader和BufferedWriter的使用以及转换流的使用、节点流和包装流
- 7、数据流DataOutputStream和DataInputStream的使用
- 8、PrintStream的使用
- 9、File类概述和常用方法
- 10、序列化和反序列化的概念、Serializable接口和作用、如何序列化和反序列化对象
- 11、IO+Properties的联合应用实现配置文件的动态读取
- 附录:某一文件夹下所有文件的复制--代码实现
- 补充:IDEA生成 Serializable序列化UID的快捷键及其设置方法
IO流和FIle类总结
1、IO流总结
2、File类中方法总结
IO流和FIle类学习笔记
1、Java流概述和IO流的分类
流的分类:输入流、输出流
字节流(什么类型的文件都可以读取)、字符流(只能读取纯文本文件)
java IO流四大家族: java.io.InputStream 字节输入流
java.io.OutputStream 字节输出流
java.io.Reader 字符输入流
java.io.Writer 字符输出流
所有的流都实现了:java.io.Closeable接口,都是可关闭的,都有close()方法。
所有的输出流都实现了:java.io.Flushable接口,都是可刷新的,都有flush()方法。
java.io包下需要掌握的流有16个:可见上面的总结部分
2、FileInputStream的使用:按字节和byte数组两种方式读取文件内容
2.1 按字节读取文件内容,返回字节本身,如果已到达文件末尾,则返回 -1。
-->内存和硬盘交互太频繁
int readData;
while((readData = fis.read()) != -1){
System.out.print(readData);
}
2.2 往byte数组中读:read(byte[] b) ,返回读取到的字节数量,数据存储在数组中
—>减少硬盘和内存的交互,提高程序的执行效率
byte[] bytes = new byte[4];
int readData = 0 ;
while((readData = fis.read(bytes))!= -1){
System.out.print(new String(bytes, 0, readData));
}
2.3 FileInputStream类的其它常用方法:
int available():返回流当中剩余的没有读到的字节数量
long skip(long n):跳过几个字节不读。
3、FileOutputStream的使用:覆盖方式和追加方式写入数组中内容
默认是通过覆盖的方式写入,文件不存在会自动创建:
new FileOutputStream();
以追加方式写入:
new FileOutputStream(, true);
写入的方法:
(1)写入数组全部内容 fos.write(bytes);
(2)写入部分数组内容 fos.write(bytes, 0, 2)
(3)写入字符串 byte[] bs = s.getBytes(); fos.write(bs);
写完之后,最后一定要刷新:fos.flush();
4、FileReader的使用
使用char数组:
char[] chars = new char[4];
reader.read(chars)
5、FileWriter的使用
可使用char数组,也可直接使用String
void write(char cbuf[])
void write(char cbuf[], int off, int len)
void write(String str)
void write(String str, int off, int len)
6、缓冲流BufferedReader和BufferedWriter的使用以及转换流的使用、节点流和包装流
特点:可以不需要数组,也可以逐行读取,相比文件流速度更快
BufferedReader:
BufferedReader br = new BufferedReader(new FileReader("
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("
readLine()方法读取一个文本行,但不带换行符。返回String类型,如果已到达流末尾,则返回 null
BufferedWriter:
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("
当一个流的构造方法中需要一个流的时候,这个被传进来的流叫做:
节点流。
外部负责包装的这个流,叫做:包装流,还有一个名字叫做:
处理流。
关闭流close():对于包装流来说,只需要关闭最外层流就行,里面的节点流会自动关闭
7、数据流DataOutputStream和DataInputStream的使用
DataOutputStream可以将数据连同数据的类型一并写入文件:writeByte()、writeShort()…
DataOutputStream写的文件,只能使用DataInputStream去读。并且读的时候你需要提前知道写入的顺序。
读的顺序需要和写的顺序一致,才可以正常取出数据:readByte()、readShort()…
8、PrintStream的使用
默认输出到控制台。
可以改变标准输出流的输出方向,达到日志输出重定向的效果:
// 标准输出流不再指向控制台,指向“log”文件。
PrintStream printStream = new PrintStream(new FileOutputStream(“log”));
// 修改输出方向,将输出方向修改到"log"文件。
System.setOut(printStream);
System.out中out属性为一个printStream对象
9、File类概述和常用方法
File对象代表什么:文件和目录路径名的抽象表示形式。
File类中常用的方法:
创建File对象:new File(“D:\file”);
判断文件或目录是否存在:exists()
创建新文件: createNewFile()
创建新目录:mkdir() 、mkdirs()
获取文件绝对路径:getAbsolutePath()
获取文件名:getName()
获取当前目录下所有的子文件:File[] | listFiles()
获取当前目录下所有的子文件:String[] | list()
判断是否是一个目录:isDirectory()
判断是否是一个文件:isFile()
经典实践:某一文件夹下所有文件的复制,参见本文最后面附录的代码
10、序列化和反序列化的概念、Serializable接口和作用、如何序列化和反序列化对象
序列化:Serialize 将java对象存储到内存中,拆分对象存储,即将java对象的状态保存下来的过程
反序列化:Deserialize 将硬盘上的数据重新恢复到内存当中,恢复成java对象(组装对象)
- 参与序列化和反序列化的对象,必须实现Serializable接口。
- Serializable这个标志接口是给java虚拟机参考的,java虚拟机看到这个接口之后,会为该类自动生成一个序列化版本号。
- 序列化版本号的作用:Java虚拟机区分类
- 凡是一个类实现了Serializable接口,建议给该类提供一个固定不变的序列化版本号。这样,以后这个类即使代码修改了,但是版本号不变,java虚拟机会认为是同一个类。
- 序列化对象:ObjectOutputStream(OutputStream out) writeObject()
- 反序列化对象:ObjectOutputStream(OutputStream out) readObject()
- 可以将对象放到集合当中一次序列化多个对象:writeObject()
- transient关键字表示游离的,该关键字修饰的属性不参与序列化。
11、IO+Properties的联合应用实现配置文件的动态读取
属性配置文件:以.properties结尾的文件,内容格式为key1=value
利用Properties的load()方法将文件中的数据加载到Map集合中:
load(Reader reader) load(InputStream inStream)
然后再用getProperty方法对配置文件中的数据进行读取
附录:某一文件夹下所有文件的复制–代码实现
备注:简单测试了一下正常场景没发现问题,可供参考,可能存在场景覆盖不全的问题,如果发现代码问题请帮忙指出,我会及时改正,谢谢!
package com.javalearn.javase.review.io;
import java.io.*;
public class CopyAll {
public static void main(String[] args) {
File srcdir = new File("G:\\学习\\java\\test2");
File dstDir = new File("G:\\学习\\java\\test1");
copyAll(srcdir, srcdir, dstDir);
}
public static void copyAll(File copyDir, File srcDir, File dstDir) {
if (!dstDir.exists()){
dstDir.mkdir();
}
if (srcDir.exists()) {
if (copyDir.isFile()) {
copyFile(copyDir, srcDir, dstDir);
return;
}
File[] files = copyDir.listFiles();
// if (files.length == 0){
// copyDir(copyDir, srcDir, dstDir);
// return;
// }
for (File file : files) {
if (file.isDirectory()) {
copyDir(file, srcDir, dstDir);
}
copyAll(file, srcDir, dstDir);
}
}
}
//拷贝文件
public static void copyFile(File srcFile, File srcDir, File dstDir) {
FileInputStream fis = null;
FileOutputStream fos = null;
try {
fis = new FileInputStream(srcFile);
String dstFilePath = null;
if (srcFile.equals(srcDir)){
dstFilePath = dstDir.getAbsolutePath() + "\\" + srcFile.getName();
} else {
dstFilePath = srcFile.getAbsolutePath().replace(srcDir.getAbsolutePath(), dstDir.getAbsolutePath());
}
fos = new FileOutputStream(dstFilePath);
byte[] bytes = new byte[1024 * 1024];
int readCount = 0;
while ((readCount = fis.read(bytes)) != -1) {
fos.write(bytes, 0, readCount);
}
fos.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException 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();
}
}
}
}
//拷贝文件夹
public static void copyDir(File srcSubDir, File srcDir, File dstDir) {
String dstDirPath = srcSubDir.getAbsolutePath().replace(srcDir.getAbsolutePath(), dstDir.getAbsolutePath());
File dstSubDir = new File(dstDirPath);
if (!dstSubDir.exists()){
dstSubDir.mkdir();
}
}
}
补充:IDEA生成 Serializable序列化UID的快捷键及其设置方法
可参考:https://blog.csdn.net/qq_41958123/article/details/87616704
设置方法:Fil–>Setting–>Editor–>Inspections–>Java–>Serialization issues–>勾选Serializable class without 'serialVersionUID’
调用快捷键:鼠标定位到类上,alt+enter 选择Add ‘serialVersionUID’ filed就会自动生成