在BufferedInputStream和BufferedOutputStream类中,为什么在写之前,读取不好.......?

时间:2012-05-24 08:38:31

标签: io

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class BufferedInputOutputStreamExample
{
    public static void main(String[] args) {
        try{
        BufferedInputStreamExample bisx=new BufferedInputStreamExample();
        BufferedInputStream bis=bisx.inputMethod();

        BufferedOutputStreamExample bosx=new BufferedOutputStreamExample();
        bosx.outputMethod(bis);
        }
        catch(FileNotFoundException fnf)
        {
            System.out.println("Sorry--------File not exists");
        }
        catch(IOException io)
        {
            System.out.println("IOException   ---:"+io.getMessage());
        }


    }
}
class BufferedInputStreamExample
{
    BufferedInputStream bis=null;
    BufferedInputStream  inputMethod()throws FileNotFoundException,IOException
    {
            FileInputStream fin=new FileInputStream("C:/e-SDK-4.1-win32-x86_64 (1)/RahulExample/src/Test.java");
            bis=new BufferedInputStream(fin); 
            int c;
            while((c=bis.read())!=-1)
                System.out.print((char)c);
            System.out.println();

        return bis;
    }
}
class BufferedOutputStreamExample
{
    BufferedOutputStream bos=null;
    int outputMethod(BufferedInputStream bis)throws IOException,FileNotFoundException
    {
        bos=new BufferedOutputStream(new FileOutputStream("C:/varun.txt"));

        int c;

        while((c=bis.read())!=-1){
            bos.write(c);
        }
        bis.close();
        bos.close();
        System.out.println("File created.............");
        return 1;
    }
}

在这个程序中我们通过使用bufferedinputstream从文件中读取内容,当我想使用bufferedoutputstream在其varun.txt文件中编写Test.java文件的内容时,它的创建文件却没有在varun.txt中写任何东西.if我们将Test.java中的内容写入varun.txt而不读取它创建文件并写两个。为什么这样做。

1 个答案:

答案 0 :(得分:1)

当您致电bisx.inputMethod()时,您正在阅读信息流以便打印其内容。事情是,你不想那样做。读取流消耗它,因此您返回的流已经结束,没有任何东西可供阅读。

如果要打印出文件的所有内容,然后将其全部写入另一个文件,那就是两个单独的操作。根据文件的大小,它需要读取文件两次 - 使用两个不同的输入流 - 或者在内存中缓存整个文件。

相反,如果您只想在复制时显示文件的内容(这看起来像是真正的目标),那么您有几个值得选择的选项......

  • 您可以在写入输出文件时outputMethod打印数据。在短期内,这可能是最简单的解决方案。当然,您还会删除inputMethod中读取流的代码。

  • 您可以子类FilterInputStreamFilterOutputStream 来定义一个流,无论何时它(分别)读取或写入数据,都会对其执行其他操作。它可以,例如......

    • 将数据打印到System.out非常简单但非常严格。我越是考虑它......嗯。

    • 将数据复制到另一个任意输出流。这将更加灵活;例如,您可以发送到日志文件或其他东西。它需要的System.out.print代码只需要很少的额外代码,因此它通常会在为你们的部门赢得胜利。

    • 触发其他对象可以订阅的事件。这可以给你几乎无限的灵活性(因为订阅者不再被迫关心流),但也可能相当复杂。 (你基本上需要添加一个事件/订阅API。)对于像这样的小项目来说,这通常是过度的。

    请注意,如果你走这条路,你应该考虑重构事物,以便对象的构造函数采用流而不是创建流。这样,main可以决定输出是否发生以及输出的位置,而其他对象甚至不必关心。他们可以完成他们的工作,将流视为常规的旧InputStreams和OutputStreams,并且传入的流确定还会发生什么。

(顺便说一句:为了专注于主要问题,我半已经忽略了你通过强制转换为char而“解码”的事实。这可能不会忠实地再现内容文件,除非你知道内容是ASCII字符的事实。我认为输出是一个调试的东西,所以这不值得长期咆哮...但是知道在一般情况下,它可能会导致问题。)