【问题标题】:Read/Write using FileChannel and FileInput/OutputStream-Java使用 FileChannel 和 FileInput/OutputStream-Java 进行读/写
【发布时间】:2015-11-09 12:28:18
【问题描述】:

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

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) {}
    }
}

【问题讨论】:

    标签: java io filechannel


    【解决方案1】:

    我会做这样的事情,

    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);
        }
    }
    

    【讨论】:

    • transferTo() 需要循环调用。不能保证在一次操作中完成整个传输。
    【解决方案2】:
    while(inChannel.read(buffer) > 0) {
        FileChannel outChannel=new FileOutputStream("sss1.jpg",true).getChannel();
        outChannel.write(buffer);
    }
    
    1. 每次循环时,您都会创建一个新文件。好的,您正在追加,但这效率不高,而且您永远不会关闭它。
    2. 您忘记翻转和压缩缓冲区。

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

    【讨论】:

    • 谢谢。缓冲区是字节缓冲区,但翻转是类缓冲区的方法。它与 bytebuffer 类配合得好吗?甚至可能吗?你能解释一下吗?
    • @Struse 查看 javadoc 和/或源代码。 ByteBufferBuffer 之间存在关系。先看类签名。
    • @djeikyb 我看到了他们。抱歉,我错过了底部缓冲区类中列出的继承方法。还是谢谢你
    【解决方案3】:

    您绝对应该关注EJP'sAchintha Gunasekara's 的答案。你做的很多事情都很糟糕(例如,创建许多输出通道,不使用FileChannel::open 等)。但我相信根本问题不是打电话给flip。来自javadoc

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

     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
    

    这个方法经常和compact方法一起使用 将数据从一个地方传输到另一个地方。

    【讨论】:

    • 在阻塞模式下通过> 0 检查没有错:read() 不能返回零,除非缓冲区中没有空间,这将是您不想旋转的编程错误-循环。使用Files 对象不是强制性的。
    • @EJP 说的很对,没想到,谢谢。我不认为它本身是一个错误,更多的是javadoc说-1表示流结束,所以应该使用它。但现在我会使用 > 0 并考虑您的评论。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-30
    • 1970-01-01
    • 2013-03-14
    • 2019-04-18
    • 1970-01-01
    • 2012-04-30
    • 1970-01-01
    相关资源
    最近更新 更多