import java.io.File; import java.io.FileOutputStream; import java.io.RandomAccessFile; import java.nio.ByteBuffer; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; import java.nio.channels.FileLock; public class test_05 { public static void main(String[] args) throws Exception { //FileLoc lock()的无参数方法为: /*源码: public final FileLock lock() throws IOException { return lock(0L, Long.MAX_VALUE, false); } *该方法与FileLock lock(position, MAX_VALUE, false)的特性完全一样 */ //tryLock(),此方法不会阻塞,如果另一个程序保持着一个重叠锁而无法获得锁定时,此方法返回null,如果由于其他原因,则抛出相应的异常 //test_05_01和test_05_02 //tryLock()的无参数和tryLock(0,Long.MAX_VALUE,false);特性一样 //isValid:测试锁的有效性,isShared:独占还是共享 //method_01();
private static void method_01() throws Exception{
File file = new File("C:\\Users\\10167\\Desktop\\test.txt");
RandomAccessFile randomAccessFile = new RandomAccessFile(file,"rw");
FileChannel fileChannel = randomAccessFile.getChannel();
System.out.println("filechannel.hashcode() = "+fileChannel.hashCode());
FileLock lock = fileChannel.lock(1, 10, true);
System.out.println("A position = "+lock.position()+" A size = "+lock.size() +"A.isValid = "+lock.isValid()+ " A isShared = "+lock.isShared()
+" A channel().hashcode() = "+lock.channel().hashCode()+" acquiredBy().hashcode() = "+lock.acquiredBy().hashCode());
lock.release();
lock = fileChannel.lock(1,10,false);
System.out.println("A position = "+lock.position()+" A size = "+lock.size() +"A.isValid = "+lock.isValid()+ " A isShared = "+lock.isShared()
+" A channel().hashcode() = "+lock.channel().hashCode()+" acquiredBy().hashcode() = "+lock.acquiredBy().hashCode());
lock.close();
fileChannel.close();
System.out.println("A position = "+lock.position()+" A size = "+lock.size() +"A.isValid = "+lock.isValid()+ " A isShared = "+lock.isShared()
+" A channel().hashcode() = "+lock.channel().hashCode()+" acquiredBy().hashcode() = "+lock.acquiredBy().hashCode());
/*输出
filechannel.hashcode() = 460141958
A position = 1 A size = 10A.isValid = true A isShared = true A channel().hashcode() = 460141958 acquiredBy().hashcode() = 460141958
A position = 1 A size = 10A.isValid = true A isShared = false A channel().hashcode() = 460141958 acquiredBy().hashcode() = 460141958
A position = 1 A size = 10A.isValid = false A isShared = false A channel().hashcode() = 460141958 acquiredBy().hashcode() = 460141958
* */
}
//overlaps(long position,long size):判断此锁是否与给定的锁定区域重叠,当且仅当至少重叠一个字节时,返回true //method_02();
private static void method_02() throws Exception{
File file = new File("C:\\Users\\10167\\Desktop\\test.txt");
RandomAccessFile randomAccessFile = new RandomAccessFile(file,"rw");
FileChannel fileChannel = randomAccessFile.getChannel();
FileLock lock = fileChannel.lock(1, 4, false);
System.out.println(lock.overlaps(3,6));
System.out.println(lock.overlaps(5,6));
/*输出
true
false
* */
}
//force(boolean metaData):强制将所有对通道的更新写入包含的文件设备,尽量减少数据丢失,耗费资源多,事件至少也要200倍以上 //metaData为false只是写入存储设备,为true则必须写入对文件内容和元素据的更新 //此参数是否有效,取决于底层操作系统 //method_03();
private static void method_03() throws Exception{
Thread thread1 = new Thread(){
@Override
public void run() {
try {
File file = new File("C:\\Users\\10167\\Desktop\\test3.txt");
if(!file.exists()){
file.createNewFile();
}
FileOutputStream fileOutputStream = new FileOutputStream(file);
FileChannel fileChannel = fileOutputStream.getChannel();
Long startTime = System.currentTimeMillis();
for (int i = 0; i < 5000; i++) {
fileChannel.write(ByteBuffer.wrap("abcdef".getBytes()));
}
Long endTime = System.currentTimeMillis();
System.out.println(endTime - startTime);
}catch (Exception e){
e.printStackTrace();
}
}
};
Thread thread2 = new Thread(){
@Override
public void run() {
try {
File file = new File("C:\\Users\\10167\\Desktop\\test4.txt");
if(!file.exists()){
file.createNewFile();
}
FileOutputStream fileOutputStream = new FileOutputStream(file);
FileChannel fileChannel = fileOutputStream.getChannel();
Long startTime = System.currentTimeMillis();
for (int i = 0; i < 5000; i++) {
fileChannel.write(ByteBuffer.wrap("abcdef".getBytes()));
fileChannel.force(false);
}
Long endTime = System.currentTimeMillis();
System.out.println(endTime - startTime);
}catch (Exception e){
e.printStackTrace();
}
}
};
thread1.start();
thread2.start();
/*输出
23
5459
* */
}
//将通道文件区域直接映射到内存 //MappedByteBuffer map(FileChannel.MapMode mode , long position , long size ) //三种模式:只读,读写,专用 //测试该方法 //method_04();
private static void method_04() throws Exception{
File file = new File("C:\\Users\\10167\\Desktop\\test.txt");
RandomAccessFile randomAccessFile = new RandomAccessFile(file,"rw");
FileChannel fileChannel = randomAccessFile.getChannel();
MappedByteBuffer buffer = fileChannel.map(FileChannel.MapMode.READ_ONLY,0,5);
System.out.println((char)buffer.get()+" position="+buffer.position());
System.out.println((char)buffer.get()+" position="+buffer.position());
System.out.println((char)buffer.get()+" position="+buffer.position());
System.out.println((char)buffer.get()+" position="+buffer.position());
System.out.println((char)buffer.get()+" position="+buffer.position());
buffer = fileChannel.map(FileChannel.MapMode.READ_ONLY,2,2);
System.out.println((char)buffer.get()+" position="+buffer.position());
System.out.println((char)buffer.get()+" position="+buffer.position());
Thread.sleep(500);
//此句超出映射范围
System.out.println((char)buffer.get()+" position="+buffer.position());
/*输出
a position=1
b position=2
c position=3
d position=4
e position=5
c position=1
d position=2
Exception in thread "main" java.nio.BufferUnderflowException
* */
}
//只读:试图修改缓冲区抛出异常 //method_05();
private static void method_05() throws Exception{
File file = new File("C:\\Users\\10167\\Desktop\\test.txt");
RandomAccessFile randomAccessFile = new RandomAccessFile(file,"rw");
FileChannel fileChannel = randomAccessFile.getChannel();
MappedByteBuffer buffer = fileChannel.map(FileChannel.MapMode.READ_ONLY,0,5);
buffer.putChar('1');
//抛出异常:Exception in thread "main" java.nio.ReadOnlyBufferException
}
//读写:对得到的缓冲区的更改最终将传播到文件,该更改对映射到同一文件的其他程序不一定是可见的 //method_06();
private static void method_06() throws Exception{
File file = new File("C:\\Users\\10167\\Desktop\\test.txt");
RandomAccessFile randomAccessFile = new RandomAccessFile(file,"rw");
FileChannel fileChannel = randomAccessFile.getChannel();
MappedByteBuffer buffer = fileChannel.map(FileChannel.MapMode.READ_WRITE,0,5);
System.out.println((char)buffer.get()+" position="+buffer.position());
System.out.println((char)buffer.get()+" position="+buffer.position());
System.out.println((char)buffer.get()+" position="+buffer.position());
System.out.println((char)buffer.get()+" position="+buffer.position());
System.out.println((char)buffer.get()+" position="+buffer.position());
buffer.position(0);
buffer.put((byte)'a');
buffer.put((byte)'b');
buffer.put((byte)'c');
buffer.put((byte)'d');
buffer.put((byte)'e');
fileChannel.close();
randomAccessFile.close();
/*输出
a position=1
b position=2
c position=3
d position=4
e position=5
执行完后:文件内为:abcde,对缓冲区的更改最终传播到文件
* */
}
//专用:对得到的缓冲区的更改最终不会传播到文件,该更改对映射到同一文件的其他程序不可见 //method_07();
private static void method_07() throws Exception{
File file = new File("C:\\Users\\10167\\Desktop\\test.txt");
RandomAccessFile randomAccessFile = new RandomAccessFile(file,"rw");
FileChannel fileChannel = randomAccessFile.getChannel();
MappedByteBuffer buffer = fileChannel.map(FileChannel.MapMode.PRIVATE,0,5);
System.out.println((char)buffer.get()+" position="+buffer.position());
System.out.println((char)buffer.get()+" position="+buffer.position());
System.out.println((char)buffer.get()+" position="+buffer.position());
System.out.println((char)buffer.get()+" position="+buffer.position());
System.out.println((char)buffer.get()+" position="+buffer.position());
buffer.position(0);
buffer.put((byte)'1');
buffer.put((byte)'2');
buffer.put((byte)'3');
buffer.put((byte)'4');
buffer.put((byte)'5');
fileChannel.close();
randomAccessFile.close();
/*输出
a position=1
b position=2
c position=3
d position=4
e position=5
文件内容:abcde,最终缓冲区的更改没有传播到文件
* */
}
//MappedByteBuffer load和MappedByteBuffer isLoaded() //将缓冲区内容加载到物理内存中,最大限度地保证返回时此缓冲区地内容位于物理内存中,可能会导致一些页面错误,并导致I/O操作 //isLoaded返回false也不是缓冲区内容不位于物理内存中,只是一个提示,而不是保证 method_08();
private static void method_08() throws Exception{
File file = new File("C:\\Users\\10167\\Desktop\\test.txt");
RandomAccessFile randomAccessFile = new RandomAccessFile(file,"rw");
FileChannel fileChannel = randomAccessFile.getChannel();
MappedByteBuffer buffer = fileChannel.map(FileChannel.MapMode.READ_WRITE,0,10);
//System.out.println(buffer+" "+buffer.isLoaded());
buffer.load();
System.out.println(buffer+" "+buffer.isLoaded());
}
}
}