一、内存文件映射
内存文件映射允许我们创建和修改那些因为太大而不能放入内存中的文件。有了内存文件映射,我们就可以假定整个文件都在内存中,而且可以完全把文件当作数组来访问。
package com.dy.xidian; import java.io.RandomAccessFile; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; public class LargeMappedFiles { static int length = 0x8FFFFFF; public static void main(String[] args) throws Exception { @SuppressWarnings("resource") MappedByteBuffer out = new RandomAccessFile("test.dat", "rw") .getChannel().map(FileChannel.MapMode.READ_WRITE, 0, length); for (int i = 0; i < length; i++) out.put((byte) ‘x‘); System.out.println("Finished writing"); for (int i = length / 2; i < length / 2 + 6; i++) System.out.print((char) out.get(i)); } }
map中的0表示从文件的起始位置开始映射,映射的大小为length(128MB)。MappedByteBuffer是直接缓冲区(JVM对直接缓冲区的内容会直接进行IO操作,如果缓冲区是非直接的,JVM会先将用户缓冲区的数据copy到自己的缓冲区,在对自己的缓冲区进行IO操作),
所以MappedByteBuffer对大文件的操作速度要比普通的IO流快。MappedByteBuffer继承自ByteBuffer,所以我们对ByteBuffer的操作都适用于ByteBuffer。
二、对映射文件的部分加锁
文件映射通常应用于极大的文件。我们可能需要对这种巨大的文件进行部分加锁,以便其它进程可以修改文件中未被加锁的部分。例如:数据库就是这样吗,因此多个用户可以同时访问它
package com.dy.xidian; import java.io.IOException; import java.io.RandomAccessFile; import java.nio.ByteBuffer; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; import java.nio.channels.FileLock; public class LockingMappedFiles { static final int LENGTH = 0X8FFFFFF; static FileChannel fc; @SuppressWarnings("resource") public static void main(String[] args) throws Exception { fc = new RandomAccessFile("test.dat", "rw").getChannel(); MappedByteBuffer out = fc .map(FileChannel.MapMode.READ_WRITE, 0, LENGTH); for (int i = 0; i < LENGTH; i++) out.put((byte) ‘x‘); new LockAndModify(out, 0, LENGTH / 3); new LockAndModify(out, LENGTH / 2, LENGTH / 2 + LENGTH / 4); } private static class LockAndModify extends Thread { private ByteBuffer buff; private int start, end; LockAndModify(ByteBuffer buff, int start, int end) { super(); this.start = start; this.end = end; this.buff = buff; buff.limit(end); buff.position(start); //创建一个新缓冲区标识对象 //该对象的position=0,limit和capacity等于原缓冲区剩余字节数。 buff = buff.slice(); start(); } public void run() { try { // 获取通道上的锁,指定加锁的起始位置和结束位置 // 将锁设置为独占锁 FileLock fl = fc.lock(start, end, false); System.out.println("Locked: " + start + " to " + end); while (buff.position() < buff.limit() - 1) buff.put((byte) (buff.get() + 1)); fl.release(); System.out.println("Released: " + start + " to " + end); } catch (IOException e) { throw new RuntimeException(e); } } } }
3.GZIP的使用范例
package com.dy.xidian; import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; public class GZIPcompress { public static void main(String[] args) throws IOException { if (args.length == 0) { System.out.println("Usage: \n\tGZIPcompress file\n" + "\tUses GZIP compress to compress " + "the file to test.gz"); System.exit(1); } BufferedReader in = new BufferedReader(new FileReader(args[0])); BufferedOutputStream out = new BufferedOutputStream( new GZIPOutputStream(new FileOutputStream("test.gz"))); System.out.println("Writing file"); int c; while ((c = in.read()) != -1) { out.write(c); } in.close(); out.close(); System.out.println("Reading file"); BufferedReader in2 = new BufferedReader(new InputStreamReader( new GZIPInputStream(new FileInputStream("test.gz")))); String s; while ((s = in2.readLine()) != null) System.out.println(s); in2.close(); } }
时间: 2024-10-22 11:51:03