使用FileChannel和FileInput/OutputStream Java进行读/写

使用FileChannel和FileInput/OutputStream Java进行读/写,java,io,filechannel,Java,Io,Filechannel,我不熟悉文件处理。我尝试使用fileinputstream和文件通道读取文件。我在下面的代码中找不到bug。它已成功运行,但尚未传输文件。新文件是用零字节创建的。请看一下代码并检查出了什么问题 public class FileTest { public static void main(String[] args) { try { File file = new File("sss.jpg"); FileCh

我不熟悉文件处理。我尝试使用fileinputstream和文件通道读取文件。我在下面的代码中找不到bug。它已成功运行,但尚未传输文件。新文件是用零字节创建的。请看一下代码并检查出了什么问题

public class FileTest
{
    public static void main(String[] args)
    {   
        try {
            File file = new File("sss.jpg");
            FileChannel inChannel=new FileInputStream(file).getChannel();
            //FileChannel inChannel = in.getChannel();
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            while(inChannel.read(buffer) > 0) {
                FileChannel outChannel=new FileOutputStream("sss1.jpg",true).getChannel();
                outChannel.write(buffer);
            }
        }
        catch(IOException ex) {}
    }
}

我会这样做

import java.io.IOException;
import java.nio.channels.FileChannel;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;

public class Test_Stuff {

    public static void main(String[] args) throws FileNotFoundException, IOException {

        String thisFile = "Test.java";
        FileInputStream source = new FileInputStream(thisFile);
        FileOutputStream destination = new FileOutputStream("Output.java");
        FileChannel sourceFileChannel = source.getChannel();
        FileChannel destinationFileChannel = destination.getChannel();
        long size = sourceFileChannel.size();
        sourceFileChannel.transferTo(0, size, destinationFileChannel);
    }
}

你应该完全听从或回答。您在多方面做得很差(例如,创建了许多输出通道,没有使用等)。但我相信根本的问题不是打电话。从:

翻转此缓冲区。将限制设置为当前位置,然后 该位置设置为零。如果标记已定义,则为 丢弃的。在一系列通道读取或放置操作之后,调用 此方法用于准备通道写入或相对get序列 操作。例如:

 buf.put(magic);    // Prepend header
 in.read(buf);      // Read data into rest of buffer
 buf.flip();        // Flip buffer
 out.write(buf);    // Write header + data to channel
在以下情况下,此方法通常与紧凑方法结合使用: 将数据从一个地方传输到另一个地方

  • 每次循环中都会创建一个新文件。好的,您正在追加,但这不是有效的,而且您永远不会关闭它
  • 你忘了翻转和压缩缓冲区

    FileChannel outChannel = new FileOutputStream("sss1.jpg").getChannel();
    while(inChannel.read(buffer) > 0) {
        buffer.flip();
        outChannel.write(buffer);
        buffer.compact();
    }
    outChannel.close();
    inChannel.close();
    

  • transferTo()
    需要在循环中调用。不能保证在单个操作中完成整个传输。在阻塞模式下通过
    >0
    进行检查没有错:
    read()
    不能返回零,除非缓冲区中没有空间,否则这将是一个编程错误,您不希望旋转循环。使用
    文件
    对象不是强制性的。@EJP这是一个公平的观点,我没有想到,谢谢。我并不认为这是一个错误,更确切地说,javadoc说
    -1
    表示流结束,所以应该使用它。但是现在我将使用
    >0
    并记住您的评论。谢谢。缓冲区是bytebuffer,但flip是类缓冲区的方法。它和bytebuffer的课程配合得好吗?。有可能吗?你能解释一下吗?@Struse看看javadoc和/或源代码。
    ByteBuffer
    Buffer
    之间存在关系。先看类签名。@djeikyb我看到了。很抱歉,我错过了底部列出的从缓冲区类继承的方法。无论如何谢谢你
    FileChannel outChannel = new FileOutputStream("sss1.jpg").getChannel();
    while(inChannel.read(buffer) > 0) {
        buffer.flip();
        outChannel.write(buffer);
        buffer.compact();
    }
    outChannel.close();
    inChannel.close();