Java学习笔记(No.15)

Java的I/O流(No.15)

1、数据源(Data Source)

数据源就是提供原始数据的原始媒介(如“数据库、文件、内存、网络连接、IO设备、其他程序”等),打个比方:“数据源就像水箱,流就像水管中流着的水流,程序就是我们最终的用户”

2、流(Stream)

流是一个抽象、动态的概念,亦即,一连串连续动态的数据集合

3、按数据流向分类(Classification By Data Stream Direction)

3.1、输入流(Input Stream)

数据源到程序(InputStream、Reader读入)

输入流示意图,如下图所示

输入流示意图

3.2、输出流(Output Stream)

程序到数据源或目的地(OutputStream、Writer写出)

输出流示意图,如下图所示

输出流示意图

4、按数据单位分类(Classification By Data Unit)

4.1、字节流(Byte Stream)

按照字节读写数据(InputStream、OutputStream),亦即,以字节(单字节编码)为单位读写所有类型文件(如“txt文件、exe文件、mp3文件、mp4文件”等)

字节流示意图,如下图所示

字节流示意图

4.2、字符流(Character Stream)

按照字符读写数据(Reader、Writer),亦即,以字符(如“GBK字符(双字节编码)、UTF-8字符(三字节编码)”等)为单位读写纯文本类型文件(如“txt文件”等)

字符流示意图,如下图所示

字符流示意图

5、按数据功能分类(Classification By Data Function)

5.1、节点流(Node Stream)

可直接从数据源或目的地读写数据

节点流示意图,如下图所示

节点流示意图

5.2、处理流(Process Stream)

不直接从数据源或目的地读写数据,而是处理流的流,即通过对其他流的处理提高程序的性能

处理流示意图,如下图所示

处理流示意图

6、InputStream类与FileInputStream类(InputStream Class And FileInputStream Class)

6.1、读入文件字节数据(Read In File Byte Data)

  • 6.1.1、示例代码(Sample Code)

其示例,如以下代码所示

package com.xueshanxuehai.io.inputstream;
import java.io.*;
public class ReadInFileByteData {
    public static void main(String[] args) throws IOException {
        System.out.println("InputStream类与FileInputStream类读入文件字节数据:");
        //文件字节输入流
        InputStream inputStream = new FileInputStream("E:\\ReadWriteFile\\InputStream.txt");
        System.out.println("使用InputStream类的read方法开始读入文件字节数据");
        /**
         *读入文件字节数据
         *从输入流读取数据的下一个字节。 值字节被返回作为int范围0至255 。
         *若读到数据字节流的末尾,则返回值-1,否则继续读取下一个数据字节流
         */
        int inputStreamRead = 0;
        while ((inputStreamRead = inputStream.read()) != -1) {
            System.out.println(inputStreamRead);
        }
        System.out.println("使用InputStream类的read方法读入文件字节数据完成");
    }
}
  • 6.1.2、运行结果(Run Result)

其运行结果,如以下信息所示

InputStream类与FileInputStream类读入文件字节数据:
使用InputStream类的read方法开始读入文件字节数据
73
110
112
117
116
83
116
114
101
97
109
13
10
48
49
50
51
52
53
54
55
56
57
13
10
228
184
173
229
141
142
228
186
186
230
176
145
229
133
177
229
146
140
229
155
189
使用InputStream类的read方法读入文件字节数据完成

6.2、批量读入文件字节数据(Batch Read In File Byte Data)

  • 6.2.1、示例代码(Sample Code)

其示例,如以下代码所示

package com.xueshanxuehai.io.inputstream;
import java.io.*;
import java.util.Arrays;
public class BatchReadInFileByteData {
    public static void main(String[] args) throws IOException {
        System.out.println("InputStream类与FileInputStream类批量读入文件字节数据:");
        //文件字节输入流
        InputStream inputStream = new FileInputStream("E:\\ReadWriteFile\\InputStream.txt");
        System.out.println("使用InputStream类的read方法开始批量读入文件字节数据");
        /**
         *批量读入文件字节数据
         *从输入流读取一些字节数,并将它们存储到缓冲区,且实际读取的字节数作为整数返回。
         *若缓冲区长度为零,则不会读取字节并返回0;否则尝试读取至少一个字节。
         *若读到数据字节流的末尾,则返回值-1,否则读取至少一个字节并存储到缓冲区
         */
        byte[] bytes = new byte[8];
        int byteLen = 0;
        while ((byteLen = inputStream.read(bytes)) != -1) {
//            //方法一:使用for循环输出打印字节数组
//            for (int i = 0; i < byteLen; i++) {
//                System.out.println(bytes[i]);
//            }
            //方法二:使用Arrays工具类方法输出打印字节数组
            System.out.println(Arrays.toString(Arrays.copyOfRange(bytes,0,byteLen)));
        }
        System.out.println("使用InputStream类的read方法批量读入文件字节数据完成");
    }
}
  • 6.2.2、运行结果(Run Result)

其运行结果,如以下信息所示

InputStream类与FileInputStream类批量读入文件字节数据:
使用InputStream类的read方法开始批量读入文件字节数据
[73, 110, 112, 117, 116, 83, 116, 114]
[101, 97, 109, 13, 10, 48, 49, 50]
[51, 52, 53, 54, 55, 56, 57, 13]
[10, -28, -72, -83, -27, -115, -114, -28]
[-70, -70, -26, -80, -111, -27, -123, -79]
[-27, -110, -116, -27, -101, -67]
使用InputStream类的read方法批量读入文件字节数据完成

7、OutputStream类与FileOutputStream类(OutputStream Class And FileOutputStream Class)

7.1、写出文件字节数据(Write Out File Byte Data)

  • 7.1.1、示例代码(Sample Code)

其示例,如以下代码所示

package com.xueshanxuehai.io.outputstream;
import java.io.*;
public class WriteOutFileByteData {
    public static void main(String[] args) throws IOException {
        System.out.println("OutputStream类与FileOutputStream类写出文件字节数据:");
        /**
         *文件字节输出流
         *若设置append参数值为“true”,则可以追加写出数据,否则只能覆盖写出数据,且默认append参数值为“false”
         */
        OutputStream  outputStream1=new FileOutputStream("E:\\ReadWriteFile\\OutputStream.txt");
        System.out.println("使用OutputStream类的write方法开始写出文件字节数据(覆盖)");
        outputStream1.write(65);//写出文件字节数据(覆盖)
        outputStream1.flush();//刷新输出流
        outputStream1.close();//关闭输出流
        System.out.println("使用OutputStream类的write方法写出文件字节数据完成(覆盖)");
        OutputStream  outputStream2=new FileOutputStream("E:\\ReadWriteFile\\OutputStream.txt",true);
        System.out.println("使用OutputStream类的write方法开始写出文件字节数据(追加)");
        outputStream2.write(65);//写出文件字节数据(追加)
        outputStream2.flush();//刷新输出流
        outputStream2.close();//关闭输出流
        System.out.println("使用OutputStream类的write方法写出文件字节数据完成(追加)");
    }
}
  • 7.1.2、运行结果(Run Result)

其运行结果,如以下信息所示

OutputStream类与FileOutputStream类写出文件字节数据:
使用OutputStream类的write方法开始写出文件字节数据(覆盖)
使用OutputStream类的write方法写出文件字节数据完成(覆盖)
使用OutputStream类的write方法开始写出文件字节数据(追加)
使用OutputStream类的write方法写出文件字节数据完成(追加)

7.2、批量写出文件字节数据(Batch Write Out File Byte Data)

  • 7.2.1、示例代码(Sample Code)

其示例,如以下代码所示

package com.xueshanxuehai.io.outputstream;
import java.io.*;
public class BatchWriteOutFileByteData {
    public static void main(String[] args) throws IOException {
        System.out.println("OutputStream类与FileOutputStream类批量写出文件字节数据:");
        /**
         *文件字节输出流
         *若设置append参数值为“true”,则可以追加写出数据,否则只能覆盖写出数据,且默认append参数值为“false”
         */
        OutputStream outputStream1=new FileOutputStream("E:\\ReadWriteFile\\OutputStream.txt");
        System.out.println("使用OutputStream类的write方法开始批量写出文件字节数据(覆盖)");
        byte[] bytes1="批量写出文件字节数据(覆盖)".getBytes("UTF-8");
        outputStream1.write(bytes1);//批量写出文件字节数据(覆盖)
        outputStream1.flush();//刷新输出流
        outputStream1.close();//关闭输出流
        System.out.println("使用OutputStream类的write方法批量写出文件字节数据完成(覆盖)");
        OutputStream  outputStream2=new FileOutputStream("E:\\ReadWriteFile\\OutputStream.txt",true);
        System.out.println("使用OutputStream类的write方法开始批量写出文件字节数据(追加)");
        byte[] bytes2="批量写出文件字节数据(追加)".getBytes("UTF-8");
        outputStream2.write(bytes2);//批量写出文件字节数据(追加)
        outputStream2.flush();//刷新输出流
        outputStream2.close();//关闭输出流
        System.out.println("使用OutputStream类的write方法批量写出文件字节数据完成(追加)");
    }
}
  • 7.2.2、运行结果(Run Result)

