一、 File 文件

  1. Java 的 File 类代表操作系统中的文件,一般来说,操作系统中的文件包括文件和文件夹;
  2. File 类可以操作文件,包括删除文件、获取文件、创建文件(文件夹)等;

    File 类的使用

    1.1 构造方法

  3. public File(String pathname): 根据路径名 字符串创建 File 实例

  4. public File(String parent, String child):根据父路径名字符串和子路径名字符串创建 File 实例
  5. public File(File parent, String child):根据父抽象路径名和子路径名字符串创建 File 实例

对于两个参数的构造函数:

  1. 如果 parent 为 null 则创建新的 File 实例,就像通过在给定的 child 路径名字符串上调用单参数 File 构造函数一样。
  2. 否则, parent 抽象路径名(或路径名字符串)被用来表示一个目录, child 路径名字符串被用来表示一个目录或一个文件。
  3. 如果 child 路径名字符串是绝对的,那么它会以系统相关的方式转换为相对路径名。
  4. 如果 parent 是空的抽象路径名(或空字符串),则通过将 child 转换为抽象路径名并根据系统相关的默认目录解析结果来创建新的File实例。
  5. 否则,每个路径名字符串都将转换为抽象路径名,并且根据父级解析子抽象路径名。

    Note: The two-argument File constructors do not interpret an empty parent abstract pathname as the current user directory. An empty parent instead causes the child to be resolved against the system-dependent directory defined by the FileSystem.getDefaultParent method. On Unix this default is “/“, while on Microsoft Windows it is “\“. This is required for compatibility with the original behavior of this class.

注意:两个参数的 File 构造函数不会将空的父抽象路径名解释为当前用户目录。相反,空父项会导致根据 FileSystem.getDefaultParent 方法定义的系统相关目录解析子项。在 Unix 上这个默认值是 “”,而在 Microsoft Windows 上它是 “\“。这是与此类的原始行为兼容所必需的。

1.2 获取功能类方法

  1. public String getAbsolutePath():返回此 File 的绝对路径名字符串;
  2. public String getPath():获取创建文件对象的时候用的路径;
  3. public String getName():返回 File 表示的文件或目录的名称(最后一级);
  4. public long length():返回由此 File 表示的文件的长度;
  5. public String getParent():返回 File 对应父目录的路径名字符串;
  6. public File getParentFile():返回 File 对应父目录的抽象路径名;

    1.3 判断功能类方法

  7. public boolean exists():判断此 File 表示的文件或目录是否实际存在;

  8. public boolean isDirectory():判断此 File 表示的是否为目录;
  9. public boolean isFile():判断此 File 表示的是否为文件;

    1.4 创建或删除方法

  10. public boolean createNewFile():当且仅当具有该名称的文件尚不存在时,创建一个新的空文件。 (几乎不用的,因为以后文件都是自动创建的!);

  11. public boolean delete():删除由此 File 表示的文件或目录。(只能删除空目录)
  12. public boolean mkdir():创建由此 File 表示的目录。(只能创建一级目录)
  13. public boolean mkdirs():可以创建多级目录(建议使用)

    1.5 遍历相关方法

  14. public String[] list():获取当前目录下所有的”一级文件名称”到一个字符串数组中去返回;

  15. public File[] listFiles():获取当前目录下所有的”一级文件对象”到一个文件对象数组中去返回;

    二、IO 流

    2.1 IO 流的分类

    按流的方向分类:输入输出以软件运行内存为基准。

  16. 输入流:从文件或网络中将数据流入内存中的流称为输入流;

  17. 输出流:从内存中将数据写出到磁盘文件或网络介质中的流称为输出流;

按流的内容分类:

  1. 字节流:流中的数据的最小单位是一个一个的字节;
  2. 字符流:流中的数据的最小单位是一个一个的字符;

所以,Java 中代表 IO 流的类分为四大类:

