Java nio(3)
Java nio(三)
一、读文件:
前面我们介绍了通过获得FileChannel来写文件,现在我们再看看读操作。
其实读操作和写操作基本是对应的。
首先与写操作类似从文件中获得流,读操作要获得输入流FileInputStream
,再从这个流中得到FileChannel对象,然后进行读操作。
文件通道的读操作有三个read()方法:
用个小例子描述上面的过程:
二、文件复制:
文件通道定义了两个方法,可以进行直接的文件传输:
int transferTo(int position,long count,WritableByteChannel dst);
这个函数是把文件从position位置开始向dst通道传送count个字节。
int transferFrom(ReadableByteChannel src,long position,long count);
将count个字节从通道src传送到文件中,position是为文件开始写入的位置。
从FileInputStream中获得的通道只支持transferTo,而从FileOutputStream中获得
的通道只支持tansferFrom()方法
举个小例子来说明这个过程:
也可以使用outChannel的transferFrom()方法复制数据,他们都可以一次传送所有的
数据,万一没有一次传送所有的数据,可以使用类似上面的while循环来处理。
三、随机读取文件:
FileChannel定义了两个方法用来进行随机读写操作:
int read(ByteBuffer buf,long position);
从文件的position位置开始读取字节到buf中
int write(ByteBuffer buf,long position);
把buf的数据,从文件的position开始写入到文件中
四、一个通道进行文件的读写
上面提到的从FileInputStream和FileOutputStream获得的通道只能进行读或者写操作,
如果我们想得到一个通道,同时可以进行读和写操作,那该怎么办?
从RandomAccessFile获得的通道就是这样一个通道。
五、内存映像文件:
内存映像文件是这样的文件,它的内容被映像到计算机虚拟内存的一块区域,这样就可以
直接的使用和更新文件中的数据了,可以很大的提高效率。
FileChannel提供了map方法来把文件影射为内存映像文件:
MappedByteBuffer map(int mode,long position,long size);
可以把文件的从position开始的size大小的区域映射为内存映像文件,mode指出了
可访问该内存映像文件的方式:READ_ONLY,READ_WRITE,PRIVATE.
详细可以参考java API
MappedByteBuffer类还提供了三个方法:
fore();缓冲区是READ_WRITE模式下,此方法对缓冲区内容的修改强行写入文件
load()将缓冲区的内容载入内存,并返回该缓冲区的引用
isLoaded()如果缓冲区的内容在物理内存中,则返回真,否则返回假
后面总结有关从Socket获得到SocketChannel进行异步通讯的问题。
一、读文件:
前面我们介绍了通过获得FileChannel来写文件,现在我们再看看读操作。
其实读操作和写操作基本是对应的。
首先与写操作类似从文件中获得流,读操作要获得输入流FileInputStream
,再从这个流中得到FileChannel对象,然后进行读操作。
文件通道的读操作有三个read()方法:
int read(ByteBuffer buf); 从文件中读取buf.remaining()[即limit-position]个字节到缓冲区buf,从缓冲区的当前位置开始存取 int read(ByteBuffer[] buffers); 从文件中读到多个缓冲区中 int read(ByteBuffer[] buffers,int offset,int length); 从文件中读到buffers[offset]--buffers[offset+length-1]缓冲区中
用个小例子描述上面的过程:
File file = new File("D:\text.txt"); FileInputStream fis = new FileInputStream(file); FileChannel inputChannel = fis.getChannel(); ByteBuffer buf = ByteBuffer.allocate(48); while(inChannel.read(buf) != -1){ //....从buf中提取出数据;for example: System.out.println(buf.filp().asCharBuffer().toString()); buf.clear(); }
二、文件复制:
文件通道定义了两个方法,可以进行直接的文件传输:
int transferTo(int position,long count,WritableByteChannel dst);
这个函数是把文件从position位置开始向dst通道传送count个字节。
int transferFrom(ReadableByteChannel src,long position,long count);
将count个字节从通道src传送到文件中,position是为文件开始写入的位置。
从FileInputStream中获得的通道只支持transferTo,而从FileOutputStream中获得
的通道只支持tansferFrom()方法
举个小例子来说明这个过程:
File fromFile = new File("D:/from.txt"); File toFile = new File("D:/to.txt"); FileInputStream fis = new FileInputStream(fromFile); FileOutputStream fos = new FileOutputStream(toFile); FileChannel inChannel = fis.getChannel(); FileChannel outChannel = fos.getChannel(); int byteWritten = 0; long byteCount = inChannel.size(); while(byteWritten < byteCount){ byteWritten += inChannel.transferTo(bytesWritten,byteCount- bytesWritten,outChannel); } fis.close(); fos.close();
也可以使用outChannel的transferFrom()方法复制数据,他们都可以一次传送所有的
数据,万一没有一次传送所有的数据,可以使用类似上面的while循环来处理。
三、随机读取文件:
FileChannel定义了两个方法用来进行随机读写操作:
int read(ByteBuffer buf,long position);
从文件的position位置开始读取字节到buf中
int write(ByteBuffer buf,long position);
把buf的数据,从文件的position开始写入到文件中
四、一个通道进行文件的读写
上面提到的从FileInputStream和FileOutputStream获得的通道只能进行读或者写操作,
如果我们想得到一个通道,同时可以进行读和写操作,那该怎么办?
从RandomAccessFile获得的通道就是这样一个通道。
File file = new File("D:\test.txt"); RandomAccessFile raf = new RandomAccessFile(file,"rw"); FileChannel ioChannel = rad.getChannel();
五、内存映像文件:
内存映像文件是这样的文件,它的内容被映像到计算机虚拟内存的一块区域,这样就可以
直接的使用和更新文件中的数据了,可以很大的提高效率。
FileChannel提供了map方法来把文件影射为内存映像文件:
MappedByteBuffer map(int mode,long position,long size);
可以把文件的从position开始的size大小的区域映射为内存映像文件,mode指出了
可访问该内存映像文件的方式:READ_ONLY,READ_WRITE,PRIVATE.
详细可以参考java API
MappedByteBuffer类还提供了三个方法:
fore();缓冲区是READ_WRITE模式下,此方法对缓冲区内容的修改强行写入文件
load()将缓冲区的内容载入内存,并返回该缓冲区的引用
isLoaded()如果缓冲区的内容在物理内存中,则返回真,否则返回假
File file = new File("D:\test.txt"); RandomAccessFile raf = new RandomAccessFile(file,"rw"); FileChannel ioChannel = rad.getChannel(); MappedByteBuffer buf = ioChannel.map(READ_WRITE.0L,ioChannel.size()).load();
后面总结有关从Socket获得到SocketChannel进行异步通讯的问题。
1 楼
fuliang
2008-03-02
另外补充一下读写基本类型的例子:
写入基本类型:
读入基本类型:
将刚写入的数据读出:
写入基本类型:
public static void testWritePrimitiveBuffer()throws Exception{ int i = 10; long l = 10L; double d = 29.01; char ch = 'c'; ByteBuffer buffer = ByteBuffer.allocate(100); buffer.putInt(i).putLong(l).putDouble(d).putChar(ch); FileOutputStream fos = new FileOutputStream(new File("D:/primitive.txt")); FileChannel outputChannel = fos.getChannel(); buffer.flip(); outputChannel.write(buffer); }
读入基本类型:
将刚写入的数据读出:
public static void testReadPrimitiveBuffer()throws Exception{ int i; long l; double d; char ch; ByteBuffer buffer = ByteBuffer.allocate(100); FileInputStream fis = new FileInputStream(new File("D:/primitive.txt")); FileChannel inputChannel = fis.getChannel(); inputChannel.read(buffer); buffer.flip(); i = buffer.getInt(); l = buffer.getLong(); d = buffer.getDouble(); ch = buffer.getChar(); System.out.println("i=" + i + ",l=" + l + ",d=" + d + ",ch=" + ch); }
2 楼
bojianpc
2008-09-08
不错哦最近项目要用 可以向你请教此类的问题么 我的QQ1067302 希望能得到你的恢复