其运行结果,如以下信息所示

OutputStream类与FileOutputStream类批量写出文件字节数据:
使用OutputStream类的write方法开始批量写出文件字节数据(覆盖)
使用OutputStream类的write方法批量写出文件字节数据完成(覆盖)
使用OutputStream类的write方法开始批量写出文件字节数据(追加)
使用OutputStream类的write方法批量写出文件字节数据完成(追加)

8、字节流读入写出结构图(Byte Stream Read In Write Out Structure Diagram)

字节流读入写出结构图,如下图所示

字节流读入写出结构图

9、Reader类与FileReader类(Reader Class And FileReader Class)

9.1、读入文件字符数据(Read In File Character Data)

  • 9.1.1、示例代码(Sample Code)

其示例,如以下代码所示

package com.xueshanxuehai.io.reader;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
public class ReadInFileCharacterData {
    public static void main(String[] args) throws IOException {
        System.out.println("Reader类与FileReader类读入文件字符数据:");
        //文件字符输入流
        Reader reader=new FileReader("E:\\ReadWriteFile\\Reader.txt");
        System.out.println("使用Reader类的read方法开始读入文件字符数据");
        //读入文件字符数据
        int readerRead=0;
        while((readerRead=reader.read())!=-1){
            System.out.println((char) readerRead);
        }
        System.out.println("使用Reader类的read方法读入文件字符数据完成");
    }
}
  • 9.1.2、运行结果(Run Result)

其运行结果,如以下信息所示

Reader类与FileReader类读入文件字符数据:
使用Reader类的read方法开始读入文件字符数据
R
e
a
d
e
r



0
1
2
3
4
5
6
7
8
9



中
华
人
民
共
和
国
使用Reader类的read方法读入文件字符数据完成

9.2、批量读入文件数据(Batch Read In File Character Data)

  • 9.2.1、示例代码(Sample Code)

其示例,如以下代码所示

package com.xueshanxuehai.io.reader;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.util.Arrays;
public class BatchReadInFileCharacterData {
    public static void main(String[] args) throws IOException {
        System.out.println("Reader类与FileReader类批量读入文件字符数据:");
        //文件字符输入流
        Reader reader = new FileReader("E:\\ReadWriteFile\\Reader.txt");
        System.out.println("使用Reader类的read方法开始批量读入文件字符数据");
        //批量读入文件字符数据
        char[] chars = new char[8];
        int charLen = 0;
        while ((charLen = reader.read(chars)) != -1) {
//            //方法一:使用for循环输出打印字符数组
//            forLoopPrintCharacterArray(chars, charLen);
            //方法二:使用Arrays工具类方法输出打印字节数组
            arraysClassMethodToPrintCharacterArray(chars, charLen);
        }
        System.out.println("使用Reader类的read方法批量读入文件字符数据完成");
    }
    //使用for循环输出打印字符数组
    public static void forLoopPrintCharacterArray(char[] chars, int charLen) {
        for (int i = 0; i < charLen; i++) {
            if (i == 0) {
                if (i == charLen - 1) {
                    switch (chars[i]) {
                        case '\r':
                            System.out.print("{\\r}\r\n");
                            break;
                        case '\n':
                            System.out.print("{\\n}\r\n");
                            break;
                        default:
                            System.out.print("{" + chars[i] + "}\r\n");
                            break;
                    }
                } else {
                    switch (chars[i]) {
                        case '\r':
                            System.out.print("{\\r");
                            break;
                        case '\n':
                            System.out.print("{\\n");
                            break;
                        default:
                            System.out.print("{" + chars[i]);
                            break;
                    }
                }
            } else if (i == charLen - 1) {
                switch (chars[i]) {
                    case '\r':
                        System.out.print(",\\r}\r\n");
                        break;
                    case '\n':
                        System.out.print(",\\n}\r\n");
                        break;
                    default:
                        System.out.print("," + chars[i] + "}\r\n");
                        break;
                }
            } else {
                switch (chars[i]) {
                    case '\r':
                        System.out.print(",\\r");
                        break;
                    case '\n':
                        System.out.print(",\\n");
                        break;
                    default:
                        System.out.print("," + chars[i]);
                        break;
                }
            }
        }
    }
    //使用Arrays工具类方法输出打印字节数组
    public static void arraysClassMethodToPrintCharacterArray(char[] chars, int charLen) {
        for (int i = 0; i < charLen; i++) {
            if ((chars[i] == '\r') || (chars[i] == '\n')) {
                chars[i] = (char) 0;
            }
        }
        System.out.println(Arrays.toString(Arrays.copyOfRange(chars, 0, charLen)));
    }

}
  • 9.2.2、运行结果(Run Result)

其运行结果,如以下信息所示

Reader类与FileReader类批量读入文件字符数据:
使用Reader类的read方法开始批量读入文件字符数据
[R, e, a, d, e, r,  ,  ]
[0, 1, 2, 3, 4, 5, 6, 7]
[8, 9,  ,  ,,,,]
[,,]
使用Reader类的read方法批量读入文件字符数据完成

9.3、注意事项(Matters Needing Attention)

  • 9.3.1、使用Reader类读入文件字符数据时,必须要把文件中的回车、换行字符数据(即,’\r’或"(char)13"、’\n’或"(char)10")特殊处理(如,转换成特殊字符“ ”或“(char)0”等不影响其它字符数据正常显示输出的字符)后才能使其它字符数据正常显示输出

10、Writer类与FileWriter类(Writer Class And FileWriter Class)

10.1、写出文件字符数据(Write Out File Character Data)

  • 10.1.1、示例代码(Sample Code)

其示例,如以下代码所示

package com.xueshanxuehai.io.writer;
import java.io.*;
public class WriteOutFileCharacterData {
    public static void main(String[] args) throws IOException {
        System.out.println("Writer类与FileWriter类写出文件字符数据:");
        /**
         *文件字符输出流
         *若设置append参数值为“true”,则可以追加写出数据,否则只能覆盖写出数据,且默认append参数值为“false”
         */
        Writer writer1=new FileWriter("E:\\ReadWriteFile\\Writer.txt");
        System.out.println("使用Writer类的write方法开始写出文件字符数据(覆盖)");
        writer1.write("a");//写出文件字符数据(覆盖)
        writer1.flush();
        writer1.close();
        System.out.println("使用Writer类的write方法写出文件字符数据完成(覆盖)");
        Writer writer2=new FileWriter("E:\\ReadWriteFile\\Writer.txt",true);
        System.out.println("使用Writer类的write方法开始写出文件字符数据(追加)");
        writer2.write("A");//写出文件字符数据(追加)
        writer2.flush();
        writer2.close();
        System.out.println("使用Writer类的write方法写出文件字符数据完成(追加)");
    }
}
  • 10.1.2、运行结果(Run Result)

其运行结果,如以下信息所示

Writer类与FileWriter类写出文件字符数据:
使用Writer类的write方法开始写出文件字符数据(覆盖)
使用Writer类的write方法写出文件字符数据完成(覆盖)
使用Writer类的write方法开始写出文件字符数据(追加)
使用Writer类的write方法写出文件字符数据完成(追加)

10.2、批量写出文件字符数据(Batch Write Out File Character Data)

  • 10.2.1、示例代码(Sample Code)

其示例,如以下代码所示

package com.xueshanxuehai.io.writer;
import java.io.*;
public class BatchWriteOutFileCharacterData {
    public static void main(String[] args) throws IOException {
        System.out.println("Writer类与FileWriter类批量写出文件字符数据:");
        /**
         *文件字符输出流
         *若设置append参数值为“true”,则可以追加写出数据,否则只能覆盖写出数据,且默认append参数值为“false”
         */
        Writer writer1=new FileWriter("E:\\ReadWriteFile\\Writer.txt");
        System.out.println("使用Writer类的write方法开始批量写出文件字符数据(覆盖)");
        char[] chars1="批量写出文件字符数据(覆盖)".toCharArray();
        writer1.write(chars1);//批量写出文件字符数据(覆盖)
        writer1.flush();
        writer1.close();
        System.out.println("使用Writer类的write方法批量写出文件字符数据完成(覆盖)");
        Writer writer2=new FileWriter("E:\\ReadWriteFile\\Writer.txt",true);
        System.out.println("使用Writer类的write方法开始批量写出文件字符数据(追加)");
        char[] chars2="批量写出文件字符数据(追加)".toCharArray();
        writer2.write(chars2);//批量写出文件字符数据(追加)
        writer2.flush();
        writer2.close();
        System.out.println("使用Writer类的write方法批量写出文件字符数据完成(追加)");
    }
}
  • 10.2.2、运行结果(Run Result)

