Random access to file Randomaccessfile and memory mapped files Mappedbytebuffer

Source: Internet
Author: User
Tags file copy

I. Randomaccessfile

Randomaccessfile is used to access files that hold data records, you can use the Seek () method to access the records and read and write them. The sizes of these records do not have to be the same, but their size and position must be knowable. However, this class is limited to manipulating files.

Randomaccessfile does not belong to the InputStream and OutputStream class systems. In fact, in addition to implementing the Datainput and DataOutput interfaces (both DataInputStream and DataOutputStream implement both interfaces), it has nothing to do with these two classes, Do not even use any of the features that already exist in the InputStream and OutputStream classes; it is a completely independent class, and all methods (most of them belong to itself) are written from scratch. This may be because randomaccessfile can move back and forth within a file, so its behavior is fundamentally different from other I/O classes. In summary, it is a separate class that inherits directly from object.

Basically, the way Randomaccessfile works is to combine DataInputStream and dataoutputstream, plus some of its own methods, such as the getfilepointer of positioning (), The Seek () to be moved in the file, and the number of bytes to determine the length (), skipbytes () of the file size skipped. In addition, its constructor has a parameter that indicates whether to open the file as read-only ("R") or read-write ("RW") (fopen () of C). It does not support write-only files.

Only Randomaccessfile has a seek search method, and this method applies only to files. Bufferedinputstream has a mark () method that you can use to set the tag (save the result in an internal variable), and then call Reset () to return to that position, but it is too weak and not practical.

The vast majority of randomaccessfile features, but not all, have been superseded by the "memory-mapped files" of the JDK 1.4 NiO (memory-mapped files), and you should consider whether to use "memory-mapped files" To replace the randomaccessfile.

Java code