抽象类 说明 常用方法
InputStream 字节输入流,数据单位为字节 int read(), void close()
OutputStream 字节输出流,数据单位为字节 void write(int), void flush(), void close()
Reader 字符输入流,数据单位字符 int read(), void close()
Writer 字符输出流,数据单位为字符 void write(String), void flush(), void close()

IO流.png

2.2 FileInputStream

2.2.1 构造方法

  1. public FileInputStream(File path):创建一个字节输入流管道与源文件对象接通。
  2. public FileInputStream(String pathName):创建一个字节输入流管道与文件路径对接。

    2.2.2 常用方法

  3. public int read():每次读取一个字节返回,字节以 int 形式返回,可转 char 获取该字节,读取完毕会返回 -1;

  4. public int read(byte[] buffer):从字节输入流中读取指定数组大小的字节到字节数组中去; ```java InputStream is = new FileInputStream(“”); // 一个字节一个字节的读取 int ch; while((ch = is.read())!= -1){ System.out.print((char) ch); }

// 按照字节数组大小读取 byte[] buffer = new byte[1024]; int len; while((len = is.read(buffer)) != -1){ // 读取了多少就倒出多少! System.out.print(new String(buffer, 0, len)); }

  1. 读取的内容存储在字节数组 buffer 中。
  2. <a name="UztHk"></a>
  3. ## 2.3 FileOutputStream
  4. <a name="qY3l9"></a>
  5. ### 2.3.1 构造方法
  6. 1. `public FileOutputStream(File file)`:创建一个字节输出流管道通向目标文件对象。
  7. 1. `public FileOutputStream(String file)`:创建一个字节输出流管道通向目标文件路径。
  8. 1. `public FileOutputStream(File file, boolean append)`:创建一个追加数据的字节输出流管道通向目标文件对象。
  9. 1. `public FileOutputStream(String file, boolean append)`:创建一个追加数据的字节输出流管道通向目标文件路径。
  10. <a name="naQUL"></a>
  11. ### 2.3.2 常用方法
  12. 1. `public void write(int a)`:写一个字节出去
  13. 1. `public void write(byte[] buffer)`:写一个字节数组出去。
  14. 1. `public void write(byte[] buffer, int pos, int len)`:写一个字节数组的一部分出去。
  15. 1. 参数一:字节数组;
  16. 1. 参数二:起始字节索引位置;
  17. 1. 参数三:写多少个**字节**数出去。
  18. ```java
  19. OutputStream os = new FileOutputStream("Day09Demo/src/dlei07.txt");
  20. os.write(97); // a
  21. os.write("\r\n".getBytes());
  22. os.write("我是谁?".getBytes());
  23. os.write("\r\n".getBytes());
  24. os.write("皮卡丘皮卡丘".getBytes(), 0, 9); // 皮卡丘
  25. os.write("\r\n".getBytes());

2.4 字节流做文件复制

public static void copyFile(String src, String dest) throws Exception {
    // 1. 创建一个字节输入流管道与源文件接通
    InputStream is  = new FileInputStream(src);
    // 2. 创建一个字节输出流与目标文件接通
    OutputStream os = new FileOutputStream(dest);
    byte[] buffer = new byte[1024];
    int len;
    // 3. 字节输入流按字节数组读取源文件
    while((len = is.read(buffer)) != -1) {
        // 4. 字节输出流按读取长度写目标文件
        os.write(buffer, 0, len);
    }
    System.out.println("复制完成");
}

2.5 FileReader

