文件管理
流类关注的是文件内容,而File类关注的是文件在磁盘上的存储。注意,File类的对象既可以表示文件,也可以表示文件夹。
java.io.File 1.0
File(String name)//创建一个文件/文件夹对象,使用当前目录下的文件名name,如果文件/文件夹不存在,则不会创建使用这个名字的新文件/文件夹。
File(String path, String name)//创建一个位于path目录下的名为name的File对象。
File(File dir, String name)//创建一个位于dir目录下的名为name的File对象。
boolean createNewFile()//以File对象是定的名字创建一个新的文件,成功返回true。
boolean mkdir()//以File对象指定的名字创建一个新的文件夹,成功返回true。
String[] list()//如果File对象表示一个文件夹,则返回该文件夹下的所有文件名组成的数组。
String[] list(FileNameFilter filter)//FileNameFilter是一个接口,要实现这个接口必须定义accept方法。该方法返回一个boolean值,调用list方法只会显示accept返回true的文件名数组。
boolean exists()//如果文件/文件夹存在返回true,否则返回false。
File getCanonicalFile()//返回一个包含该File对象绝对路径的File对象。
String getCanonicalFile()//返回一个包含该File对象绝对路径的字符串。
String getName()//返回File对象的文件名字符串(不包括路径信息)。
boolean isDirectory()//File对象表示文件夹返回true,否则返回false。
boolean isFile()//File对象表示文件返回true,否则返回false。
还有一些其他方法可以查询java文档。
在不同的系统中,路径的分隔符不相同,例如windows中使用【】,Unix中使用【/】,为了实现可移植性,File类中有个separator静态成员变量,它保存着当前系统的路径分隔符信息:
File foo = new File("Documents" + File.separator + "data.txt");
内存映射文件
建立内存映射步骤:
1.为文件获取通道(channel),通过FileInputStream/FileOutputStream或RandomAccessFile类中的getChannel方法。
2.通过调用FileChannel类的map方法获得MappedByteBuffer。可以指定需要进行映射的文件区域和映射模式:
FileChannel.MapMode.READ_ONLY:结果缓冲区是只读的。任何试图写入缓冲区的举动都将引发抛出ReadOnlyBufferException。
FileChannel.MapMode.READ_WRITE:结果缓冲区可写,这些改变会及时写回文件中。注意,如果其他程序也映射了同一个文件,它并不会立即观察到这些变化。
FileChannel.MapMode.PRIVATE:结果缓冲区可写,但任何改变都是私有的,仅仅对该缓冲区有效,并不会写入文件中。
3.一旦获取了缓冲区,可以用ByteBuffer类和Buffer超类读写数据。
例如,将一个文件映射到内存,然后通过访问内存读取文件内容:
public void myRead(String filename) { FileInputStream in = new FileInputStream(filename); FileChannel channel = in.getChannel(); int length = (int)channel.size(); MappedByteBuffer buffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, length); while(buffer.hasRemaining()) { byte b = buffer.get(); ...//dealing with the byte } }
java.nio.channels.FileChannel 1.4
MappedByteBuffer map(FileChannel.MapMode mode, long position, long size)
参数:mode
position 被映射区域的起始位置
size 被映射区域的大小
java.nio.ByteBuffer 1.4
byte get()//获取当前位置的字节并移动到当前位置的下一字节位置。
byte get(int index)//获取指定位置的字节
ByteBuffer put(byte b)//在当前位置写入一个字节并移动到下一字节位置。返回该缓冲区的引用。
ByteBuffer put(int index, byte b)//在指定位置写入一个字节。
ByteBuffer get(byte[] destination)//用缓冲区中的字节来填充字节数组。并且将当前位置向后移动读入的字节数。如果缓冲区中没有足够的字节,则不会读取任何字节,抛出BufferUnderflowException。
ByteBuffer get(byte[] destination, int offset, int length)//用缓冲区中的字节来填充字节数组的一部分。
参数:destination 被填充的字节数组
offset 被填充区域的偏移量
length 被填充区域的大小
ByteBuffer put(byte[] source)//将字节数组填充到缓冲区,并且将当前位置向后移动了写入的字节数。如果缓冲区中没有足够的空间,则不会写入任何字节,并抛出BufferOverflowException。
ByteBuffer put(byte[] source, int offset, int length)//将字节数组的一部分填充到缓冲区中。
Xxx getXxx()
Xxx getXxx(int index)
ByteBuffer putXxx(xxx value)
ByteBuffer putXxx(int index, xxx value)
//Xxx是Int,Long,Short,Char, Float或者Double
ByteOrder order()//获取字节顺序,返回BIG_ENDIAN或LITTLE_ENDIAN。
ByteBuffer order(ByteOrder order)//设置字节顺序。
文件映射的内存称为缓冲区,由Buffer类来表示,Buffer类有一些子类,包括:ByteBuffer,CharBuffer,DoubleBuffer,FloatBuffer,IntBuffer,LongBuffer,ShortBuffer.
一个缓冲区具有
1.一个绝不会改变的容量(capacity)。
2.一个下一数值读取或写入的位置(positon)。
3.一个限制,超出这个限制的读写是无意义的(limit)。
4.可选地,一个重复进行读写操作的标志(mark)。
这些值满足条件:
0<=mark<=position<=limit<=capacity
java.nio.Buffer 1.4
Buffer clear()//设置position到0,limit到capacity,准备写入。
Buffer flip()//设置position到0,limit到capacity,准备读取。
Buffer rewind()//设置positon到0,limit不变,准备再次读取。
Buffer mark()//设置mark到position
Buffer reset()//设置position到mark,从而允许mark部分能再次读或写。
int remaining()//返回limit-position,即还能够读写的数量。
int positon()//返回position
int capacity()//返回capacity
java.nio.CharBuffer 1.4
char get()
CharBuffer get(char[] destination)
CharBuffer get(char[] destination,int offset, int length)
获取一个char值,或者一系列的char值,从缓冲区的position开始,移动position直到字符都被读取。
CharBuffer read(CharBuffer destination)
从这个缓冲区中获取char值,并且把他们放进destination中直到destination到达了limit。
CharBuffer put(char c)
CharBuffer put(char[] source)
CharBuffer put(char[] source, int offset, int length)
CharBuffer put(String source)
CharBuffer put(CharBuffer source)
文件锁定
多个进程或线程同时处理一个文件时,需要同步机制,文件锁可以完成这一任务。
要锁住一个文件,需要调用FileChannel类的lock或tryLock方法,它们的区别是一个阻塞,一个非阻塞。
java.nio.channels.FileChannel 1.4
FileLock lock()
FileLock lock(long position, long size, boolean shared)//锁住文件的一部分,position表示锁住部分的起始位置,size表示锁住部分的大小,shared表示是否为共享锁。共享锁都可读,但只有一个可写。
FileLock tryLock()
FileLock tryLock(long position, long size, boolean shared)
java.nio.channels.FileLock 1.4
void release()//释放锁
注意:文件锁和操作系统有很大的关系:
1.在一些系统中,文件锁仅仅是建议性的,因此,一个应用程序未能获得锁,也可以对文件进行读写操作。
2.在一些系统中,不能同步地锁住一个文件并把它映射到内存中。
3.文件锁是整个Java虚拟机持有的,如果虚拟机已经拥有了对同一个文件的重叠锁,则lock或者tryLock方法会抛出异常。
4.在某些系统上,关闭通道会释放Java虚拟机拥有的文件上的全部锁,因此,应该避免对同一个被锁定的文件打开多个通道。
5.避免对网络文件系统中的文件进行锁定。