Introduction: This article mainly introduces RandomAccessFile, which is the most versatile file content access class in the IO stream system. It can not only read the file content, but also output data to the file. Summarize this article, hoping to be helpful or enlightening to students engaged in related work
1, Background
For file processing, when the network environment is bad and the upload fails, the failed Part can be retried independently without re uploading other parts; After the pause, you can continue to upload from the location of the last uploaded Part. Or when the local file to be uploaded to the OSS is large, you can upload multiple parts in parallel to speed up the upload; Or when some files are relatively large, we need to cut the large files and upload them in batches before merging.
2, RandomAccessFile introduction
RandomAccessFile can not only read the contents of the file, but also output data to the file. At the same time, RandomAccessFile supports "random access", and the program can jump directly to any place of the file to read and write data.
Since RandomAccessFile can freely access any location of the file, if you need to access part of the file instead of reading the file from beginning to end, RandomAccessFile will be a better choice.
Different from output streams such as OutputStream and Writer, RandomAccessFile allows free definition of file record pointers. RandomAccessFile can not output from the beginning. Therefore, RandomAccessFile can add content to the existing file. If the program needs to append content to an existing file, RandomAccessFile should be used.

As can be seen from the class diagram, RandomAccessFile implements DataInput and DataOutput data writing and data writing functions. The following is the specific implementation function declaration.

♪ constructor of RandomAccessFile
RandomAccessFile class has two constructors. In fact, the two constructors are basically the same, but the form of the specified file is different.
A file name needs to be specified using the String parameter

The other uses the File parameter to specify the File itself.

In addition, when creating a RandomAccessFile object, you also need to specify a mode parameter, which specifies the access mode of RandomAccessFile. There are four modes in total.
-
**"r": * * open in read-only mode. Calling any write method of the result object will cause an IOException to be thrown.
-
"rw": open for reading and writing.
-
"rws": open for reading and writing. Compared with "rw", rws also requires that each update of "file content" or "metadata" be synchronously written to the underlying storage device.
-
"rwd": open for reading and writing. Compared with "rw", rwd also requires that each update of "file content" be synchronously written to the basic storage device.
⒌ important method of RandomAccessFile
RandomAccessFile class contains a record pointer to identify the current read / write location. When the program creates a new RandomAccessFile object, The file record pointer of this object is located at the file header (i.e. 0). When n bytes are read / written, the file record pointer will move backward by N bytes. In addition, RandomAccessFile can move the record pointer freely, that is, forward or backward. RandomAccessFile contains the following two methods to operate the file record pointer
-
long getFilePointer(); Returns the current position of the file record pointer
-
void seek(long pos); Position the file record pointer to the POS position
3, Use of RandomAccessFile
♪ read the file at the specified location
public static void main(String[] args) { RandomAccessFile accessFile = null; try { File file = new File(filePath); accessFile = new RandomAccessFile(file, "r"); // obtain RandomAccessFile The position of the object file pointer. The initial position is 0 log.debug("Input:{}", accessFile.getFilePointer()); // Move the position of the file record pointer accessFile.seek(1000); byte[] b = new byte[1024]; int hasRead = 0; //Loop read file while ((hasRead = accessFile.read(b)) > 0) { //Output file read content System.out.print(new String(b, 0, hasRead)); } } catch (IOException e) { e.printStackTrace(); } finally { accessFile.close(); } }
There are two key codes in the above program. One is to create the RandomAccessFile object, which opens the file in read-only mode, which means that the RandomAccessFile file can only read the file content and cannot write. In the second place, the seek (1000) method is called, which refers to positioning the record pointer of the file to 1000 bytes. That is, the program will read the data from 1000 bytes. The reading method of other parts of the code is no different from that of other input streams.
Η add content to the file

public static void main(String[] args) { RandomAccessFile accessFile = null; File file = null; try { file = new File(filePath); // Open a read-write RandomAccessFile object accessFile = new RandomAccessFile(file, "rw"); //Move the record pointer to the end of the file accessFile.seek(accessFile.length()); //Append to end of file accessFile.writeChars("This is an addition.."); } catch (IOException e) { e.printStackTrace(); } finally { accessFile.close(); } }
The above code first creates a RandomAccessFile object by reading and writing, then moves the file record pointer to the end, and then uses RandomAccessFile to write content to the file. The method is the same as that of other output examples OutputStream. Each time you run the above program, you can find text Txt file.
Η insert content to the specified location of the file

Note: RandomAccessFile cannot insert content into the specified location of the file. If you directly move the file record pointer to a middle location and start output, the newly output content will overwrite the original content of the file. If you need to insert content into the specified location, the program needs to write the content behind the insertion point into the cache first, and then write the data to be inserted into the file, Then append the contents of the cache to the back of the file.
/** * Inserts content into the specified location of the file * * @param filePath Source file path * @param pos Insert file to specified location * @param writeContent Write content */ private static void readFileThenWrite(String filePath, long pos, String writeContent) throws IOException { RandomAccessFile raf = null; File tempFile = File.createTempFile("tmp", null); tempFile.deleteOnExit(); try { // Open a read-write RandomAccessFile object raf = new RandomAccessFile(new File(filePath), "rw"); // Create a temporary file to save the data after the insertion point FileOutputStream fileOutputStream = new FileOutputStream(tempFile); FileInputStream fileInputStream = new FileInputStream(tempFile); // Position the file record pointer to pos position raf.seek(pos); raf.seek(pos); //------------Read the contents after the insertion point into a temporary file and save it------------ byte[] bytes = new byte[64]; //Used to save the byte data actually read int hasRead = 0; //Use the loop to read the data after the insertion point while ((hasRead = raf.read(bytes)) != -1) { //Writes the read contents to a temporary file fileOutputStream.write(bytes, 0, hasRead); } //------------For inserting content ------------ //Reposition the file record pointer to pos position raf.seek(pos); //Append content to be inserted raf.write(writeContent.getBytes()); //Append contents in temporary file while ((hasRead = fileInputStream.read(bytes)) != -1) { //Writes the read contents to a temporary file raf.write(bytes, 0, hasRead); } } catch (Exception e) { throw e; } }
The above program creates a temporary File using the createTempFile method of the File class (the File will be deleted after the JVM exits), which is used to save the contents after the insertion point. The program first reads the contents after the insertion point into the temporary File, then relocates to the insertion point, adds the contents to be inserted to the back of the File, and finally adds the contents of the temporary File to the back of the File. Through this process, you can specify the location to the specified File Insert content. Each time you run the above program, you will see one more line in the File.
4, Summary
By reading the RandomAccessFile source code, you will find that although there are many methods, it has one biggest limitation, that is, it can only read and write files, not other IO nodes.
However, RandomAccessFile can freely access any location of the file, so if you need to access part of the file instead of reading the file from beginning to end, an important use scenario of RandomAccessFile is multi-threaded download and breakpoint continuation in network request.
This article mainly introduces RandomAccessFile, which is the most functional file content access class in the IO stream system. It can not only read the file content, but also output data to the file. The summary of this article is mainly to undertake the previous article< https://mp.weixin.qq.com/s/yxBG4t-GVRYYUIMXUcOwKw >The topic is a supplement to the processing of file fragmentation.
