Java 以较小长度的字节缓冲区块数读取和写入文件

Java 以较小长度的字节缓冲区块数读取和写入文件,java,bytebuffer,filechannel,Java,Bytebuffer,Filechannel,我正在尝试读取固定长度的ByteBuffer块中的文件,然后将其存储到ByteBuffer列表中,然后在执行一些操作后,按顺序读取这些ByteBuffer块以重建文件。问题是,在写入输出文件时,通道位置并没有增加。 我不想使用字节数组,因为它们是固定长度的,并且文件重建不能正常工作。 所以我想知道如何增加文件写入通道位置的大小,或者用任何其他方法来做这个操作。样本代码将不胜感激。 这是我的代码片段 file = new File(fileName); // hello.txt - 20 MB

我正在尝试读取固定长度的
ByteBuffer
块中的文件,然后将其存储到
ByteBuffer
列表中,然后在执行一些操作后,按顺序读取这些
ByteBuffer
块以重建文件。问题是,在写入输出文件时,通道位置并没有增加。 我不想使用字节数组,因为它们是固定长度的,并且文件重建不能正常工作。 所以我想知道如何增加文件写入通道位置的大小,或者用任何其他方法来做这个操作。样本代码将不胜感激。 这是我的代码片段

file = new File(fileName);  // hello.txt - 20 MB size
fis = new FileInputStream(file);
inChannel = fis.getChannel();
double maxChunkSequenceNoFloat = ((int)inChannel.size()) / chunkSize;
int maxChunkSequenceNo = 1;
if(maxChunkSequenceNoFloat%10 > 0) {
    maxChunkSequenceNo = ((int)maxChunkSequenceNoFloat)+1;
} else if(maxChunkSequenceNoFloat%10 < 0) {
    maxChunkSequenceNo = 1;
} else {
    maxChunkSequenceNo = (int)maxChunkSequenceNoFloat;
}
maxChunkSequenceNo = (maxChunkSequenceNo == 0) ? 1 : maxChunkSequenceNo;            
ByteBuffer buffer = ByteBuffer.allocate(chunkSize);
buffer.clear();

while(inChannel.read(buffer) > 0) {
    buffer.flip();
    bufferList.add(buffer);
    buffer.clear();
    chunkSequenceNo++;
}
maxChunkSequenceNo = chunkSequenceNo;

// write
File file1 = new File("hello2.txt") ; 
buffer.clear();
FileOutputStream fos = new FileOutputStream(file1);
FileChannel outChannel = fos.getChannel();
chunkSequenceNo = 1;
for(ByteBuffer test : bufferList) {
    writeByteCount += outChannel.write(test);
    //outChannel.position() += writeByteCount;'
    System.out.println("main - channelPosition: "+outChannel.position()
                        +" tempBuffer.Position: "+test.position()
                        +" limit: "+test.limit()
                        +" remaining: "+test.remaining()
                        +" capacity: "+test.capacity());              
}
BufferedReader br = new BufferedReader(new FileReader(file1));
String line = null;
while ((line = br.readLine()) != null) {
    System.out.println(line);
}
outChannel.close();
fos.close();
file=新文件(文件名);//hello.txt-20 MB大小
fis=新文件输入流(文件);
inChannel=fis.getChannel();
double maxChunkSequenceNoFloat=((int)inChannel.size())/chunkSize;
int maxChunkSequenceNo=1;
如果(maxChunkSequenceNoFloat%10>0){
maxChunkSequenceNo=((int)maxChunkSequenceNoFloat)+1;
}else if(maxChunkSequenceNoFloat%10<0){
maxChunkSequenceNo=1;
}否则{
maxChunkSequenceNo=(int)maxChunkSequenceNoFloat;
}
maxChunkSequenceNo=(maxChunkSequenceNo==0)?1:maxChunkSequenceNo;
ByteBuffer缓冲区=ByteBuffer.allocate(chunkSize);
buffer.clear();
而(在通道读取(缓冲区)>0){
flip();
bufferList.add(buffer);
buffer.clear();
chunkSequenceNo++;
}
maxChunkSequenceNo=chunkSequenceNo;
//写
File file1=新文件(“hello2.txt”);
buffer.clear();
FileOutputStream fos=新的FileOutputStream(file1);
FileChannel outChannel=fos.getChannel();
n=1;
用于(ByteBuffer测试:bufferList){
writeByteCount+=输出通道写入(测试);
//outChannel.position()+=writeByteCount;'
System.out.println(“主通道位置:+outChannel.position()
+tempBuffer.Position:“+test.Position()
+“限制:“+test.limit()
+“剩余:”+测试剩余()
+“容量:“+test.capacity());
}
BufferedReader br=新的BufferedReader(新文件读取器(文件1));
字符串行=null;
而((line=br.readLine())!=null){
系统输出打印项次(行);
}
outChannel.close();
fos.close();

