content
3. Reading and writing of file content - data flow
5,BufferedInputStream与BufferedOutputStream
Fourth, serialization and deserialization
1. Know the documents
Let's first understand the narrow sense of the file (file). For the I/O device of persistent storage such as hard disk, when we want to save data, it is often not saved as a whole, but is saved in separate units. This independent unit is abstracted into a file. Concepts are like real documents on a desk.
In addition to the data content, the file also has some information, such as file name, file type, file size, etc., which does not exist as the data of the file. We can regard this part of the information as the meta information of the file.
Two representations of paths
How to locate one of our unique files in the file system has become the current problem to be solved, but this is not difficult for computer scientists, because from the perspective of tree structure, each node in the tree can be accessed by a Starting from the root, it is described by the path of the node that has been reached, and this description is called the absolute path of the file ( absolute path).
Disks starting with C or D are absolute paths
In addition to the description of the path from the root, we can start from any node to describe the path, and this description method is called a relative path (relative path), a path relative to the current node.
Take C:\Users\12556\Desktop\JavaEE\4.JavaEE elementary as an example
Relative path: 4. JavaEE initial stage as an example
2. Manipulating files in Java
1. Method
Modifiers and return value types | method signature | illustrate |
String | getParent() | Returns the parent directory file path of the File object |
String | getName() | Returns the plain filename of the FILE object |
String | getPath() | Returns the file path of the File object |
boolean | exists() | Determine whether the file described by the File object actually exists |
boolean | isDirectory() | Determine whether the file represented by the File object is a directory |
boolean | isFile() | Determine whether the file represented by the File object is a normal file |
boolean | delete() | According to the File object, delete the file. Returns true after successful deletion |
boolean | deleteOnExit() | According to the File object, the marked file will be deleted, and the deletion will not be performed until the end of the JVM operation. |
String[] | list() | Returns all file names in the directory represented by the File object |
File[] | listFiles() | Returns all files in the directory represented by the File object, represented by the File object |
boolean | mkdir() | Create the directory represented by the File object |
boolean | mkdirs() | Creates the directory represented by the File object, and intermediate directories if necessary |
boolean | canRead() | Determine if the user has read permission on the file |
boolean | canWrite () | Determine if the user has writable permissions on the file |
Example 1
public static void main(String[] args) {
File file = new File("D:/123.txt");
System.out.println(file.exists());
System.out.println(file.getParentFile());
System.out.println(file.getName());
System.out.println(file.getPath());
}
Example 2
public static void main(String[] args) throws IOException {
File file = new File("D:/123.txt");
System.out.println(file.exists());
System.out.println(file.isDirectory());
System.out.println(file.isFile());
System.out.println(file.createNewFile());
System.out.println(file.exists());
System.out.println(file.isDirectory());
System.out.println(file.isFile());
System.out.println(file.createNewFile());
}
Example 3
Recursively list all files in a directory
public static void main(String[] args) {
File file = new File("D:/练习");
listAllFile(file);
}
private static void listAllFile(File file) {
if (file.isDirectory()){
File[] files = file.listFiles();
for (File file1 : files){
listAllFile(file1);
}
}else {
System.out.println(file);
}
}
Example 4
public static void main(String[] args) throws IOException {
File dir = new File("D:/some-dir"); // 要求该目录不存在,才能看到相同的现象
System.out.println(dir.isDirectory());
System.out.println(dir.isFile());
System.out.println(dir.mkdir());
System.out.println(dir.isDirectory());
System.out.println(dir.isFile());
}
3. Reading and writing of file content - data flow
1. Overview of InputStream
InputStream is just an abstract class, and a concrete implementation class is required to use it. There are many implementation classes for InputStream. Basically, it can be considered that different input devices can correspond to an InputStream class. Now we only care about reading from files, so we use FileInputStream.
InputStream: input, read data from the input device into memory
2, OutputStream overview
OutputStream is also just an abstract class, and a concrete implementation class is required to use it. We still only care about writing to the file, so use FileOutputStream
OutputStream: output, write the data in memory to the output device
3, stream object operation
step:
1. Open the file (construction method)
2, read: read data from the file into memory
3, write: write data from memory to file
4, close: close the file (corresponding to open)
public static void main(String[] args) throws IOException {
copyFile("D:/test/12.jpg","D:/test/123.jpg");
}
private static void copyFile(String srcPath, String destPath) throws IOException {
//打开文件,才能读写
FileInputStream fileInputStream = new FileInputStream(srcPath);
FileOutputStream fileOutputStream = new FileOutputStream(destPath);
//1,读取scrPath对应的内容
byte[] buffer = new byte[1024];
int len = -1;
//读到的len是-1说明读取结束,循环结束了
while ((len = fileInputStream.read(buffer)) != -1){
//读取成功,把读的内容写入另外一个文件
fileOutputStream.write(buffer,0,len);
}
fileInputStream.close();
fileOutputStream.close();
}
When a file is opened in a process, certain records will be made in the PCB
Each time a file is opened in the code, the essence is to create a new item in the descriptor table of the file. Each time a file is closed in the code, the essence is to delete the corresponding item in the file descriptor table.
The file descriptor is an attribute in the PCB, and a process may correspond to multiple PCBs (each PCB corresponds to a thread)
The same file descriptor table is shared among several PCBs of the same process
4. Code optimization
private static void copyFile2() throws IOException {
//创建示例
FileInputStream fileInputStream = null;
FileOutputStream fileOutputStream = null;
try {
fileInputStream = new FileInputStream("d:/test_dir/rose.jpg");
fileOutputStream = new FileOutputStream("d:/test_dir/rose2.jpg");
byte[] buffer = new byte[1024];
int len = -1;
while ((len = fileInputStream.read(buffer)) != -1) {
fileOutputStream.write(buffer, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fileInputStream != null) {
fileInputStream.close();
}
if (fileOutputStream != null) {
fileOutputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
private static void copyFile3() {
//当代码写成这样的时候,就不需要显示调用close了
//try语句会在代码执行完毕后自动调用close方法
try {FileInputStream fileInputStream = new FileInputStream("d:/test_dir/rose.jpg");
FileOutputStream fileOutputStream = new FileOutputStream("d:/test_dir/rose2.jpg");
byte[] buffer = new byte[1024];
int len = -1;
while ((len = fileInputStream.read(buffer)) != -1){
fileOutputStream.write(buffer,0,len);
}
}catch (IOException e){
e.printStackTrace();
}
}
5,BufferedInputStream与BufferedOutputStream
The built-in buffer is essentially a piece of memory space, and the reason for the existence of the buffer is to improve efficiency.
Program access to memory is much faster than program access to disk. IO involves disk access. The more IO, the lower the overall program efficiency.
When reading and writing a disk, reading one byte at a time, reading a hundred times is definitely less efficient than reading 100 bytes each time, and reading once.
public static void main(String[] args) throws IOException {
copyFile();
}
private static void copyFile() throws IOException {
FileInputStream fileInputStream = new FileInputStream("路径");
FileOutputStream fileOutputStream = new FileOutputStream("路径");
BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
//用户指定的缓冲区
byte[] buffer = new byte[1024];
int len = -1;
while ((len = bufferedInputStream.read(buffer)) != -1) {
bufferedOutputStream.write(buffer,0,len);
}
bufferedInputStream.close();
bufferedOutputStream.close();
}
optimize code
private static void copyFile2() {
try (BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream("d:/test_dir/rose.jpg"));
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream("d:/test_dir/rose2.jpg"))) {
int len = -1;
byte[] buffer = new byte[1024];
while ((len = bufferedInputStream.read(buffer)) != -1) {
bufferedOutputStream.write(buffer, 0, len);
}
} catch (IOException e) {
e.printStackTrace();
}
}
6. Character stream
The usage of character stream objects is very similar to that of byte stream objects, except that some details are different
The read and write operations of the byte stream are in bytes, and the buffer is a byte[]
The read and write operations of the character stream take char as the unit, and the buffer area is a char[]
private static void copyFile() throws IOException {
try{
FileReader fileReader = new FileReader("路径");
FileWriter fileWriter = new FileWriter("路径");
char[] buffer = new char[1024];
int len = -1;
while ((len = fileReader.read(buffer)) != -1) {
fileWriter.write(buffer,0,len);
}
} catch (IOException e){
e.printStackTrace();
}
}
optimize code
public static void main(String[] args) throws IOException {
copyFile1();
}
private static void copyFile1() throws IOException {
//带缓冲区的字符流有一种特殊的用法,按行读取
try{BufferedReader bufferedReader = new BufferedReader(new FileReader("路径"));
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("路径"));
String line = "";
while ((line = bufferedReader.readLine()) != null){
System.out.println("line:" + line);
bufferedWriter.write(line + "\n");
}
}catch (IOException e){
e.printStackTrace();
}
}
Fourth, serialization and deserialization
Serialization : Turn a structured data (object) into a binary bit stream (this bit stream can be saved to a file, or transmitted over the network)
Deserialization : restore the binary bit stream back to the original object
Purpose:
Just to allow objects to be transferred over the network / to be saved in a file
The process of serialization and deserialization must ensure "information loss"
Java has its own serialization method, which is done with the help of stream objects.
static class Student implements Serializable{
public String name;
public int age;
public int score;
}
public static void main(String[] args) throws IOException {
Student s = new Student();
s.name = "张三";
s.age = 20;
s.score = 100;
seeializeStudet(s);
}
private static void seeializeStudet(Student s) throws IOException {
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("D:/student.txt"));
objectOutputStream.writeObject(s);
objectOutputStream.close();
}
static class Student implements Serializable{
public String name;
public int age;
public int score;
}
public static void main(String[] args) throws IOException, ClassNotFoundException {
Student s = deserializeStudent();
System.out.println(s.name);
System.out.println(s.age);
System.out.println(s.score);
}
private static Student deserializeStudent() throws IOException, ClassNotFoundException {
ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("D:/student.txt"));
Student s = (Student) objectInputStream.readObject();
return s;
}