2.5.1 构造方法

  1. public FileReader(File file):创建一个字符输入流与源文件对象接通。
  2. public FileReader(String filePath):创建一个字符输入流与源文件路径接通。

    2.5.2 常用方法

  3. public int read():读取一个字符的编号返回! 读取完毕返回-1

  4. public int read(char[] buffer):读取一个字符数组,读取多少个字符就返回多少个数量,读取完毕返回-1; ```java Reader fr = new FileReader(“Day10Demo/src/dlei01.txt”); // 1. while循环一个一个字符读取。 int ch; while ((ch = fr.read()) != -1){ System.out.print((char)ch); }

// 2.按照字符数组读取数据使用循环 char[] buffer = new char[1024]; // 1K int len; while((len = fr.read(buffer)) != -1) { // 读取多少倒出多少字符 System.out.print(new String(buffer, 0, len)); }

<a name="JabmG"></a>
## 2.6 FileWriter
<a name="UsO1l"></a>
### 2.6.1 构造方法

1. `public FileWriter(File file)`:创建一个字符输出流管道通向目标文件对象;
1. `public FileWriter(String filePath)`:创建一个字符输出流管道通向目标文件路径;
1. `public FileWriter(File file, boolean append)`:创建一个追加数据的字符输出流管道通向目标文件对象;
1. `public FileWriter(String filePath, boolean append)`:创建一个追加数据的字符输出流管道通向目标文件路径;
<a name="F7kQw"></a>
### 2.6.2 常用方法

1. `public void write(int c)`:写一个字符出去;
1. `public void write(String c)`:写一个字符串出去;
1. `public void write(char[] buffer)`:写一个字符数组出去;
1. `public void write(String c, int pos, int len)`:写字符串的一部分出去;
1. `public void write(char[] buffer, int pos, int len)`:写字符数组的一部分出去;
```java
Writer fw = new FileWriter("/file.txt", true);

// 1. 写一个字符
 fw.write(97);   // 字符a
fw.write('b');  // 字符b
fw.write('中');
fw.write("\r\n"); // 换行

// 2. 写一个字符串
fw.write("Java是最优美的语言!");

// 3. 写一个字符数组出去
fw.write("我爱中国".toCharArray());

// 4. 写字符串的一部分
fw.write("Java是最优美的语言!", 0, 9); // Java是最优美的

// 5. 写字符数组的一部分
fw.write("我爱中国".toCharArray(), 0, 2); // 我爱

2.7 缓冲流

缓冲流可以提高 IO 流操作的效率。缓冲字节流通过原始流构建而成,其功能和原始流基本一致,缓冲流多了一个8kb 的缓冲池,提高了原始流操作的效率。

2.7.1 字节缓冲流

构造方法:

  1. public BufferedInputStream(InputStream in):字节缓冲输入流;
  2. public BufferedOutputStream(OutputStream os):字节缓冲输出流;
// 1. 字节缓冲输入流的使用
BufferedInputStream bis = new BufferedInputStream(new FileInputStream("file.txt"));
byte[] buffer = new byte[1024];
int len;
while((len = is.read(buffer)) != -1) {
    System.out.print(new String(buffer, 0, len));
}

// 2. 字节缓冲输出流的使用
BufferedOutputStream bos =  new BufferedOutputStream(new FileOutputStream("file.txt"));
bos.write('a');
bos.write(100);
bos.write("我爱中国".getBytes());

2.7.2 字符缓冲流

构造方法

  1. public BufferedReader(Reader reader):字符缓冲输入流;
  2. public BufferedWriter(Writer writer):字符缓冲输出流;

新增方法:

  1. public String readLine():字符缓冲输入流新增读一行的方法,读取完毕返回 null;
  2. public void newLine():字符缓冲输出流新增新建一行的方法; ```java // 1. 字符缓冲输入流的使用 BufferedReader br = new BufferedReader(new FileReader(“file.txt”)); String line; while((line = br.readLine()) != null){ System.out.println(line); }

// 2. 字符缓冲输出流的使用 BufferedWriter bw = new BufferedWriter(new FileWriter(“file.txt”, true)); bw.write(“心中有信仰,脚下有力量”); bw.newLine(); // 换行 bw.write(“人民有信仰,民族有希望,国家有力量”);

<a name="cCe6z"></a>
## 2.8 转换流
转换流包含 `InputStreamReader` `OutputStreamWriter` 实际上输入 `Reader`、`Writer` 字符流抽象类的子类,可以将字节流传入构造器按照指定的字符编码转换为字符流,可以作为字节流到字符流的桥梁。

转换流还可以包装成缓冲流提高效率。
<a name="paIaD"></a>
### 2.8.1 转换输入流 - InputStreamReader
定义:
```java
public class InputStreamReader extends Reader {}