Package Jtest;import Java.io.ioexception;import java.io.randomaccessfile;/** * @author root * Randomaccessfile is used to access files that hold data records, you can use the Seek () method to access records, * and read and write. The sizes of these records do not have to be the same, but their size and position must be knowable. However, this class is limited to manipulating files.  */public class Randomaccessfiletest {public static void main (string[] args) throws IOException {Randomaccessfile RF = new Randomaccessfile ("Rtest.dat", "RW"); for (int i = 0; i <; i++) {//write basic type Double data rf.writedouble (i * 1.414);} Rf.close (); RF = new Randomaccessfile ("Rtest.dat", "RW");//move the file pointer directly behind the 5th double data Rf.seek (5);// Overwrites the 6th double data Rf.writedouble (47.0001), Rf.close (), RF = new Randomaccessfile ("Rtest.dat", "R"); for (int i = 0; i <; i++ {System.out.println ("Value" + i + ":" + rf.readdouble ());} Rf.close ();}}

Application of Randomaccessfile class to implement copy operation of file

Package Jtest;import java.io.*;/** * @author root * @ Implement file copy Operation */public class RandomAccessFileTest2 {public static void Mai N (string[] args) throws Exception {randomaccessfile file = new Randomaccessfile ("File", "RW");// The following writes data to the file File.writeint (20);//4 bytes file.writedouble (8.236598);//8 bytes File.writeutf ("This is a UTF string");// This length is written at the first two bytes of the current file pointer and can be read File.writeboolean (true) by Readshort (), or 1 bytes file.writeshort (395);//2 bytes File.writelong ( 2325451L);//accounted for 8 bytes File.writeutf ("Again a UTF string"), File.writefloat (35.5f);//accounted for 4 bytes file.writechar (' a ');// 2 bytes file.seek (0);//Set the file pointer position to the beginning of the file//below to read data from file, note the position of the file pointer System.out.println ("—————— read data from the file specified location ——————"); System.out.println (File.readint ()); System.out.println (File.readdouble ()); System.out.println (File.readutf ()); File.skipbytes (3);//Skips the file pointer over 3 bytes, which in this case skips a Boolean and short value. System.out.println (File.readlong ()); File.skipbytes (File.readshort ()); Skipping the bytes of "another UTF string" in the file, note that the Readshort () method moves the file pointer, so you don't have to add 2. System.out.println (File.readfloat ());//The following demo file copy Operation SYSTEM.OUT.PRintln ("—————— file copy (from file to FileCopy) ——————"); File.seek (0); Randomaccessfile fileCopy = new Randomaccessfile ("FileCopy", "RW"); int len = (int) file.length (); Get file Length (bytes) byte[] B = new byte[len];file.readfully (b); Filecopy.write (b); System.out.println ("Copy done! ");}}

Two. Memory-mapped file mappedbytebuffer

Memory-mapped files allow you to create and modify files that are too large to fit into memory. With a memory-mapped file, you can assume that the file has all been read into memory, and then it is accessed as a very large array. This solution greatly simplifies the code to modify the file.
Filechannel.map (Filechannel.mapmode mode, long position, long size) maps the file area of this channel directly into memory. Note that you have to indicate where it starts mapping from where the file is, how big the map is, and 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 new force () forces the contents of the buffer to be flushed to the storage device, load () loads the data from the storage device into memory, IsLoaded () The data in memory is synchronized with the storage settings. In addition to the put () and get () methods, you can easily read and write basic type data by using methods such as Ascharbuffer () to get a buffered view of the corresponding basic type of data.

import Java.io.randomaccessfile;import Java.nio.mappedbytebuffer;import Java.nio.channels.filechannel;public Class Largemappedfiles {static int length = 0x8000000;//Mbpublic static void Main (string[] args) throws Exception {/ /In order to open the file in a readable and writable manner, use Randomaccessfile to create the file. FileChannel fc = new Randomaccessfile ("Test.dat", "RW"). Getchannel ();//Note that The readable writable file channel is based on the file stream itself can be read and written on the basis of 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 the middle of the file 6 bytes of content for (int i = LENGTH/2; I < LENGTH/2 + 6; i++) {System.out.prin T ((char) out.get (i));} Fc.close ();}}  
Although mapping writes seem to use FileOutputStream, all output from the mapping file must use Randomaccessfile, but if you only need to read FileInputStream, you must use random access files when writing the map file. Perhaps the reason to read when writing .

The program creates a 128Mb file that can cause memory overflow if read to memory at once, but the access here seems like just a flash, because the only small part of the memory is actually transferred, and the rest is placed on the swap file. This makes it easy for you to modify very large files (up to 2 GB). Note that Java is called the "file mapping mechanism" of the operating system to improve performance.

In fact, it is not difficult to master Mappedbytebuffer, as long as remember the "three-way tripartite three characteristics" (Turn from http://blog.csdn.net/mgoann/article/details/3345850) This sentence can be easily done! Mappedbytebuffer is just a special kind of bytebuffer, which is Bytebuffer subclass. Mappedbytebuffer maps files directly to memory (the memory here refers to virtual memory, not physical memory, which is demonstrated later). In general, you can map the entire file, and if the file is larger, you can map it in segments, as long as you specify that part of the file. And, very similar to Bytebuffer, there is no constructor (you cannot construct a mappedbytebuffer with new Mappedbytebuffer (), we can Java.nio.channels.FileChannel's Map () method to get the Mappedbytebuffer. in fact, the popular point is that the map to the content of the file is imaged to a piece of computer virtual memory area, so that you can directly manipulate the data in memory without the need to operate each time through the I/O to the physical hard disk to read files, so the efficiency of a great increase!

Three different ways:

FileChannel provides a map method for mapping files to memory image files: Mappedbytebuffer map (int mode,long position,long size); You can map the size of a file from position to a memory image file, mode indicates how the memory image file can be accessed: read_only,read_write,private.

A. Read_Only, (read-only): Attempting to modify the resulting buffer will cause the readonlybufferexceptionto be thrown. mapmode.read_only)

B. Read_write (read/write): Changes to the resulting buffer will eventually propagate to the file; The change is not necessarily visible to other programs that map to the same file. (mapmode.read_write)

c. Private (private): changes to the resulting buffer are not propagated to the file, and the change is not visible to other programs that map to the same file; instead, a private copy of the modified portion of the buffer is created. (mapmode.private)

Three methods:

A. Fore (); buffer is Read_write mode, this method forces the file to be written to the buffer content modification

B. Load () Loads the contents of the buffer into memory and returns a reference to the buffer

C. isLoaded () If the contents of the buffer are in physical memory, returns true, otherwise false

Three features:

After calling the channel's map () method, you can map part or all of the file to memory, the mapped memory buffer is a direct buffer and inherits from Bytebuffer, but it has more advantages over Bytebuffer:

A. Read fast

B. Write fast

c. Write Anywhere, anytime


Package Jtest;import Java.io.file;import Java.io.fileinputstream;import java.io.fileoutputstream;import Java.nio.bytebuffer;import Java.nio.charbuffer;import Java.nio.mappedbytebuffer;import Java.nio.channels.filechannel;import Java.nio.charset.charset;import Java.nio.charset.charsetdecoder;public Class  Mapmemorybuff {public static void main (string[] args) throws Exception {Bytebuffer bytebuf = bytebuffer.allocate (1024 * 14 * 1024x768); byte[] bbb = new BYTE[14 * 1024 * 1024]; File F = new file ("test"); FileInputStream fis = new FileInputStream ("test"); FileOutputStream fos = new FileOutputStream ("OutFile.txt"); FileChannel FC = Fis.getchannel (); Long Timestar = System.currenttimemillis ();//Get Current time//fc.read (BYTEBUF);//1 Read Mappedbytebuffer MBB = Fc.map (FileChannel.MapMode.READ_ONLY, 0,f.length ()); Long timeend = System.currenttimemillis ( System.out.println ("Read Time:" + (Timeend-timestar) + "MS"); Timestar = System.currenttimemillis ();//FOS.W Rite (BBB);//2 write to Mbb.flip (); timeend = SyStem.currenttimemillis (); System.out.println ("Write Time:" + (Timeend-timestar) + "MS"); Fos.flush (); Fc.close (); Fis.close ();}}

Output Result:

Read time:28ms
Write time:56ms

Replace 1 of the above program with Mappedbytebuffer MBB = Fc.map (FileChannel.MapMode.READ_ONLY, 0, file length);

2 Replace with Mbb.flip ();

Output Result:

Read time:2ms
Write time:0ms

Normal I/O and Mappedbytebuffer can be seen. In addition, it takes 0ms to write the map write mechanism is based on your change amount to decide, just save the modified part!


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.