Bytebuffer位置正确,但outChannel位置保持在1048,即块大小。

以下内容确实会根据请求维护ByteBuffers列表

String fileName = "hello.txt";
final int chunkSize = 256;
List<ByteBuffer> bufferList = new ArrayList<>();
Path path = Paths.get(fileName);
try (SeekableByteChannel inChannel = Files.newByteChannel(path,
        EnumSet.of(StandardOpenOption.READ))) {
    long size = inChannel.size();
    while (size > 0) {
        ByteBuffer buffer = ByteBuffer.allocate(chunkSize);

        int nread = inChannel.read(buffer);
        if (nread <= 0) {
            break;
        }
        buffer.flip();
        bufferList.add(buffer);
        size -= nread;
    }
}

// write
Path file1 = Paths.get("hello2.txt") ;
try (SeekableByteChannel outChannel = Files.newByteChannel(file1,
        EnumSet.of(StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE))) {
    for (ByteBuffer buffer : bufferList) {
        int nwritten = outChannel.write(buffer);
    }
}
String fileName=“hello.txt”;
最终int chunkSize=256;
List bufferList=new ArrayList();
Path Path=Path.get(文件名);
try(参见通道中的KableByteChannel=Files.newByteChannel(路径,
枚举集(StandardOpenOption.READ))){
长尺寸=英寸通道尺寸();
而(大小>0){
ByteBuffer缓冲区=ByteBuffer.allocate(chunkSize);
int nread=inChannel.read(缓冲区);

如果(nread以下内容确实会按照要求维护ByteBuffers列表

String fileName = "hello.txt";
final int chunkSize = 256;
List<ByteBuffer> bufferList = new ArrayList<>();
Path path = Paths.get(fileName);
try (SeekableByteChannel inChannel = Files.newByteChannel(path,
        EnumSet.of(StandardOpenOption.READ))) {
    long size = inChannel.size();
    while (size > 0) {
        ByteBuffer buffer = ByteBuffer.allocate(chunkSize);

        int nread = inChannel.read(buffer);
        if (nread <= 0) {
            break;
        }
        buffer.flip();
        bufferList.add(buffer);
        size -= nread;
    }
}

// write
Path file1 = Paths.get("hello2.txt") ;
try (SeekableByteChannel outChannel = Files.newByteChannel(file1,
        EnumSet.of(StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE))) {
    for (ByteBuffer buffer : bufferList) {
        int nwritten = outChannel.write(buffer);
    }
}
String fileName=“hello.txt”;
最终int chunkSize=256;
List bufferList=new ArrayList();
Path Path=Path.get(文件名);
try(参见通道中的KableByteChannel=Files.newByteChannel(路径,
枚举集(StandardOpenOption.READ))){
长尺寸=英寸通道尺寸();
而(大小>0){
ByteBuffer缓冲区=ByteBuffer.allocate(chunkSize);
int nread=inChannel.read(缓冲区);

如果(nread)保持简单且(部分)使用字节数组。FileReader使用默认的平台编码。这不仅与我的代码有关,而且处理我的数据的类需要ByteBuffers,因此正如我在问题中明确指出的,直接使用字节数组是不可能的。您只使用一个缓冲区,因此您的代码根本不符合您的描述。请保持简单(部分)使用字节数组。FileReader使用默认的平台编码。这不仅是关于我的代码,而且处理我的数据的类需要ByteBuffers,所以正如我在问题中明确指出的,直接使用字节数组是不可能的。您只使用了一个缓冲区,所以您的代码根本不符合您的描述。谢谢您的工作。我认为bytebuffer无法重用,必须再次实例化。@andi99使用Buffer的倒带和清除来重用缓冲区。谢谢你的工作。我认为bytebuffer不能重用,必须再次实例化。@andi99使用Buffer的倒带和清除来重用缓冲区。