流与文件(三)

文件管理

流类关注的是文件内容,而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.避免对网络文件系统中的文件进行锁定。

原文地址:https://www.cnblogs.com/johnsblog/p/4180601.html