Role of IO stream: persistent to disk
Use of File class
Basic concepts of File class
- Files and folders are represented by the File class.
- File class is a memory level object. The file object created in memory does not necessarily have a real file or folder, but the real file or folder on disk must create a corresponding file object to operate.
- The File file can be added, deleted, modified and queried, but the contents of the File itself cannot be accessed, and the input / output stream needs to be used for access.
- The File object is generally passed in as a constructor parameter of the stream object. For example, FileInputStream fileInputStream = new FileInputStream(new File("hello.tex");
File object creation
Note: if there are no folders and files on the disk, create folders and files separately.
constructor
Separator
Example summary
public class FileTest { /** * String parameter meaning of file creation * @throws FileNotFoundException */ @Test public void test1() throws FileNotFoundException { //In windows environment, \ \ is used as the folder separator. The reason why \ \ is used is because \ means escape character. All \ \ means no escape File fileA1 = new File("F:\\newwork\\roy-practice-metaverse\\hello-io.txt"); //In windows environment, it can also be expressed with / like in linux environment File fileA2 = new File("F:/newwork/roy-practice-metaverse/hello-io.txt"); //Java provides a File.pathSeparator to splice path separators for reading path separators of different systems File fileA3 = new File("F:" + File.pathSeparator + "newwork" + File.pathSeparator + "roy-practice-metaverse" + File.pathSeparator + "hello-io.txt"); //It is equivalent to hello-io.txt under the current module module. If it is the main method, it is hello-io.txt under the current project File fileR = new File("hello-io.txt"); } /** * Three constructors for file creation * @throws FileNotFoundException */ @Test public void test2() throws FileNotFoundException { //Constructor 1: File(String pathname) File file1 = new File("F:/newwork/roy-practice-metaverse/hello-io.txt"); //Constructor 2: File(String parent, String child) //child can be a file or folder name File file2 = new File("F:/newwork","roy-practice-metaverse"); //Constructor 3: File(File parent, String child) //child can be a file or folder name File file3 = new File(file2,"hello-io.txt"); } }
Common methods of File class
Query method
Note: the operation of the view method in the File class will not report an error because the File or folder does not exist, because it is also a memory level operation and does not involve disk files.
Example summary
/** * File Common methods of class * @throws FileNotFoundException */ @Test public void test3() throws FileNotFoundException { File file1 = new File("hi-io.txt");//File existence System.out.println(file1.getAbsolutePath()); System.out.println(file1.getPath()); System.out.println(file1.getName()); System.out.println(file1.getParent()); System.out.println(file1.length());//Default 0 System.out.println(file1.lastModified());//Default 0 System.out.println("------------------------------------"); File file2 = new File("F:/newwork/roy-practice-metaverse/hello-io.txt"); System.out.println(file2.getAbsolutePath()); //The return value of this path is the parameter passed in when we create the file object. If the parameter is an absolute path, it returns an absolute path, otherwise it is a relative path name System.out.println(file2.getPath()); System.out.println(file2.getName()); System.out.println(file2.getParent()); System.out.println(file2.length()); System.out.println(file2.lastModified()); } /** * F:\newwork\roy-practice-metaverse\hi-io.txt * hi-io.txt * hi-io.txt * null * 0 * 0 * ------------------------------------ * F:\newwork\roy-practice-metaverse\hello-io.txt * F:\newwork\roy-practice-metaverse\hello-io.txt * hello-io.txt * F:\newwork\roy-practice-metaverse * 0 * 0 */ /** * File Class - folder method * @throws FileNotFoundException */ @Test public void test4() throws FileNotFoundException { //When traversing a folder, the folder must exist, otherwise NPE File file1 = new File("F:/newwork/roy-practice-metaverse"); String[] list = file1.list(); for (String name : list) { System.out.println(name); } File[] files = file1.listFiles(); for (File file : files) { System.out.println(file); } //To move or rename a file successfully, you need to have from on the disk, but not to File from = new File("hello-io.txt"); File to = new File("new-io.txt"); boolean success = from.renameTo(to); System.out.println(success); } /** * .idea * hello-io.txt * pom.xml * src * target * F:\newwork\roy-practice-metaverse\.idea * F:\newwork\roy-practice-metaverse\hello-io.txt * F:\newwork\roy-practice-metaverse\pom.xml * F:\newwork\roy-practice-metaverse\src * F:\newwork\roy-practice-metaverse\target * true * * * Process finished with exit code 0 */
Judgment method of File class
Create and delete methods of File class
Example summary
/** * File Class judgment function * * @throws FileNotFoundException */ @Test public void test5() throws FileNotFoundException { File existFile = new File("new-io.txt"); System.out.println(existFile.isDirectory()); System.out.println(existFile.isFile()); System.out.println(existFile.exists()); System.out.println(existFile.canRead()); System.out.println(existFile.canWrite()); System.out.println(existFile.isHidden()); System.out.println("------------------------"); File notExistFile = new File("notExist-new-io.txt"); //When the file does not exist, the result is neither a folder nor a file. If necessary, you can judge whether it exists first System.out.println(notExistFile.isDirectory()); System.out.println(notExistFile.isFile()); System.out.println(notExistFile.exists()); System.out.println(notExistFile.canRead()); System.out.println(notExistFile.canWrite()); System.out.println(notExistFile.isHidden()); } /** * false * true * true * true * true * false * ------------------------ * false * false * false * false * false * false */ /** * File Class to create or delete files / folders * * @throws FileNotFoundException */ @Test public void test6() throws IOException { //Create delete file File file = new File("create-file.txt"); if (!file.exists()) { boolean flag = file.createNewFile(); if (flag) { System.out.println("File created successfully"); } } else { boolean delete = file.delete(); if (delete) { System.out.println("File deleted successfully"); } } //Create delete folder File file2 = new File("create-dir"); if (!file2.exists()) { boolean flag = file2.mkdir(); if (flag) { System.out.println("Folder created successfully"); } } else { boolean delete = file2.delete(); if (delete) { System.out.println("Folder deleted successfully"); } } //Create or delete multi-level folders File file3 = new File("create-dir1/sub-dir1"); if (!file3.exists()) { //mkdirs can create folders recursively. mkdir can only create one level folders. If there are multiple levels, the creation is unsuccessful boolean flag = file3.mkdirs(); if (flag) { System.out.println("Folder created successfully"); } } else { boolean delete = file3.delete(); if (delete) { System.out.println("Folder deleted successfully"); } } //To delete a multi-level folder, you can only delete the files or folders of the leaf node, not cascade deletion //To delete successfully, the deleted folder cannot have subfolders or files. If it is a file, the file must exist. // File file4 = new File("create-dir1"); // System.out.println(file4.delete());//false }
IO stream principle and stream classification
Basic concepts
-
I/O refers to Input/Output stream, which is used to process data transmission between devices.
-
The division of input and output streams is a relative concept. We choose whether the input and output streams belong to input or output from the perspective of program or memory.
-
We should look at the stream from the perspective of memory. When we read the stream from memory, we should find the input stream. When we read the stream from memory to disk or other network terminals, it is called the output stream.
Four steps for IO stream template
- File class object creation
- Creation of input and output streams
- Read / write data operation
- Close stream resource
Classification of IO streams
- Data unit
- flow to
- role
IO stream system
Node flow and processing flow
Basic concepts
Flow selection
- For text files (. TXT. Java. C...), use character stream processing.
- For non text files (. Doc. Ppt. Jpg. Avi...), (can only) use byte stream processing.
Note: the character stream operation shall be used when the text file is displayed after reading the input stream (i.e. when reading at the memory level) to avoid random code. Of course, if you just read data and write it to a file, you can use it. Even if the non text file is not read at the memory level and written directly to the hard disk, it cannot be processed with character stream, otherwise the file will fail to open.
Example summary
Character stream
public class FileReaderWriterTest { /** * Read the file data through the character input stream and print it to the console */ @Test public void test1() { //Note that when writing code at the beginning, you can throw exceptions first, and then try catch for specific processing when sorting out later //1. Instantiate the file object to operate on FileReader fr = null; try { //If the read file does not exist, an exception will be reported that the file is not found File file = new File("new-io.txt"); //2. Create a concrete flow fr = new FileReader(file); //3. Read in / write out of data //Reading the next byte of data from the input stream does not return - 1 int data; while ((data = fr.read()) != -1) { //Force to character System.out.print((char) data); } } catch (IOException e) { e.printStackTrace(); } finally { //When closing the stream, first judge whether the character input stream is not empty if (fr != null) { //Close flow try { fr.close(); } catch (IOException e) { e.printStackTrace(); } } } } /** * Read the file data through the character input stream and print it to the console - add slow charging */ @Test public void test2() { //Note that when writing code at the beginning, you can throw exceptions first, and then try catch for specific processing when sorting out later //1. Instantiate the file object to operate on FileReader fr = null; try { //If the read file does not exist, an exception will be reported that the file is not found File file = new File("new-io.txt"); //2. Create a concrete flow fr = new FileReader(file); //3. Read in / write out of data //Reading the next byte of data from the input stream does not return - 1 int len; char[] cbuff = new char[1024]; //Reading more than one at a time can provide efficiency. len is the number read into the cbuff array each time. If not, it returns - 1 while ((len = fr.read(cbuff)) != -1) { //Note that the length is len, not the length of the array cbuff //Receiving method 1: System.out.print(new String(cbuff, 0, len)); //Receiving method 2: /*for (int i = 0; i < len; i++) { System.out.print(cbuff[i]); }*/ } } catch (IOException e) { e.printStackTrace(); } finally { //When closing the stream, first judge whether the character input stream is not empty if (fr != null) { //Close flow try { fr.close(); } catch (IOException e) { e.printStackTrace(); } } } } /** * Write files from memory to hard disk through character output stream * The file for the output operation may not exist and will be created automatically when it does not exist. * When creating a character output stream, there will be an append parameter. The default is false, which means that if the file exists, it will be overwritten * If the append parameter = true is set, it means that if the file exists, the data will be appended to the end of the file. */ @Test public void test3() { FileWriter fw = null; try { //1. Instantiate the file object to operate on File file = new File("out-io.txt"); //2. Create a concrete flow //Fileoutputstream (file, Boolean append) append = false indicates overwrite, and true indicates append at the end of the file fw = new FileWriter(file); //3. Write out of data //Write a string directly, \ n representing a newline character fw.write("everybody wants to rule the world!\n"); //You can also write character arrays fw.write("No, I'm just a good citizen. Just live!".toCharArray()); } catch (IOException e) { e.printStackTrace(); } finally { if (fw != null) { //4. Close stream resource try { fw.close(); } catch (IOException e) { e.printStackTrace(); } } } } /** * Read files from hard disk to new files (copy) - character stream version */ @Test public void test5() { FileReader fr = null; FileWriter fw = null; try { //1. Instantiate the read in / write out file object to operate on File srcFile = new File("new-io.txt"); File destFile = new File("new-io-copy.txt"); //2. Create input and output streams fr = new FileReader(srcFile); fw = new FileWriter(destFile); //3. Read in and write out of data int len; char[] buff = new char[1024]; while ((len = fr.read(buff)) != -1) { //Note how many words to read and how many lengths to write len fw.write(buff, 0, len); } } catch (IOException e) { e.printStackTrace(); } finally { //4. Close stream resource if (fw != null) { try { fw.close(); } catch (IOException e) { e.printStackTrace(); } } if (fr != null) { try { fr.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
Byte stream
public class FileInOutPutStreamTest { /** * Read files from hard disk to new files (copy) - byte stream version */ @Test public void test() { copyFile("It's a minister.jpg", "It's a minister-copy.jpg"); } public void copyFile(String srcPath, String destPath) { FileInputStream fis = null; FileOutputStream fos = null; try { //1. Instantiate the read in / write out file object to operate on File srcFile = new File(srcPath); File destFile = new File(destPath); // File srcFile = new File("new-io.txt"); // File destFile = new File("new-io-copy.txt"); //2. Create input and output streams fis = new FileInputStream(srcFile); fos = new FileOutputStream(destFile); //3. Read in and write out of data int len; byte[] buff = new byte[1024]; while ((len = fis.read(buff)) != -1) { //Note how many words to read and how many lengths to write len fos.write(buff, 0, len); } } catch (IOException e) { e.printStackTrace(); } finally { //4. Close stream resource if (fos != null) { try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } if (fis != null) { try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
Buffer stream -- a kind of processing stream
A processing stream is a stream nested on the basis of an existing stream.
Function: improve the reading and writing speed of the stream.
Reason: a default 8K buffer is provided internally. Buffer size we can specify the size in the constructor.
Example summary
public class BufferedTest { /** * Replication using cache streams */ @Test public void test1() { //971M takes 1444ms. After the test, the larger the specified buff buffer, the better in theory, because the sequential write speed is faster long start = System.currentTimeMillis(); BufferedInputStream bis = null; BufferedOutputStream bos = null; try { //1. Instantiate the read in / write out file object to operate on File srcFile = new File("E:/mv/[Movie paradise www.dygod.com]Beautiful girl ghost 3: Tao BD Chinese characters in Mandarin.rmvb"); File destFile = new File("nxq.rmvb"); //2.1. Create input stream and output stream FileInputStream fis = new FileInputStream(srcFile); FileOutputStream fos = new FileOutputStream(destFile); //2.1. Create cache stream bis = new BufferedInputStream(fis); bos = new BufferedOutputStream(fos, 8192);//1444ms // bos = new BufferedOutputStream(fos, 8192 / 2);//1952ms // bos = new BufferedOutputStream(fos, 8192 * 2);//1202ms // bos = new BufferedOutputStream(fos, 8192 * 8);//1101ms //3. Read in and write out of data byte[] buffer = new byte[1024]; int len; while ((len = bis.read(buffer)) != -1) { bos.write(buffer, 0, len); //Forced refresh of the buffer will flush the data in the buffer to the disk // bos.flush(); } long end = System.currentTimeMillis(); System.out.println(end - start); } catch (IOException e) { e.printStackTrace(); } finally { //4. The closed flow resource closing principle is to open first and then close. When the outer packaging flow is closed, the inner flow will also be closed, so there is no need to close it separately if (bis != null) { try { bis.close(); } catch (IOException e) { e.printStackTrace(); } } if (bos != null) { try { bos.close(); } catch (IOException e) { e.printStackTrace(); } } } } /** * Text copy using cached character stream */ @Test public void test2() { //971M takes 1444ms. After the test, the larger the specified buff buffer, the better in theory, because the sequential write speed is faster long start = System.currentTimeMillis(); BufferedReader br = null; BufferedWriter bw = null; try { //1. Instantiate the read in / write out file object to operate on //2.1. Create input stream and output stream //2.1. Create cache stream br = new BufferedReader(new FileReader(new File("new-io.txt"))); bw = new BufferedWriter(new FileWriter(new File("new-io-copy3.txt"))); //3. Read in and write out of data //The character stream reads and writes characters, so the character container is used //Method 1: use char array /* char[] buffer = new char[1024]; int len; while ((len = br.read(buffer)) != -1) { bw.write(buffer, 0, len); //Forced refresh of the buffer will flush the data in the buffer to the disk // bw.flush(); }*/ //Method 2: use String String data; while ((data = br.readLine()) != null) { // bw.write(data+"\n"); //If there is no escape character, it will be written together bw.write(data); bw.newLine(); } long end = System.currentTimeMillis(); System.out.println(end - start); } catch (IOException e) { e.printStackTrace(); } finally { //4. Close stream resource if (br != null) { try { br.close(); } catch (IOException e) { e.printStackTrace(); } } if (bw != null) { try { bw.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
Conversion flow
Basic concepts
-
The conversion stream belongs to the character stream, and the suffix depends on the attribution of the stream.
-
InputStreamReader converts a byte stream into a character stream and decodes it (byte, byte array -- > character, character array).
-
OutputStreamWriter converts a character stream into a byte stream and encodes it (character, character array -- > byte, byte array).
-
The encoding and decoding process requires character set processing.
character set
ASCII: because one byte is enough to represent all these letters.
GBK and UTF-8 are compatible with ASCII code table. When decoding the text originally UTF-8 into GBK, there will be no problem with the English part, but the Chinese part will be garbled.
GBK and gbk2312 represent a byte code and a character by the first character of 0; The first character is 1, which means that 2 bytes need to be read to represent one character to standardize coding, that is, the highest bit is 1 or 0 to represent two bytes or one byte.
application
Encoding and decoding.
Example summary
public class TransferIOTest { /** * Convert stream read file print */ @Test public void test1() { //1. Create byte stream object InputStreamReader isr = null; try { FileInputStream fis = new FileInputStream("new-io.txt"); //If no decoded character set is specified, the default character set is used // InputStreamReader isr = new InputStreamReader(fis); //2. Create character conversion stream isr = new InputStreamReader(fis, "UTF-8"); //3. Decode read char[] buff = new char[1024]; int len; while ((len = isr.read(buff)) != -1) { //Because we use the original UTF-8 character set encoding format of the file, there will be no decoding and garbled code during printing. System.out.println(new String(buff, 0, len)); } } catch (IOException e) { e.printStackTrace(); } finally { if (isr != null) { //4. Close stream resource try { isr.close(); } catch (IOException e) { e.printStackTrace(); } } } } /** * hello,my io * I'm going to be forced * hello,my io * I'm going to be forced * hello,my io * I'm going to be forced. I'm going to be forced. I'm going to be forced. I'm going to be forced */ /** * Convert stream read UTF-8 file and save it as GBK file */ @Test public void test2() { //1. Create byte stream object InputStreamReader isr = null; OutputStreamWriter osr = null; try { FileInputStream fis = new FileInputStream("new-io.txt"); FileOutputStream fos = new FileOutputStream("new-io-gbk.txt"); //If no decoded character set is specified, the default character set is used // InputStreamReader isr = new InputStreamReader(fis); //2. Create character conversion stream //Character set format must be specified when writing code isr = new InputStreamReader(fis, "UTF-8"); osr = new OutputStreamWriter(fos, "GBK"); //3. Decode read char[] buff = new char[1024]; int len; while ((len = isr.read(buff)) != -1) { osr.write(buff,0,len); } } catch (IOException e) { e.printStackTrace(); } finally { if (isr != null) { //4. Close stream resource try { isr.close(); } catch (IOException e) { e.printStackTrace(); } } if (osr != null) { //4. Close stream resource try { osr.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
Other streams
Standard input and output streams
Print stream
data stream
Example summary
public class OtherTest { /** * Use the standard I / O stream to read the input from the keyboard, convert it into uppercase and print it on the console * Note that idea does not support reading keyboard input using the @ Test test method, so use the main method instead * * @param args */ public static void main(String[] args) { BufferedReader br = null; try { br = new BufferedReader(new InputStreamReader(System.in)); String data = ""; while (true) { System.out.println("Please enter:"); data = br.readLine(); if ("exit".equalsIgnoreCase(data)) { System.out.println("bye!"); break; } System.out.println(data.toUpperCase()); } } catch (IOException e) { e.printStackTrace(); } finally { if (br != null) { try { br.close(); } catch (IOException e) { e.printStackTrace(); } } } } /** * Please enter: * hhhh * HHHH * Please enter: * exit * bye! */ /** * Print stream */ @Test public void test1() { PrintStream ps = null; try { //Create a printout stream and set automatic refresh. The default is false. Automatic refresh will refresh the output buffer when a line break or \ n is encountered ps = new PrintStream(new FileOutputStream(new File("test-print.txt")),true); //The print stream PrintStream/PrintWriter is used to record the standard output stream (print to the console into our file) and our log into the text System.setOut(ps); String str = "I'm here to test the print stream\n Now start the test: abcedsakjfslkdjfdfskgjdfkg\nsdfsdfsdf\n end"; System.out.println(str); } catch (FileNotFoundException e) { e.printStackTrace(); } finally { if (ps != null) { ps.close(); } } } /** * Data stream: read and write 8 basic data types and strings */ @Test public void test2() throws Exception { DataOutputStream dos = new DataOutputStream(new FileOutputStream("data.txt")); dos.writeUTF("Salary Expectation "); dos.writeInt(36000); dos.writeBoolean(true); dos.flush(); dos.close(); DataInputStream dis = new DataInputStream(new FileInputStream("data.txt")); //Pay attention to reading data in the order of writing, otherwise an error will be reported System.out.println(dis.readUTF()); System.out.println(dis.readInt()); System.out.println(dis.readBoolean()); dis.close(); } }
Object flow
Three conditions must be met for an object to be serializable
- The class corresponding to the object needs to implement the Serializable interface.
- A global constant serialVersionUID needs to be defined.
- All attributes in the object must also be serializable, such as the custom Address class, and the basic data type is serializable.
Serialization * *: convert objects in memory into binary streams. This allows the binary stream to be persisted to disk or transferred to another network node.
Deserialization: restores a binary stream to a Java object.
Role of serialVersionUID
- Identifies the version of the class for version compatibility.
- If the serialVersionUID is not defined, Java will automatically generate it according to the internal details of the class. If the instance variable of the class is modified, the automatically generated serialVersionUID will change.
- The Java serialization mechanism verifies the consistency of the version through the serialVersionUID. If the version is inconsistent, a version inconsistency exception will be reported during deserialization.
Example summary
ublic class ObjectInputOutputStreamTest { /** * Object serialization * * @throws Exception */ @Test public void test1() throws Exception { ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("object.txt")); oos.writeObject(new Person("Zhang San", 30, new Address("Forbidden City 1"))); oos.writeObject(new String("I'm Amy")); oos.flush(); oos.close(); } /** * Object deserialization * * @throws Exception */ @Test public void test2() throws Exception { ObjectInputStream ois = new ObjectInputStream(new FileInputStream("object.txt")); //You need to read in the order of the written objects, otherwise an error will be reported Person person = (Person) ois.readObject(); String str = (String) ois.readObject(); System.out.println(person); System.out.println(str); ois.close(); } /** * Person(name=Zhang San, age=30, address=Address(location = No. 1 Forbidden City)) * I'm Amy */ } /** * Three conditions must be met for object serialization: * The class corresponding to the object needs to implement the Serializable interface * A global constant serialVersionUID needs to be defined * All attributes in the object must also be serializable, such as the custom Address class, and the basic data type is serializable. */ @Data @AllArgsConstructor @NoArgsConstructor public class Person implements Serializable { private static final long serialVersionUID = -6849344724054667710L; private String name; private int age; private Address address; } @Data @AllArgsConstructor @NoArgsConstructor public class Address implements Serializable { private static final long serialVersionUID = -684934470754667710L; private String location; }
On demand access file stream -- breakpoint continuation
Example summary
public class RandomAccessFileTest { /** * Random access file - read the file and write it to a new file */ @Test public void test1() { RandomAccessFile read = null; RandomAccessFile write = null; try { //read-only read = new RandomAccessFile(new File("new-io.txt"), "r"); //Readable and writable write = new RandomAccessFile(new File("test.txt"), "rw"); byte[] buff = new byte[1024]; int len; while ((len = read.read(buff)) != -1) { write.write(buff, 0, len); } } catch (IOException e) { e.printStackTrace(); } finally { if (read != null) { try { read.close(); } catch (IOException e) { e.printStackTrace(); } } if (write != null) { try { write.close(); } catch (IOException e) { e.printStackTrace(); } } } } /** * Use RandomAccessFile to achieve data insertion effect */ @Test public void test2() throws Exception { //Readable and writable RandomAccessFile raf = new RandomAccessFile(new File("test.txt"), "rw"); //Adjust the pointer to the position marked with 3 and start with 0. raf.seek(3); //Save the data after corner mark 3, then insert it, and finally add the data at the position after corner mark 3 //Save data with byte array output stream to avoid garbled code ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buff = new byte[1024]; int len; while ((len = raf.read(buff)) != -1) { baos.write(buff, 0, len); } //Returns the pointer to the position to insert raf.seek(3); raf.write("Hahaha, I'm in".getBytes()); raf.write(baos.toString().getBytes()); raf.close(); baos.close(); } }
Use of Path, Paths and Files classes in NIO.2
The third-party common IO implements IO reading and writing
rely on
<dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.4</version> </dependency>
Example
public class CommonsIOTest { @Test public void test() throws IOException { File srcFile = new File("It's a minister.jpg"); File destFile = new File("It's a minister-copy3.jpg"); FileUtils.copyFile(srcFile, destFile); } }
reference resources
Getting started with Java video tutorial
577-617