// 字符编码转换
// ByteBuffer中存放了表示Unicode字符编码的字节,那么asCharBuffer()方法会返回包含正确字符的CharBuffer,否则,asCharBuffer()方法返回的CharBuffer
// 会包含乱码,此时应该利用Charset类来进行Unicode字符编码与其他类型字符编码的转换
// 缓冲区视图
// ByteBuffer类提供了asCharBuffer(),asIntBuffer()和asFloatBuffer()等用来生成缓冲区视图的方法,通过视图,程序可以从底层的ByteBuffer中读取各种基本类型
// 的数据,或者向底层的ByteBuffer中写入各种基本类型的数据
// 文件映射缓冲区MappedByteBuffer用于创建和修改那些因为太大而不能放入内存的文件,可用来映射文件中的一块区域,所有对MappedByteBuffer的读写操作都会被映射到对文件的物理读写操作
// FileChannel提供了获得MappedByteBuffer对象的map()方法:MappedByteBuffer map(FileChannel.MapMode mode,long position ,long size)
// position指定文件映射区域的起始位置,参数size指定映射区域的大小,参数mode指定映射模式,包括三种:
// MapMode.READ_ONLY---只能对映射区域进行读操作, Read/Write---可以对映射区域进行读和写的操作,MapMode.PRIVATE----对MappedByteBuffer缓冲区中数据的修改不会被保存
// 到文件中,并且这种修改对其他程序不可见,
// 文件加锁
// java使用的文件锁对操作系统的其他线程是可见的,因为这种文件锁直接映射到本地操作系统的加锁工具
public class Test21 {
public static void main(String[] args) throws Exception {
// ByteBuffer中存放的是UTF-8字符编码,Charset.forName("UTF-8")方法返回代表UTF-8字符编码的Charset对象,该Charset对象的decode()
// 方法把ByteBuffer参数中的UTF-8字符编码转换为CharBuffer中的Unicode字符编码,因此CharBuffer包含正确的字符串
ByteBuffer bb = ByteBuffer.wrap("你好".getBytes("UTF-8"));
Charset cs = Charset.forName("UTF-8");
CharBuffer cb = cs.decode(bb);
System.out.println(cb);
// Charset.forName("GBK")返回代表GBK字符编码的Charset对象,该Charset对象的encode()方法把字符串"你好"转换为GBK字符编码,并把它存放在ByteBuffer中
cs = Charset.forName("GBK");
bb = cs.encode("你好");
cb = cs.decode(bb);
for (int i = 0; i < cb.limit(); i++) {
System.out.println(cb.get());
}
FileOutputStream fos = new FileOutputStream("D:\\test.txt");
// FileChannel的tryLock()或lock()方法用于锁定文件,锁定成功,会返回一个FileLock对象,tryLock()方法是非阻塞式的,他设法获取锁,如果不能获得锁,就立即返回null
// lock()方法是阻塞式的,他设法获取锁,如果不能获得锁,那么会执行该lock()方法的线程进入阻塞状态,只有等到获得了锁,线程才能恢复运行
// 也可以对文件的部分区域加锁:
// tryLock(long position, long size, boolean shared)
// lock(long position, long size, boolean shared)
// 依次是加锁位置,加锁区域大小,指定锁的类型,true为共享锁,否则为排他锁,
// 共享锁:当一个线程已经获得了文件的共享锁时,其他线程还可以获得该文件的共享锁,但是不能获得该文件的排他锁。
// 排他锁:当一个线程已经获得了文件的排他锁时,其他线程不允许获得该文件的共享锁和排他锁
// FileLock类的isShared()方法用来判断锁的类型,true为共享锁
// release()用来释放文件锁,程序没有调用该方法,则java虚拟机结束进程以前,也会自动释放进程占用的所有文件锁
// 有些巨大的文件,如数据库的存储文件,可能会有多个用户同时访问他们,为了提高并发性,可以对文件进行部分加锁,使得其他线程或进程可以同时方法文件中未被加锁的部分
//
FileLock fl = fos.getChannel().tryLock();
if(fl!=null){
System.out.println("Locked File");
System.out.println(fl.isShared());
fl.release();
System.out.println("Released Lock");
}
}
}