Buffer和FileChannel 都有pos指针的操作
FileChannel :
FileChannel 主要是利用pos指针的块数据操作,所以输入和输出的块对象有:ByteBuffer ,FileChannel 和 ByteBuffer[ ]数组三类。FileChannel 主要是channel之间的复制传输。
ByteBuffer:
ByteBuffer是读写FileChannel的标配工具,有FileChannel必有Bytebuffer。
Buffer的作用:除了因为是块操作速度快外,还有一个作用是可以任意提取Buffer中全部或是部分buffer数据。
ByteBuffer 的任何操作前,一定要记得pos指针在哪里。一定要设置pos的值
ByteBuffer 的处理主要是转为byte[ ]后,再对byte数组操作。
Files:
Files主要是对文件的建立,删除等操作。最实用的是InputStream OutputStream 这两个流和Files之间的双向转换 ; 字节数组与Files 的双向转换。所以如要把文件转化为流或数组,选Files,如果是读取部分文件数据,选FileChannel。
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Path;
import java.nio.file.Paths;
import static java.nio.file.StandardOpenOption.READ;
public class Test1 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
Khd3 kk=new Khd3();
Path path=Paths.get("/home/wjs/1.txt");
FileChannel fileInputStream=FileChannel.open(path,READ); //用读的方式打开文件
fileInputStream.position(65); //设置文件指针(每一个T类数据开始的第一个位置)
ByteBuffer byteBuffer=ByteBuffer.allocate(65); // 读入每一个T的数据,ByteBuffer大小刚好与数据一样,不多读也不少读
fileInputStream.read(byteBuffer);
byte[] b=byteBuffer.array(); //ByteBuffer 转为数组
ByteArrayInputStream inputStream=new ByteArrayInputStream(b); //字节数组转为Inputstream
ObjectInputStream objectInputStream=new ObjectInputStream(inputStream);
T t= (T) objectInputStream.readObject();
System.out.println(t.name);
System.out.println(t.age);
}
}
import java.io.*;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
import static java.nio.file.StandardOpenOption.*;
public class Khd3{
static Map<String,Integer> map1=new HashMap<>();
static Map<String,Integer> map2=new HashMap<>();
public static void main(String[] args) throws IOException {
Path path=Paths.get("/home/wjs/1.txt");
FileChannel fileInputStream=FileChannel.open(path,READ);
int c= (int) fileInputStream.size();
fileInputStream.close();
T t=new T("ww",20);
map1.put(t.name,c); //存入数据的首地址
System.out.println(map1.get("ww"));
OutputStream outputStream=Files.newOutputStream(path,APPEND);
ObjectOutputStream objectOutputStream=new ObjectOutputStream(outputStream);
objectOutputStream.writeObject(t);
objectOutputStream.flush();
FileChannel fileInputStream2=FileChannel.open(path,READ);
int c2= (int) fileInputStream2.size();
fileInputStream2.close();
map2.put(t.name,c2); //存入数据的结束地址
System.out.println(map2.get("ww"));
}
}
class T implements Serializable{
String name;
int age;
T(String name,int age)
{
this.name=name;
this.age=age;
}
}
//ByteBuffer的作用:多个Buffer 的拼接;可以用为多个文件的拼接。
//buffer 的重点,我理解就是怎样用pos 位置指针。读写时都可以用pos操作。
import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Path;
import java.nio.file.Paths;
import static java.nio.file.StandardOpenOption.*;
public class Khd3{
public static void main(String[] args) throws IOException {
// Path path= FileSystems.getDefault().getPath("/home/wjs/1.txt"); 提取path 的两种方法
Path path1= Paths.get("/home/wjs/2.txt");
byte[] b={48,49,50,51,52};
byte[] b1={(byte)'a',(byte)'b',(byte)'c',(byte)'d'};
ByteBuffer byteBuffer=ByteBuffer.wrap(b); //byte[] 包装为buffer
ByteBuffer byteBuffer1=ByteBuffer.wrap(b1);
//--------------------------------------------------
ByteBuffer byteBuffer8=ByteBuffer.allocate(100);
byteBuffer8.put(byteBuffer); //pos=0
byteBuffer8.put(5,(byte)'&'); //中间不能为空,不懂为啥,意思两个buffer中间要首尾相连,重叠都可以。
byteBuffer8.position(6); //pos=6
byteBuffer8.put(byteBuffer1); //现在pos>6,如要读,必须让pos=0
//---------------------------------------------------
FileChannel fileChannel2=FileChannel.open(path1,WRITE); //这个参数有很多种:APPEND 文件追加 READ;读
byteBuffer8.flip(); //bytebuffer8 put时是write,如要读完整时必须pos=0,读一部分,可以用pos设置
byteBuffer8.position(6); //如是读一部分,可以用pos设置
fileChannel2.write(byteBuffer8);
}
}
FileChannel 复制文件
//文件的建立,读写,追加,删除,复制 主要是参数的设置运用
import java.io.*;
import java.nio.channels.FileChannel;
import java.nio.file.Path;
import java.nio.file.Paths;
import static java.nio.file.StandardOpenOption.*; //OpenOption: APPEND 追加 READ 读 WRITE 写 CREATA:建立文件 CREATA_NEW 建立不存在的文件,如有报错
//DELETE_ON_CLOSE 关闭时删除。
//TRUNCATE_EXISTING 如果文件已经存在,并且打开 WRITE访问,则其长度将截断为0。
// DSYNC 要求将文件内容的每次更新都与底层存储设备同步写入。
//SYNC 要求将文件内容或元数据的每次更新都同步写入底层存储设备。
//SPARSE //稀疏文件
public class Khd3{
public static void main(String[] args) throws IOException {
Path path1= Paths.get("/home/wjs/1.txt");
Path path2=Paths.get("/home/wjs/3.txt");
FileChannel fileChannel1=FileChannel.open(path1,READ,WRITE);
FileChannel fileChannel2=FileChannel.open(path2,CREATE,READ,WRITE,SYNC); //参数可以多用
fileChannel1.transferTo(0,fileChannel1.size(),fileChannel2); //复制文件
}
}