其运行结果,如以下信息所示

Writer类与FileWriter类批量写出文件字符数据:
使用Writer类的write方法开始批量写出文件字符数据(覆盖)
使用Writer类的write方法批量写出文件字符数据完成(覆盖)
使用Writer类的write方法开始批量写出文件字符数据(追加)
使用Writer类的write方法批量写出文件字符数据完成(追加)

10.3、注意事项(Matters Needing Attention)

  • 10.3.1、使用Writer类写出文件字节或字符数据时,必须在写完文件数据后正常关闭才能生效成功

11、字符流读入写出结构图(Character Stream Read In Write Out Structure Diagram)

字符流读入写出结构图,如下图所示

字符流读入写出结构图

12、关闭输入流(Close Input Stream)

12.1、关闭InputStream输入流(Close InputStream Input Stream)

  • 12.1.1、示例代码(Sample Code)

其示例,如以下代码所示

package com.xueshanxuehai.io.inputstream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
public class CloseInputStream {
    public static void main(String[] args) {
        InputStream inputStream=null;//文件字节输入流
        try {
            System.out.println("InputStream类与FileInputStream类批量读入文件字节数据:");
            inputStream = new FileInputStream("E:\\ReadWriteFile\\InputStream.txt");
            System.out.println("使用InputStream类的read方法开始批量读入文件字节数据");
            byte[] bytes = new byte[8];
            int byteLen = 0;
            while ((byteLen = inputStream.read(bytes)) != -1) {                System.out.println(Arrays.toString(Arrays.copyOfRange(bytes,0,byteLen)));//使用Arrays工具类方法输出打印字节数组
            }
            System.out.println("使用InputStream类的read方法批量读入文件字节数据完成");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            if(inputStream!=null){
                try {
                    inputStream.close();
                    System.out.println("关闭InputStream输入流成功");
                } catch (IOException e) {
                    e.printStackTrace();
                    System.out.println("关闭InputStream输入流失败");
                }
            }
        }
    }
}
  • 12.1.2、运行结果(Run Result)

其运行结果,如以下信息所示

InputStream类与FileInputStream类批量读入文件字节数据:
使用InputStream类的read方法开始批量读入文件字节数据
[73, 110, 112, 117, 116, 83, 116, 114]
[101, 97, 109, 13, 10, 48, 49, 50]
[51, 52, 53, 54, 55, 56, 57, 13]
[10, -28, -72, -83, -27, -115, -114, -28]
[-70, -70, -26, -80, -111, -27, -123, -79]
[-27, -110, -116, -27, -101, -67]
使用InputStream类的read方法批量读入文件字节数据完成
关闭InputStream输入流成功

12.2、关闭Reader输入流(Close Reader Input Stream)

  • 12.2.1、示例代码(Sample Code)

其示例,如以下代码所示

package com.xueshanxuehai.io.reader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.util.Arrays;
public class CloseReader {
    public static void main(String[] args) {
        Reader reader = null;//文件字符输入流
        try {
            System.out.println("Reader类与FileReader类批量读入文件字符数据:");
            reader = new FileReader("E:\\ReadWriteFile\\Reader.txt");
            System.out.println("使用Reader类的read方法开始批量读入文件字符数据");
            //批量读入文件字符数据
            char[] chars = new char[8];
            int charLen = 0;
            while ((charLen = reader.read(chars)) != -1) {
                arraysClassMethodToPrintCharacterArray(chars, charLen);//使用Arrays工具类方法输出打印字节数组
            }
            System.out.println("使用Reader类的read方法批量读入文件字符数据完成");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                    System.out.println("关闭Reader输入流成功");
                } catch (IOException e) {
                    e.printStackTrace();
                    System.out.println("关闭Reader输入流失败");
                }
            }
        }
    }
    //使用Arrays工具类方法输出打印字节数组
    public static void arraysClassMethodToPrintCharacterArray(char[] chars, int charLen) {
        for (int i = 0; i < charLen; i++) {
            if ((chars[i] == '\r') || (chars[i] == '\n')) {
                chars[i] = (char) 0;
            }
        }
        System.out.println(Arrays.toString(Arrays.copyOfRange(chars, 0, charLen)));
    }
}
  • 12.2.2、运行结果(Run Result)

其运行结果,如以下信息所示

Reader类与FileReader类批量读入文件字符数据:
使用Reader类的read方法开始批量读入文件字符数据
[R, e, a, d, e, r,  ,  ]
[0, 1, 2, 3, 4, 5, 6, 7]
[8, 9,  ,  ,,,,]
[,,]
使用Reader类的read方法批量读入文件字符数据完成
关闭Reader输入流成功

13、关闭输出流(Close Output Stream)

13.1、关闭OutputStream输入流(Close OutputStream Input Stream)

  • 13.1.1、示例代码(Sample Code)

其示例,如以下代码所示