构造方法:

  1. public InputStreamReader(InputStream is):可以使用当前代码默认编码转换成字符流;
  2. public InputStreamReader(InputStream is, String charset):可以指定编码把字节流转换成字符流;
// 转换输入流
InputStreamReader isr = new InputStreamReader(new FileInputStream("file.txt"), "GBK");
 // 包装成缓冲输入流
BufferedReader br = new BufferedReader(isr);
String line;
while((line = br.readLine())!=null){
    System.out.println(line);
}

2.8.2 转换输出流 - OutputStreamWriter

定义:

public class OutputStreamWriter extends Writer {}

构造方法:

  1. public OutputStreamWriter(OutputStream os):用当前默认编码把字节输出流转换成字符输出流;
  2. public OutputStreamWriter(OutputStream os, String charset):指定编码把字节输出流转换成字符输出流;
OutputStream os = new FileOutputStream("file.txt");

// 把字节输出流转换成字符输出流
Writer osw = new OutputStreamWriter(os, "GBK");
osw.write("abc我是中国人");
osw.close();

2.9 打印流

打印流可以方便高效的写各种类型数据,

2.9.1 PrintSteam

  1. public PrintStream(OutputStream os)
  2. public PrintStream(String filepath) ```java PrintStream ps = new PrintStream(“file.txt”);

ps.println(97); // 97 ps.println(99.8); ps.println(false);

// 写字节数据出去 ps.write(“我爱你”.getBytes());

<a name="CGxwD"></a>
# 三、Java 序列化技术

- Java 序列化是指把 Java 对象转换为字节序列的过程;
- Java 反序列化是指把字节序列恢复为 Java 对象的过程;

注意:

1. 对象如果想参与序列化,对象必须实现序列化接口 implements Serializable ,否则序列化失败;
1. transient修饰成员变量,该成员变量将不参与序列化;
1. 序列化版本号 - serialVersionUID 序列化使用的版本号和反序列化使用的版本号一致才可以正常反序列化,否则报错;
<a name="Af7yq"></a>
## 3.1 序列化 - ObjectOutputStream
把内存中的Java对象数据保存到字节序列中去。

1. 构造方法:`public ObjectOutputStream(OutputStream out)`
1. 序列化方法:`public final void writeObject(Object obj)`

```java
// 1.创建User用户对象
User user = new User("tsgz","003197","铁扇公主");
// 2.创建低级的字节输出流通向目标文件
OutputStream os = new FileOutputStream("/object.dat");
// 3.把低级的字节输出流包装成高级的对象字节输出流ObjectOutputStream
ObjectOutputStream oos = new ObjectOutputStream(os);
// 4.通过对象字节输出流序列化对象:
oos.writeObject(user);
System.out.println("序列化对象成功~~~~");

3.2 反序列化 - ObjectInputStream

读取序列化的对象字节序列恢复到Java对象中。

  1. 构造方法:public ObjectInputStream(InputStream is)
  2. 反序列化方法:public final Object readObject()
    // 1.定义一个低级的字节输入流通向源文件
    InputStream is = new FileInputStream("/object.dat");
    // 2.把字节输入流包装成高的对象字节输入流
    ObjectInputStream ois = new ObjectInputStream(is);
    // 3.反序列化
    User user = (User) ois.readObject();
    System.out.println(user);
    System.out.println("反序列化完成!");
    

    3.3 原理解析参考

    1. 反序列化创建对象原理

    Java反序列化创建对象探析