RandomAccessFile
RandomAccessFile is used to access files that save data records. You can use the seek ( ) method to access records and read and write. The size of these records does not have to be the same; however, their size and position must be known. However, this class is limited to operating files.
RandomAccessFile does not belong to the InputStream and OutputStream classes. In fact, in addition to implementing the DataInput and DataOutput interfaces (DataInputStream and DataOutputStream also implement these two interfaces), it has nothing to do with these two classes, and does not even use any functions that already exist in the InputStream and OutputStream classes; it is a completely independent class, and all methods (mostly belong to itself only) are written from scratch. This may be because RandomAccessFile can move back and forth in the file, so its behavior is somewhat fundamentally different from other I/O classes. In short, it is a separate class that directly inherits Object.
Basically, the working method of RandomAccessFile is to combine DataInputStream and DataOutputStream, and add some of its own methods, such as getFilePointer( ) for positioning, seek( ) for moving in the file, and determine the length( ) for file size, and skipBytes() for skip by how many bytes it skips. In addition, its constructor also has a parameter that indicates whether to open the file in read-only mode ("r") or read-write mode ("rw") (exactly the same as the fopen( ) of C). It does not support writing only files.
Only RandomAccessFile has a seek search method, and this method is only applicable to files. BufferedInputStream has a mark( ) method, which you can use to set the mark (save the result in an internal variable), and then call reset( ) to return to this position, but its function is too weak and not very practical.
Most of the functions of RandomAccessFile, but not all, have been replaced by the "memory-mapped files" of JDK 1.4. You should consider whether to use "memory-mapped files" instead of RandomAccessFile.
import java.io.IOException; import java.io.RandomAccessFile; public class TestRandomAccessFile { public static void main(String[] args) throws IOException { RandomAccessFile rf = new RandomAccessFile("rtest.dat", "rw"); for (int i = 0; i < 10; i++) { //Write basic type double data rf.writeDouble(i * 1.414); } rf.close(); rf = new RandomAccessFile("rtest.dat", "rw"); //Turn directly move the file pointer to the 5th double data rf.seek(5 * 8); //Overwrite the 6th double data rf.writeDouble(47.0001); rf.close(); rf = new RandomAccessFile("rtest.dat", "r"); for (int i = 0; i < 10; i++) { System.out.println("Value " + i + ": " + rf.readDouble()); } rf.close(); } }Memory mapped file
Memory mapped files allow you to create and modify files that are too large to put into memory. With the memory mapped file, you can think that the file has been read into memory and access it as a very large array. This solution can greatly simplify the code of modifying files.
fileChannel.map(FileChannel.MapMode mode, long position, long size) maps the file area of this channel directly into memory. Note that you must indicate where it maps from and how large the range of the map is; that is, it can also map a small fragment of a large file.
MappedByteBuffer is a subclass of ByteBuffer, so it has all the methods of ByteBuffer, but a new force() is added to force refresh the content of the buffer to the storage device, load() loads the data in the storage device into memory, and isLoaded() in the memory location whether the data in the memory is synchronized with the storage settings. Here we only briefly demonstrate the put() and get() methods. In addition, you can also use methods such as asCharBuffer( ) to obtain the buffered view of the corresponding basic type data, which can easily read and write basic type data.
import java.io.RandomAccessFile; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; public class LargeMappedFiles { static int length = 0x8000000; // 128 Mb public static void main(String[] args) throws Exception { // In order to open the file in a readable and writable way, RandomAccessFile is used here to create the file. FileChannel fc = new RandomAccessFile("test.dat", "rw").getChannel(); //Note that the readable and writable file channel must be based on the readable and writable file stream itself. MappedByteBuffer out = fc.map(FileChannel.MapMode.READ_WRITE, 0, length); //Write 128M content for (int i = 0; i < length; i++) { out.put((byte) 'x'); } System.out.println("Finished writing"); //Read 6 bytes of the middle of the file for (int i = length / 2; i < length / 2 + 6; i++) { System.out.print((char) out.get(i)); } fc.close(); } }Although it seems that FileOutputStream is used to write mapping, all outputs in the mapping file must use RandomAccessFile, but if you only need to read FileInputStream, you must use Random Access File when writing mapping files. Maybe the reason for reading when writing.
The program creates a 128Mb file. If you read the memory at one time, it may cause memory overflow, but access here seems to be just a moment, because only a small part of it is actually transferred into the memory, and the rest is placed on the swap file. This way you can easily modify super-large files (up to 2 GB). Note that Java calls the operating system's "file mapping mechanism" to improve performance.
Application of RandomAccessFile class:
/* * Program function: Demonstrate the operations of the RandomAccessFile class and implement a file copy operation. */ package com.lwj.demo; import java.io.*; public class RandomAccessFileDemo { public static void main(String[] args) throws Exception { RandomAccessFile file = new RandomAccessFile("file", "rw"); // The following writes data to the file file.writeInt(20);// It occupies 4 bytes file.writeDouble(8.236598);// It occupies 8 bytes file.writeUTF("This is a UTF string");// This length is written in the first two bytes of the current file pointer. File.writeBoolean(true);// occupies 1 byte file.writeShort(395);// occupies 2 bytes file.writeLong(2325451l);// occupies 8 bytes file.writeUTF("Another UTF string"); file.writeFloat(35.5f);// occupies 4 bytes file.writeChar('a');// occupies 2 bytes file.seek(0);// Set the file pointer position to the start of the file// The following is to read data from the file file. Pay attention to the location of the file pointer System.out.println("――――――――――――――――――――; System.out.println(file.readInt()); System.out.println(file.readDouble()); System.out.println(file.readUTF()); file.skipBytes(3);// Skip the file pointer by 3 bytes, and in this case a boolean value and short value are skipped. System.out.println(file.readLong()); file.skipBytes(file.readShort()); // Skip the bytes occupied by "a UTF string" in the file. Note that the readShort() method will move the file pointer, so you don't need to add 2. System.out.println(file.readFloat()); //The following demonstrates file copy operation System.out.println("――――――――――――――――――; file.seek(0); RandomAccessFile fileCopy=new RandomAccessFile("fileCopy","rw"); int len=(int)file.length();//Get file length (byte number) byte[] b=new byte[len]; file.readFully(b); fileCopy.write(b); System.out.println("Copy completed!"); } } RandomAccessFile Insertion Write Example:
/** * * @param skip How many bytes to skip to insert data* @param str String to insert* @param fileName File path*/ public static void beiju(long skip, String str, String fileName){ try { RandomAccessFile raf = new RandomAccessFile(fileName,"rw"); if(skip < 0 || skip > raf.length()){ System.out.println("Skip number of skipped bytes is invalid"); return; } byte[] b = str.getBytes(); raf.setLength(raf.length() + b.length); for(long i = raf.length() - 1; i > b.length + skip - 1; i--){ raf.seek(i - b.length); byte temp = raf.readByte(); raf.seek(i); raf.writeByte(temp); } raf.seek(skip); raf.write(b); raf.close(); } catch (Exception e) { e.printStackTrace(); } }Use RandomAccessFile to realize multi-threaded download of files, that is, when multiple threads download a file, the file is divided into several pieces, and each piece is downloaded with a different thread. Here is an example of using multithreading when writing files, where the space required for the file is pre-allocated, then chunked in the allocated space, and then written:
import java.io.FileNotFoundException; import java.io.IOException; import java.io.RandomAccessFile; /** * Test using multithreading for file writing operations*/ public class Test { public static void main(String[] args) throws Exception { // Pre-allocated disk space, a file of a specified size will be created on the disk RandomAccessFile raf = new RandomAccessFile("D://abc.txt", "rw"); raf.setLength(1024*1024); // Pre-allocated 1M file space raf.close(); // file content to be written String s1 = "first string"; String s2 = "second string"; String s3 = "third string"; String s4 = "fourth string"; String s5 = "fifth string"; // Write a file at the same time using multiple threads new FileWriteThread(1024*1,s1.getBytes()).start(); // Write data from 1024 bytes of the file new FileWriteThread(1024*2,s2.getBytes()).start(); // Write data from 2048 bytes of the file new FileWriteThread(1024*3,s3.getBytes()).start(); // Write data from 3072 bytes of the file new FileWriteThread(1024*4,s4.getBytes()).start(); // Write data from 4096 bytes of the file new FileWriteThread(1024*5,s5.getBytes()).start(); // Write data from 5120 bytes of the file} // Use a thread to write specified data at the specified location of the file static class FileWriteThread extends Thread{ private int skip; private byte[] content; public FileWriteThread(int skip,byte[] content){ this.skip = skip; this.content = content; } public void run(){ RandomAccessFile raf = null; try { raf = new RandomAccessFile("D://abc.txt", "rw"); raf.seek(skip); raf.write(content); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { try { raf.close(); } catch (Exception e) { } } } } } } }The detailed explanation of the usage of Java RandomAccessFile above is all the content I share with you. I hope you can give you a reference and I hope you can support Wulin.com more.