package com.xueshanxuehai.io.outputstream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.FileNotFoundException;
import java.io.UnsupportedEncodingException;
import java.io.IOException;
public class CloseOutputStream {
    public static void main(String[] args) {
        OutputStream outputStream1=null;//文件字节输出流
        OutputStream  outputStream2=null;//文件字节输出流
        try {
            System.out.println("OutputStream类与FileOutputStream类批量写出文件字节数据:");
            outputStream1=new FileOutputStream("E:\\ReadWriteFile\\OutputStream.txt");
            System.out.println("使用OutputStream类的write方法开始批量写出文件字节数据(覆盖)");
            byte[] bytes1="批量写出文件字节数据(覆盖)".getBytes("UTF-8");
            outputStream1.write(bytes1);//批量写出文件字节数据(覆盖)
            outputStream1.flush();//刷新输出流
            outputStream1.close();//关闭输出流
            System.out.println("使用OutputStream类的write方法批量写出文件字节数据完成(覆盖)");
            outputStream2=new FileOutputStream("E:\\ReadWriteFile\\OutputStream.txt",true);
            System.out.println("使用OutputStream类的write方法开始批量写出文件字节数据(追加)");
            byte[] bytes2="批量写出文件字节数据(追加)".getBytes("UTF-8");
            outputStream2.write(bytes2);//批量写出文件字节数据(追加)
            outputStream2.flush();//刷新输出流
            outputStream2.close();//关闭输出流
            System.out.println("使用OutputStream类的write方法批量写出文件字节数据完成(追加)");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
  • 13.1.2、运行结果(Run Result)

其运行结果,如以下信息所示

OutputStream类与FileOutputStream类批量写出文件字节数据:
使用OutputStream类的write方法开始批量写出文件字节数据(覆盖)
使用OutputStream类的write方法批量写出文件字节数据完成(覆盖)
使用OutputStream类的write方法开始批量写出文件字节数据(追加)
使用OutputStream类的write方法批量写出文件字节数据完成(追加)

13.2、关闭Writer输入流(Close Writer Input Stream)

  • 13.2.1、示例代码(Sample Code)

其示例,如以下代码所示

package com.xueshanxuehai.io.writer;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
public class CloseWriter {
    public static void main(String[] args) {
        Writer writer1=null;//文件字符输出流
        Writer writer2=null;//文件字符输出流
        try {
            System.out.println("Writer类与FileWriter类批量写出文件字符数据:");
            writer1=new FileWriter("E:\\ReadWriteFile\\Writer.txt");
            System.out.println("使用Writer类的write方法开始批量写出文件字符数据(覆盖)");
            char[] chars1="批量写出文件字符数据(覆盖)".toCharArray();
            writer1.write(chars1);//批量写出文件字符数据(覆盖)
            writer1.flush();//刷新输出流
            writer1.close();//关闭输出流
            System.out.println("使用Writer类的write方法批量写出文件字符数据完成(覆盖)");
            writer2=new FileWriter("E:\\ReadWriteFile\\Writer.txt",true);
            System.out.println("使用Writer类的write方法开始批量写出文件字符数据(追加)");
            char[] chars2="批量写出文件字符数据(追加)".toCharArray();
            writer2.write(chars2);//批量写出文件字符数据(追加)
            writer2.flush();//刷新输出流
            writer2.close();//关闭输出流
            System.out.println("使用Writer类的write方法批量写出文件字符数据完成(追加)");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
  • 13.2.2、运行结果(Run Result)

其运行结果,如以下信息所示

Writer类与FileWriter类批量写出文件字符数据:
使用Writer类的write方法开始批量写出文件字符数据(覆盖)
使用Writer类的write方法批量写出文件字符数据完成(覆盖)
使用Writer类的write方法开始批量写出文件字符数据(追加)
使用Writer类的write方法批量写出文件字符数据完成(追加)

14、处理流(Process Stream)

14.1、BufferedInputStream处理流(BufferedInputStream Process Stream)

  • 14.1.1、示例代码(Sample Code)

其示例,如以下代码所示

package com.xueshanxuehai.io.processstream;
import java.io.*;
import java.util.Arrays;
public class BufferedInputStreamClass {
    public static void main(String[] args){
        InputStream inputStream=null;//创建BufferedInputStream处理流
        try {
            inputStream=new BufferedInputStream(new FileInputStream("E:\\ReadWriteFile\\InputStream.txt"));
            System.out.println("InputStream类、BufferedInputStream类、FileInputStream类批量读入文件字节数据(处理流):");
            System.out.println("使用InputStream类的read方法开始批量读入文件字节数据(处理流)");
            byte[] bytes = new byte[32];
            int byteLen = 0;
            while ((byteLen = inputStream.read(bytes)) != -1) {
              System.out.println(Arrays.toString(Arrays.copyOfRange(bytes,0,byteLen)));//使用Arrays工具类方法输出打印字节数组
            }
            System.out.println("使用InputStream类的read方法批量读入文件字节数据完成(处理流)");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(inputStream!=null){
                try {
                    inputStream.close();
                    System.out.println("关闭InputStream输入流成功(处理流)");
                } catch (IOException e) {
                    e.printStackTrace();
                    System.out.println("关闭InputStream输入流失败(处理流)");
                }
            }
        }
    }
}
  • 14.1.2、运行结果(Run Result)

其运行结果,如以下信息所示

InputStream类、BufferedInputStream类、FileInputStream类批量读入文件字节数据(处理流):
使用InputStream类的read方法开始批量读入文件字节数据(处理流)
[-26, -119, -71, -23, -121, -113, -27, -122, -103, -27, -121, -70, -26, -106, -121, -28, -69, -74, -27, -83, -105, -24, -118, -126, -26, -107, -80, -26, -115, -82, 40, -24]
[-90, -122, -25, -101, -106, 41, 40, -27, -92, -124, -25, -112, -122, -26, -75, -127, 41]
使用InputStream类的read方法批量读入文件字节数据完成(处理流)
关闭InputStream输入流成功(处理流)

14.2、BufferedOutputStream处理流(BufferedOutputStream Process Stream)

  • 14.2.1、示例代码(Sample Code)

其示例,如以下代码所示

package com.xueshanxuehai.io.processstream;
import java.io.*;
public class BufferedOutputStreamClass {
    public static void main(String[] args) {
        OutputStream outputStream1=null;//创建BufferedOutputStream处理流
        OutputStream outputStream2=null;//创建BufferedOutputStream处理流
        try {
            outputStream1=new BufferedOutputStream(new FileOutputStream("E:\\ReadWriteFile\\InputStream.txt"));
            System.out.println("OutputStream类、BufferedOutputStream类、FileOutputStream类批量写出文件字节数据(处理流):");
            System.out.println("使用OutputStream类的write方法开始批量写出文件字节数据(覆盖)(处理流)");
            byte[] bytes1="批量写出文件字节数据(覆盖)(处理流)".getBytes("UTF-8");
            outputStream1.write(bytes1);//批量写出文件字节数据(覆盖)
            outputStream1.flush();//刷新输出流
            outputStream1.close();//关闭输出流
            System.out.println("使用OutputStream类的write方法批量写出文件字节数据完成(覆盖)(处理流)");
            outputStream2=new FileOutputStream("E:\\ReadWriteFile\\OutputStream.txt",true);
            System.out.println("使用OutputStream类的write方法开始批量写出文件字节数据(追加)(处理流)");
            byte[] bytes2="批量写出文件字节数据(追加)(处理流)".getBytes("UTF-8");
            outputStream2.write(bytes2);//批量写出文件字节数据(追加)
            outputStream2.flush();//刷新输出流
            outputStream2.close();//关闭输出流
            System.out.println("使用OutputStream类的write方法批量写出文件字节数据完成(追加)(处理流)");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
  • 14.2.2、运行结果(Run Result)

其运行结果,如以下信息所示

OutputStream类、BufferedOutputStream类、FileOutputStream类批量写出文件字节数据(处理流):
使用OutputStream类的write方法开始批量写出文件字节数据(覆盖)(处理流)
使用OutputStream类的write方法批量写出文件字节数据完成(覆盖)(处理流)
使用OutputStream类的write方法开始批量写出文件字节数据(追加)(处理流)
使用OutputStream类的write方法批量写出文件字节数据完成(追加)(处理流)

14.3、BufferedReader处理流(BufferedReader Process Stream)

  • 14.3.1、示例代码(Sample Code)

其示例,如以下代码所示

package com.xueshanxuehai.io.processstream;
import java.io.*;
public class BufferedReaderClass {
    public static void main(String[] args) {
        BufferedReader bufferedReader=null;//创建BufferedReader处理流
        try {
            bufferedReader=new BufferedReader(new FileReader("E:\\ReadWriteFile\\Reader.txt"));
            System.out.println("BufferedReader类与FileReader类读入文件字符数据(处理流):");
            System.out.println("使用BufferedReader类的readLine方法开始读入文件字符数据(处理流)");
            //批量读入文件字符数据(一行一行的读入)
            String strLine="";
            while ((strLine = bufferedReader.readLine()) != null) {
                System.out.println(strLine);
            }
            System.out.println("使用BufferedReader类的readLine方法读入文件字符数据完成(处理流)");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                bufferedReader.close();
                System.out.println("关闭BufferedReader输入流成功(处理流)");
            } catch (IOException e) {
                e.printStackTrace();
                System.out.println("关闭BufferedReader输入流失败(处理流)");
            }
        }
    }
}
  • 14.3.2、运行结果(Run Result)

其运行结果,如以下信息所示

BufferedReader类与FileReader类读入文件字符数据(处理流):
使用BufferedReader类的readLine方法开始读入文件字符数据(处理流)
Reader
0123456789
中华人民共和国
使用BufferedReader类的readLine方法读入文件字符数据完成(处理流)
关闭BufferedReader输入流成功(处理流)

14.4、BufferedWriter处理流(BufferedWriter Process Stream)

  • 14.4.1、示例代码(Sample Code)

其示例,如以下代码所示

package com.xueshanxuehai.io.processstream;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
public class BufferedWriterClass {
    public static void main(String[] args) {
        BufferedWriter bufferedWriter1=null;//创建BufferedWriter处理流
        BufferedWriter bufferedWriter2=null;//创建BufferedWriter处理流
        try {
            System.out.println("BufferedWriter类与FileWriter类批量写出文件字符数据(处理流):");
            bufferedWriter1=new BufferedWriter(new FileWriter("E:\\ReadWriteFile\\Writer.txt"));
            System.out.println("使用BufferedWriter类的write方法开始批量写出文件字符数据(覆盖)(处理流)");
            char[] chars1="批量写出文件字符数据(覆盖)(处理流)".toCharArray();
            bufferedWriter1.write(chars1);//批量写出文件字符数据(覆盖)
            bufferedWriter1.flush();//刷新输出流
            bufferedWriter1.close();//关闭输出流
            System.out.println("使用BufferedWriter类的write方法批量写出文件字符数据完成(覆盖)(处理流)");
            bufferedWriter2=new BufferedWriter(new FileWriter("E:\\ReadWriteFile\\Writer.txt",true));
            System.out.println("使用BufferedWriter类的write方法开始批量写出文件字符数据(追加)(处理流)");
            char[] chars2="批量写出文件字符数据(追加)(处理流)".toCharArray();
            bufferedWriter2.write(chars2);//批量写出文件字符数据(追加)
            bufferedWriter2.flush();//刷新输出流
            bufferedWriter2.close();//关闭输出流
            System.out.println("使用BufferedWriter类的write方法批量写出文件字符数据完成(追加)(处理流)");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
  • 14.4.2、运行结果(Run Result)

其运行结果,如以下信息所示

BufferedWriter类与FileWriter类批量写出文件字符数据(处理流):
使用BufferedWriter类的write方法开始批量写出文件字符数据(覆盖)(处理流)
使用BufferedWriter类的write方法批量写出文件字符数据完成(覆盖)(处理流)
使用BufferedWriter类的write方法开始批量写出文件字符数据(追加)(处理流)
使用BufferedWriter类的write方法批量写出文件字符数据完成(追加)(处理流)

15、练习(Exercise)

练习作业:将一个文件或文件夹(包含其所有子文件夹与子文件))从一个磁盘复制到另一个磁盘

  • 15.1、示例代码(Sample Code)

其示例,如以下代码所示

package com.xueshanxuehai.io.exercise;
import java.io.*;
/**
 * 1、将一个文件从一个磁盘复制到另一个磁盘
 * 2、将一个文件夹从一个磁盘复制到另一个磁盘
 */
public class CopyFileAndFolderBetweenDisk {
    public static void main(String[] args) {
        //将一个文件从一个磁盘复制到另一个磁盘
        String sourceDirectory1 = "E:\\ReadWriteFile";//源目录
        String destinationDirectory1 = "D:\\";//目标目录
        String copyFile = "CopyFile.txt";//复制文件名称
        File file1 = new File(sourceDirectory1 + "\\" + copyFile);//创建File类对象
        System.out.println("复制源目录(" + sourceDirectory1 + ")的指定文件(" + copyFile + ")到目标目录(" + destinationDirectory1 + ")<开始>");
        CreateAllSubFile(file1, sourceDirectory1, destinationDirectory1);//递归创建指定文件目录下的指定文件
        System.out.println("复制源目录(" + sourceDirectory1 + ")的指定文件(" + copyFile + ")到目标目录(" + destinationDirectory1 + ")<完成>");
        //将一个文件夹从一个磁盘复制到另一个磁盘
        String sourceDirectory2 = "E:";//源目录
        String destinationDirectory2 = "D:\\";//目标目录
        String copyDirectory = "ReadWriteFile";//复制文件目录名称
        File file2 = new File(sourceDirectory2 + "\\" + copyDirectory);//创建File类对象
        System.out.println("复制源目录(" + sourceDirectory2 + ")的指定文件目录(" + copyDirectory + ")到目标目录(" + destinationDirectory2 + ")<开始>");
        CreateAllSubFile(file2, sourceDirectory2, destinationDirectory2);//递归创建指定文件目录下的所有子文件
        System.out.println("复制源目录(" + sourceDirectory2 + ")的指定文件目录(" + copyDirectory + ")到目标目录(" + destinationDirectory2 + ")<完成>");
    }
    public static void CreateAllSubFile(File file, String srcDir, String destDir) {
        /**
         *递归创建指定文件目录下的所有子文件
         */
        //判断文件是否为文件目录
        if (file.isDirectory()) {//File类对象为文件夹
            File file3 = new File(file.toString().replace(srcDir, destDir));
            if (!file3.exists()) {//文件目录不存在
                if (!file3.mkdirs()) {//创建文件目录失败
                    System.out.println("创建文件目录(" + file3.toString() + ")失败");
                }
            }
            File[] fileArr = file.listFiles();//获取文件目录的所有子文件
            String[] fileString = file.list();//获取文件目录的所有子文件路径
            for (int i = 0; i < fileArr.length; i++) {
                //System.out.println(fileString[i]);//输出子文件或子文件夹路径
                CreateAllSubFile(fileArr[i], srcDir, destDir);//递归创建指定文件目录下的所有子文件
            }
        } else {
            File file4 = new File(file.toString().substring(0, file.toString().lastIndexOf("\\")).replace(srcDir, destDir), file.toString().substring(file.toString().lastIndexOf("\\") + 1, file.toString().length()));
            if (!file4.exists()) {//文件不存在
                if (!file4.getParentFile().exists()) {//文件父级目录不存在
                    if (!file4.getParentFile().mkdirs()) {//创建文件父级目录失败
                        System.out.println("创建文件父级目录(" + file4.getParentFile().toString() + ")失败");
                        return;//返回方法参数并退出方法
                    }
                }
                try {
                    file4.createNewFile();//创建文件(默认为空)
                    /**
                     *先使用BufferedReader处理流读入文件字符数据,再使用BufferedWriter处理流写出文件字符数据
                     *且边读边写,即“读一行写一行”
                     */
                    readFileData_BufferedReader(file.toString(), file4.toString());
                } catch (IOException e) {
                    e.printStackTrace();
                    System.out.println("创建文件(" + file4.toString() + ")失败");
                }
            }
        }
        return;//返回方法参数并退出方法
    }
    private static void readFileData_BufferedReader(String strReadFile, String strWriteFile) {
        /**
         *使用BufferedReader处理流读入文件字符数据
         *批量读入文件字符数据(一行一行的读入)
         */
        BufferedReader bufferedReader = null;//创建BufferedReader处理流
        try {
            bufferedReader = new BufferedReader(new FileReader(strReadFile));
            //批量读入文件字符数据(一行一行的读入)
            String strLine = "";
            while ((strLine = bufferedReader.readLine()) != null) {
                writeFileData_BufferedWriter(strWriteFile, strLine + "\r\n");
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                bufferedReader.close();
            } catch (IOException e) {
                e.printStackTrace();
                System.out.println("关闭BufferedReader输入流失败(处理流)");
            }
        }
        return;//返回方法参数并退出方法
    }
    private static void writeFileData_BufferedWriter(String strFile, String strFileReadData) {
        /**
         *使用BufferedWriter处理流写出文件字符数据
         *批量写出文件字符数据(一行一行的写出)
         */
        BufferedWriter bufferedWriter = null;//创建BufferedWriter处理流
        try {
            bufferedWriter = new BufferedWriter(new FileWriter(strFile, true));
            bufferedWriter.write(strFileReadData);//批量写出文件字符数据(追加)
            //bufferedWriter.write(strFileReadData.toCharArray());//批量写出文件字符数据(追加)
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                bufferedWriter.flush();//刷新输出流
                bufferedWriter.close();//关闭输出流
            } catch (IOException e) {
                e.printStackTrace();
                System.out.println("刷新或关闭BufferedWriter输出流失败(处理流)");
            }
        }
    }
}
  • 15.2、运行结果(Run Result)

其运行结果,如以下信息所示

复制源目录(E:\ReadWriteFile)的指定文件(CopyFile.txt)到目标目录(D:\)<开始>
复制源目录(E:\ReadWriteFile)的指定文件(CopyFile.txt)到目标目录(D:\)<完成>
复制源目录(E:)的指定文件目录(ReadWriteFile)到目标目录(D:\)<开始>
复制源目录(E:)的指定文件目录(ReadWriteFile)到目标目录(D:\)<完成>

16、编码格式发展史(Code Format Development History)

编码格式发展史示意图,如下图所示

编码格式发展史示意图

17、转换流(Conversion Stream)

17.1、InputStreamReader转换流(InputStreamReader Conversion Stream)

将字节流转换为字符流

  • 17.1.1、示例代码(Sample Code)

其示例,如以下代码所示

package com.xueshanxuehai.io.processstream;
import java.io.*;
/**
 * InputStreamReader
 * 将字节流转换为字符流
 */
public class InputStreamReaderClass {
    public static void main(String[] args) throws IOException {
        /**
         //方式一
         //文件输入流
         InputStream inputStream=new FileInputStream("E:\\ReadWriteFile\\20210713001.txt");
         //转换流
         Reader reader= new InputStreamReader(inputStream,"GBK");
         //缓冲流
         BufferedReader bufferedReader = new BufferedReader(reader);
         */
        /**
         *方式二
         */
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream("E:\\ReadWriteFile\\20210713001.txt"), "GBK"));
        //读入文件数据
        String strLine = "";
        while ((strLine = bufferedReader.readLine()) != null) {
            System.out.println(strLine);
        }
        //关闭流
        bufferedReader.close();
    }
}
  • 17.1.2、运行结果(Run Result)

其运行结果,如以下信息所示

1
China
Chinese
中国

18、数据处理流(Data Process Stream)

18.1、DataOutputStream数据处理流(DataOutputStream Data Process Stream)

其作用是“将内存数据写出到磁盘”

  • 18.1.1、示例代码(Sample Code)

其示例,如以下代码所示

package com.xueshanxuehai.io.processstream;
import java.io.*;
public class DataOutputStreamClass {
    public static void main(String[] args) throws IOException {
        String strFile="";
        strFile="E:\\ReadWriteFile\\Test.test";//文件目录
        dataOutputStream(strFile);
    }
    private static void dataOutputStream(String strFile) throws IOException {
        //数据
        int id=1;
        String uid="Test";
        String pwd="123";
        //处理输出流数据
        DataOutputStream dataOutputStream=new DataOutputStream(new BufferedOutputStream(new FileOutputStream(strFile)));
        //写出输出流数据
        dataOutputStream.writeInt(id);
        System.out.println("写出id:"+id);
        dataOutputStream.writeUTF(uid);
        System.out.println("写出uid:"+uid);
        dataOutputStream.writeUTF(pwd);
        System.out.println("写出pwd:"+pwd);
        //刷新与关闭输出流
        dataOutputStream.flush();
        dataOutputStream.close();
    }
}
  • 18.1.2、运行结果(Run Result)

其运行结果,如以下信息所示

写出id:1
写出uid:Test
写出pwd:123

18.2、DataInputStream数据处理流(DataInputStream Data Process Stream)

其作用是“将磁盘文件数据恢复到内存”

  • 18.2.1、示例代码(Sample Code)

其示例,如以下代码所示

package com.xueshanxuehai.io.processstream;
import java.io.*;
public class DataInputStreamClass {
    public static void main(String[] args) throws IOException {
        String strFile="";
        strFile="E:\\ReadWriteFile\\Test.test";//文件目录
        dataInputStream(strFile);
    }
    private static void dataInputStream(String strFile) throws IOException {
        //处理输入流数据
        DataInputStream dataInputStream=new DataInputStream(new BufferedInputStream(new FileInputStream(strFile)));
        //读入输入流数据
        System.out.println("读入id:"+dataInputStream.readInt());
        System.out.println("读入uid:"+dataInputStream.readUTF());
        System.out.println("读入pwd:"+dataInputStream.readUTF());
        //关闭输入流
        dataInputStream.close();
    }
}
  • 18.2.2、运行结果(Run Result)

其运行结果,如以下信息所示

读入id:1
读入uid:Test
读入pwd:123

19、JavaBean

JavaBean是一种JAVA语言写成的可重用组件

用户可以使用JavaBean将功能、处理、值、数据库访问和其他任何可以用java代码创造的对象进行打包,并且其他的开发者可以通过内部的JSP页面、Servlet、其他JavaBean、applet程序或者应用来使用这些对象。用户可以认为JavaBean提供了一种随时随地的复制和粘贴的功能,而不用关心任何改变

JavaBean可分为两种:一种是有用户界面(UI,User Interface)的JavaBean;还有一种是没有用户界面,主要负责处理事务(如数据运算,操纵数据库)的JavaBean。JSP通常访问的是后一种JavaBean

19.1、三大约束(Three Constraints)

  • 19.1.1、写成JavaBean时,类必须是具体的和公共的,并且具有无参数的构造器(即,必须声明公共类的无参构造器<防止被重写构造器覆盖>)
  • 19.1.2、写成JavaBean时,类中属性必须是私有的(即,类属性私有化)
  • 19.1.3、写成JavaBean时,类通过提供符合一致性设计模式的公共方法将内部域暴露成员属性,set和get方法获取(即,设置类属性的set方法与get方法)

19.2、类属性变量名命名的第二个字符问题(The Second Character Problem Of Class Attribute Variable Name Naming)

其示例,如以下代码所示

package com.xueshanxuehai.io.javabean;
import java.util.Objects;
/**
 * 写成JavaBean时,类属性变量名命名的第二个字符问题
 */
public class User {
    /**
     * 设置属性set方法与get方法时,若属性名称中第二个字母不是大写,则大写其方法名称中"set或get"之后属性名称的首字母
     */
    private String uname;
    private String Uname;
    /**
     * 设置属性set方法与get方法时,若属性名称中第二个字母是大写,则不大写其方法名称中"set或get"之后属性名称的首字母
     */
    private String uName;
    private String UName;
    //无参构造器(即,空构造器)
    public User() {
    }
    public String getUname() {
        return uname;
    }
    public void setUname(String uname) {
        this.uname = uname;
    }
    public String getuName() {
        return uName;
    }
    public void setuName(String uName) {
        this.uName = uName;
    }
    public String getUName() {
        return UName;
    }
    public void setUName(String UName) {
        this.UName = UName;
    }
    @Override
    public String toString() {
        return "User{" +
                "uname='" + uname + '\'' +
                ", Uname='" + Uname + '\'' +
                ", uName='" + uName + '\'' +
                ", UName='" + UName + '\'' +
                '}';
    }
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        User user = (User) o;
        return Objects.equals(uname, user.uname) && Objects.equals(Uname, user.Uname) && Objects.equals(uName, user.uName) && Objects.equals(UName, user.UName);
    }
    @Override
    public int hashCode() {
        return Objects.hash(uname, Uname, uName, UName);
    }
}

19.3、JavaBean类、ObjectOutputStream类、ObjectInputStream类(JavaBean Class And ObjectOutputStream Class And ObjectInputStream Class)

19.3.1、JavaBean类(JavaBean Class)

其示例代码,如以下所示

package com.xueshanxuehai.io.javabean;
import java.io.Serializable;
import java.util.Objects;
/**
 *员工类
 *1.必须声明空构造器(防止被重写构造器覆盖);
 *2.属性私有化;
 *3.设置属性的set方法与get方法;
 *4.重写toString方法;
 *5.重写equals方法与hashCode方法;
 *6.使用transient关键字的类对象不允许序列化;
 */
//public class Employee {//Exception in thread "main" java.io.NotSerializableException: com.xueshanxuehai.io.javabean.Employee
public class Employee implements Serializable {
    private static final long serialVersionUID = -4914578680201043792L;//序列化版本号
    private int empno;//员工编号
    private String empname;//员工姓名
    private transient String deptno;//部门编号
    private transient String deptname;//部门名称
    private transient String jobno;//职务(岗位)编号
    private transient String jobname;//职务(岗位)名称
    private transient double salary;//薪资
    private transient double allowance;//津贴(补助)
    private transient int mgrno;//主管编号
    private transient String mgrname;//主管名称
    private transient long phonenumber;//电话号码
    //空构造器(即,无参构造器)
    public Employee() {
    }
    //有参构造器
    public Employee(int empno, String empname, String deptno, String deptname, String jobno, String jobname, double salary, double allowance, int mgrno, String mgrname, long phonenumber) {
        this.empno = empno;
        this.empname = empname;
        this.deptno = deptno;
        this.deptname = deptname;
        this.jobno = jobno;
        this.jobname = jobname;
        this.salary = salary;
        this.allowance = allowance;
        this.mgrno = mgrno;
        this.mgrname = mgrname;
        this.phonenumber = phonenumber;
    }
    public int getEmpno() {
        return empno;
    }
    public void setEmpno(int empno) {
        this.empno = empno;
    }
    public String getEmpname() {
        return empname;
    }
    public void setEmpname(String empname) {
        this.empname = empname;
    }
    public String getDeptno() {
        return deptno;
    }
    public void setDeptno(String deptno) {
        this.deptno = deptno;
    }
    public String getDeptname() {
        return deptname;
    }
    public void setDeptname(String deptname) {
        this.deptname = deptname;
    }
    public String getJobno() {
        return jobno;
    }
    public void setJobno(String jobno) {
        this.jobno = jobno;
    }
    public String getJobname() {
        return jobname;
    }
    public void setJobname(String jobname) {
        this.jobname = jobname;
    }
    public double getSalary() {
        return salary;
    }
    public void setSalary(double salary) {
        this.salary = salary;
    }
    public double getAllowance() {
        return allowance;
    }
    public void setAllowance(double allowance) {
        this.allowance = allowance;
    }
    public int getMgrno() {
        return mgrno;
    }
    public void setMgrno(int mgrno) {
        this.mgrno = mgrno;
    }
    public String getMgrname() {
        return mgrname;
    }
    public void setMgrname(String mgrname) {
        this.mgrname = mgrname;
    }
    public long getPhonenumber() {
        return phonenumber;
    }
    public void setPhonenumber(long phonenumber) {
        this.phonenumber = phonenumber;
    }
    //重写toString方法
    @Override
    public String toString() {
        return "Employee{" +
                "empno=" + empno +
                ", empname='" + empname + '\'' +
                ", deptno='" + deptno + '\'' +
                ", deptname='" + deptname + '\'' +
                ", jobno='" + jobno + '\'' +
                ", jobname='" + jobname + '\'' +
                ", salary=" + salary +
                ", allowance=" + allowance +
                ", mgrno=" + mgrno +
                ", mgrname='" + mgrname + '\'' +
                ", phonenumber=" + phonenumber +
                '}';
    }
    //重写equals方法
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Employee employee = (Employee) o;
        return empno == employee.empno && Double.compare(employee.salary, salary) == 0 && Double.compare(employee.allowance, allowance) == 0 && mgrno == employee.mgrno && phonenumber == employee.phonenumber && Objects.equals(empname, employee.empname) && Objects.equals(deptno, employee.deptno) && Objects.equals(deptname, employee.deptname) && Objects.equals(jobno, employee.jobno) && Objects.equals(jobname, employee.jobname) && Objects.equals(mgrname, employee.mgrname);
    }
    //重写hashCode方法
    @Override
    public int hashCode() {
        return Objects.hash(empno, empname, deptno, deptname, jobno, jobname, salary, allowance, mgrno, mgrname, phonenumber);
    }
}
19.3.2、ObjectOutputStream类(ObjectOutputStream Class)

其作用是“将对象序列化到磁盘”

其示例代码,如以下所示

package com.xueshanxuehai.io.javabean;
import java.io.*;
/**
 *ObjectOutputStream
 *将对象序列化到磁盘
 */
public class ObjectOutputStreamClass {
    public static void main(String[] args) throws IOException {
        //文件目录
        String strFile="";
        strFile="E:\\ReadWriteFile\\Employee.emp";
//        //方式一
//        //实例化类对象
//        Employee employee=new Employee();
//        //设置类对象的属性值
//        employee.setEmpno(123);
//        employee.setEmpname("奋斗者");
//        employee.setDeptno("IT001");
//        employee.setDeptname("软件开发");
//        employee.setJobno("IT001_001");
//        employee.setJobname("系统架构");
//        employee.setSalary(12345.67890);
//        employee.setAllowance(2345.6789);
//        employee.setMgrno(1);
//        employee.setMgrname("创业者");
//        employee.setPhonenumber(12345654321L);
        //方式二
        Employee employee=new Employee(123,"奋斗者","IT001","软件开发","IT001_001","系统架构",12345.67890,2345.6789,1,"创业者",12345654321L);
        objectOutputStream(strFile, employee);
    }
    private static void objectOutputStream(String strFile, Employee employee) throws IOException {
        //处理对象输出流数据(即,处理对象)
        ObjectOutputStream objectOutputStream=new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(strFile)));
        //写出对象输出流数据(即,写出对象)
        objectOutputStream.writeObject(employee);
        //关闭对象输出流
        objectOutputStream.flush();//刷新
        objectOutputStream.close();//关闭
    }
}
19.3.3、ObjectInputStream类(ObjectInputStream Class)

其作用是“将对象反序列化到内存”

其示例代码,如以下所示

package com.xueshanxuehai.io.javabean;
import java.io.*;
/**
 *ObjectInputStream
 *将对象反序列化到内存
 */
public class ObjectInputStreamClass {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        //文件目录
        String strFile="";
        strFile="E:\\ReadWriteFile\\Employee.emp";
        objectInputStream(strFile);
    }
    private static void objectInputStream(String strFile) throws IOException, ClassNotFoundException {
        //处理对象输入流数据
        ObjectInputStream objectInputStream=new ObjectInputStream(new BufferedInputStream(new FileInputStream(strFile)));
        //读入对象输入流数据
        Object object= objectInputStream.readObject();
        //判断对象
        if(object instanceof Employee){
            Employee employee=(Employee)object;
            System.out.println(employee);
        }
        //关闭对象输入流
        objectInputStream.close();
    }
}
19.3.4、运行结果(Run Result)

其运行结果,如以下信息所示

Employee{empno=123, empname='奋斗者', deptno='null', deptname='null', jobno='null', jobname='null', salary=0.0, allowance=0.0, mgrno=0, mgrname='null', phonenumber=0}

19.4、注意事项(Matters Needing Attention)

  • 1、设置属性set方法与get方法时,若属性名称中第二个字母不是大写,则大写其方法名称中"set或get"之后属性名称的首字母
  • 2、设置属性set方法与get方法时,若属性名称中第二个字母是大写,则不大写其方法名称中"set或get"之后属性名称的首字母
  • 3、在JavaBean类中使用ObjectOutputStream类将对象序列化到磁盘时,需让相关JavaBean类实现“Serializable”接口才可以成功,否则会触发异常(即,java.io.NotSerializableException)
  • 4、在JavaBean类中使用transient关键字的类对象不允许序列化(如“private transient String deptno”)
  • 5、在JavaBean类中使用serialVersionUID版本反序列化时,若serialVersionUID版本相同,则可以反序列化,否则(如“修改JavaBean类属性时”)会反序列化异常(即,java.io.InvalidCastException)

20、ByteArrayOutputStream类、ByteArrayInputStream类(ByteArrayOutputStream Class And ByteArrayInputStream Class)

ByteArrayOutputStream类作用是“写入数据至内存中的某个数组”,ByteArrayInputStream类作用是“读取内存中的某个数组数据”,经常用在需要流与数组之间转换的情况

  • 20.1、示例代码(Sample Code)

其示例,如以下代码所示

package com.xueshanxuehai.io.processstream;
import java.io.*;
/**
 *ByteArrayOutputStream类:写入数据至内存中的某个数组
 *ByteArrayInputStream类:读取内存中的某个数组数据
 */
public class ByteArrayOutputStreamAndByteArrayInputStream {
    public static void main(String[] args) throws IOException {
        String str="123Abc";//字符串
        byte[] bytes=str.getBytes();//字节数组
        System.out.println("使用ByteArrayOutputStream类写入数据至内存中的某个数组");
        ByteArrayOutputStream byteArrayOutputStream=new ByteArrayOutputStream();
        byteArrayOutputStream.write(bytes);
        System.out.println(byteArrayOutputStream.toString("UTF-8"));
        byteArrayOutputStream.flush();//无需刷新数组输出流(写与不写都一样)
        byteArrayOutputStream.close();//无需关闭数组输出流(写与不写都一样)
        System.out.println("使用ByteArrayInputStream类读取内存中的某个数组数据");
        ByteArrayInputStream byteArrayInputStream=new ByteArrayInputStream(bytes);
        for (int i = 0; i < bytes.length; i++) {
            System.out.print(byteArrayInputStream.read()+"\t");
        }
        System.out.println();
        byteArrayInputStream.close();//无需关闭数组输入流(写与不写都一样)
    }
}
  • 20.2、运行结果(Run Result)

其运行结果,如以下信息所示

使用ByteArrayOutputStream类写入数据至内存中的某个数组
123Abc
使用ByteArrayInputStream类读取内存中的某个数组数据
49	50	51	65	98	99	
  • 20.3、注意事项(Matters Needing Attention)
    • 20.3.1、由于ByteArrayOutputStream与ByteArrayInputStream本身操作的是数组流,并没有打开文件描述之类的流,所以不需要关闭对应输入输出与输出流(但也可以调用close方法关闭,只是close方法不做任何事情)

21、Apache Commons IO

Commons IO就是其他人写好的一些工具类,我们为了方便才会去使用而已

Commons IO是Apache的一个开源工具包,封装了IO操作的相关类,使用Commons IO可以很方便的读写文件、url源代码等,Commons IO需要加入classpath的第三方jar包内的class文件才能在项目中使用

  • 1、IOUtils包含一些工具类,它们的方法基于InputStream、OutputStream、Reader、Writer类工作,用于处理读、写 、复制(拷贝)
  • 2、FileUtils包含一些工具类,它们基于File对象工作,包括读、写、复制(拷贝)、比较文件
  • 3、FilenameUtils包含一些工具类,它们基于文件名工作而不是File对象,这个类宗旨就是在Unix和Windows环境下保持一致,帮助在两个环境下过度(如从开发环境到生成环境)
  • 4、FileSystemUtils包含一些工具类,基于文件系统访问功能不被JDK支持。目前,只有一个方法就是得到驱动器空余空间。且要注意的是,这里使用的是命令行而不是native code(本地或原生代码)

21.1、原生Java项目添加Commons IO Jar包以及Commons IO源代码Jar包(Native Java Project Add Commons IO Jar Package And Commons IO Source Code Jar Package)

  • 21.1.1、官网下载Apache Commons IO软件,如下图所示

    下载Apache Commons IO软件

  • 21.1.2、解压commons-io压缩文件,如下图所示

    解压commons-io压缩文件

  • 21.1.3、新建工程项目Commons-IO与文件目录lib,如下图所示

    新建工程Commons-IO与文件目录lib

  • 21.1.4、直接将解压的Commons IO jar包文件复制到文件目录lib中,如下图所示

    直接将解压的jar包文件复制到文件目录lib中

  • 21.1.5、设置工程项目库001,如下图所示

    设置工程项目库001

  • 21.1.6、设置工程项目库002,如下图所示

    设置工程项目库002

  • 21.1.7、设置工程项目库003,如下图所示

    设置工程项目库003

  • 21.1.8、设置工程项目库004,如下图所示

    设置工程项目库004

  • 21.1.9、添加Commons IO源代码 Jar包(与上述添加Commons IO Jar包操作步骤类似,这里不再重复操作),最终结果如下图所示

添加commons-io-sources.jar包

21.2、Commons IO的IOUtils(Commons IO IOUtils)

  • 21.2.1、示例代码(Sample Code)

其示例,如以下代码所示

package com.xueshanxuehai.apache.commonsio;
import org.apache.commons.io.IOUtils;
import java.io.*;
public class IOUtilsClass {
    public static void main(String[] args) throws IOException {
        //复制文件
        IOUtils.copy(new FileInputStream("E:\\ReadWriteFile\\commons-io-ioutils.txt"),new FileOutputStream("D:\\commons-io-ioutils.txt"));
        //复制较大文件(一般复制2G以上文件时建议使用此方法),默认会用1024*8=8192B=8KB的buffer来读取
        IOUtils.copyLarge(new FileInputStream("E:\\ReadWriteFile\\commons-io-ioutils.txt"),new FileOutputStream("D:\\commons-io-ioutils.txt"));
        //通过文本获取输入流,可以指定编码格式
        InputStream inputStream= IOUtils.toInputStream("123中国","UTF-8");
        //获取一个缓冲输入流,默认缓冲大小1024*1=1024B=1KB,也可以指定缓冲大小
        InputStream inputStream1= IOUtils.toBufferedInputStream(inputStream,1024*2);
        //复制文件(使用缓冲输入流)
        IOUtils.copy(inputStream1,new FileOutputStream("D:\\ReadWriteFile\\BufferedInputStream.txt"));
        //获取一个字符缓冲流,默认缓冲大小1024*8=8192B=8KB,也可以指定缓冲大小
        Reader reader= IOUtils.toBufferedReader(new FileReader("E:\\ReadWriteFile\\commons-io-ioutils.txt"),1024*16);
    }
}

21.3、Commons IO的FileUtils(Commons IO FileUtils)

  • 21.3.1、示例代码(Sample Code)

其示例,如以下代码所示

package com.xueshanxuehai.apache.commonsio;
import org.apache.commons.io.FileUtils;
import java.io.File;
import java.io.IOException;
public class FileUtilsCLass {
    public static void main(String[] args) throws IOException {
        //把字节表示的文件大小转换为一个字符串(如一个1024*1024*8字节的文件,转换的结果就是8MB)
        String strByteSize=FileUtils.byteCountToDisplaySize(1024*1024*8);
        //System.out.println("FileUtils.byteCountToDisplaySize(1024*1024*8)结果为:"+FileUtils.byteCountToDisplaySize(1024*1024*8));
        //复制文件夹(文件夹里面的文件内容也会复制)
        FileUtils.copyDirectory(new File("E:\\ReadWriteFile"),new File("D:\\ReadWriteFile"));
        //复制文件夹(以子目录的形式将文件夹复制到另一个文件夹下)
        FileUtils.copyDirectoryToDirectory(new File("E:\\ReadWriteFile"),new File("D:\\ReadWriteFile"));
        //复制文件(将一个文件内容复制到另一个文件中)
        FileUtils.copyFile(new File("E:\\ReadWriteFile\\in.txt"),new File("D:\\ReadWriteFile\\out.txt"));
        //复制文件(将一个文件复制到一个指定的文件目录)
        FileUtils.copyFileToDirectory(new File("E:\\ReadWriteFile\\in.txt"),new File("D:\\ReadWriteFile\\out"));
        //把字符串写入文件(指定编码方式,指定写入字符串,且不追加<即覆盖>)
        FileUtils.writeStringToFile(new File("D:\\ReadWriteFile\\write1.txt"),"你好!中国!","GBK");
        //把字符串写入文件(指定编码方式,指定写入字符串,且追加<即不覆盖>)
        FileUtils.writeStringToFile(new File("D:\\ReadWriteFile\\write2.txt"),"你好!中国!","GBK",true);
        //把字节数组写入文件
        byte[] bytes={48,65,97,49,66,98,50,67,99};
        FileUtils.writeByteArrayToFile(new File("D:\\ReadWriteFile\\write3.txt"),bytes);
        //文件移动
        FileUtils.moveFile(new File("E:\\ReadWriteFile\\srcMove.txt"),new File("D:\\ReadWriteFile\\destMove.txt"));
        //删除文件夹(文件夹和文件夹里面的所有文件内容都会删除)
        FileUtils.deleteDirectory(new File("D:\\ReadWriteFile\\out"));
        //删除文件夹(只删除文件夹里面的所有文件内容,不会删除文件夹)
        FileUtils.cleanDirectory(new File("D:\\ReadWriteFile\\out1"));
    }
}

21.4、Commons IO的FilenameUtils(Commons IO FilenameUtils)

  • 21.4.1、示例代码(Sample Code)

其示例,如以下代码所示

package com.xueshanxuehai.apache.commonsio;
import org.apache.commons.io.FilenameUtils;
public class FilenameUtilsClass {
    public static void main(String[] args) {
        //文件名
        String strFileName = "E:\\ReadWriteFile\\FilenameUtils\\FilenameUtils.txt";
        System.out.println("指定文件名:" + strFileName);
        //获取文件路径中的盘符
        System.out.println("获取文件路径中的盘符:"+FilenameUtils.getPrefix(strFileName));
        //获取文件路径中的盘符长度
        System.out.println("获取文件路径中的盘符长度:"+FilenameUtils.getPrefixLength(strFileName));
        //获取去除盘符的文件路径
        System.out.println("获取去除盘符的文件路径:" + FilenameUtils.getPath(strFileName));
        //获取去除盘符与最后分隔(割)符的文件路径
        System.out.println("获取去除盘符与最后分隔(割)符的文件路径:"+FilenameUtils.getPathNoEndSeparator(strFileName));
        //获取完整文件路径
        System.out.println("获取完整文件路径:"+FilenameUtils.getFullPath(strFileName));
        //获取去最后分隔(割)符的完整文件路径
        System.out.println("获取去最后分隔(割)符的完整文件路径"+FilenameUtils.getFullPathNoEndSeparator(strFileName));
        //获取去除目录的文件名
        System.out.println("获取去除目录的文件名:"+FilenameUtils.getName(strFileName));
        //获取去除目录与后缀名的文件名
        System.out.println("获取去除目录与后缀名的文件名:"+FilenameUtils.getBaseName(strFileName));
        //获取文件后缀名
        System.out.println("获取文件后缀名:"+FilenameUtils.getExtension(strFileName));
        //判定文件后缀名是否为指定后缀名类型,也可以是多个后缀名类型
        System.out.println("判定文件("+strFileName+")后缀名是否为指定后缀名(txt)类型:"+FilenameUtils.isExtension(strFileName,"txt"));
        System.out.println("判定文件("+strFileName+")后缀名是否为指定后缀名(txt/ini)类型:"+FilenameUtils.isExtension(strFileName,"txt","ini"));
        //获取文件后缀名之前的最大下标索引值(从0开始)
        System.out.println("获取文件后缀名之前的最大下标索引值(从0开始):"+FilenameUtils.indexOfExtension(strFileName));
        //获取文件最后分隔(割)符的下标索引值(从0开始)
        System.out.println("获取文件最后分隔(割)符的下标索引值(从0开始):"+FilenameUtils.indexOfLastSeparator(strFileName));
    }
}
  • 21.4.2、运行结果(Run Result)

其运行结果,如以下信息所示

指定文件名:E:\ReadWriteFile\FilenameUtils\FilenameUtils.txt
获取文件路径中的盘符:E:\
获取文件路径中的盘符长度:3
获取去除盘符的文件路径:ReadWriteFile\FilenameUtils\
获取去除盘符与最后分隔()符的文件路径:ReadWriteFile\FilenameUtils
获取完整文件路径:E:\ReadWriteFile\FilenameUtils\
获取去最后分隔()符的完整文件路径E:\ReadWriteFile\FilenameUtils
获取去除目录的文件名:FilenameUtils.txt
获取去除目录与后缀名的文件名:FilenameUtils
获取文件后缀名:txt
判定文件(E:\ReadWriteFile\FilenameUtils\FilenameUtils.txt)后缀名是否为指定后缀名(txt)类型:true
判定文件(E:\ReadWriteFile\FilenameUtils\FilenameUtils.txt)后缀名是否为指定后缀名(txt/ini)类型:true
获取文件后缀名之前的最大下标索引值(0开始):44
获取文件最后分隔()符的下标索引值(0开始):30

参考资料(Reference Data):

JavaBean

学习网站地址(即"学习网址",Learning Website Address):Java的I/O流

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值