import java.io.*;public class WriterDemo 
{
public static void main(String[] args) 
{
OutputStreamWriter osw=null;
PrintWriter pw=null;
BufferedWriter bw=null;
try{
osw=new OutputStreamWriter(new FileOutputStream("c:/write.txt",true),"GBK");
pw=new PrintWriter("c:/write.txt","GBK");
bw=new BufferedWriter(new FileWriter("c:/write.txt",true));
String str="9. 分别使用OutputStreamWriter、PrintWriter和BufferedWriter";
String str2="类将三行字符串写入到文本文件中,";
String str3="仔细分析有何差别"; String str4="youedkdkdkdkdlkaldalelrladl";
String str5="youedkdkdkdkdlkaldalelrladl";
String str6="youedkdkdkdkdlkaldalelrladl"; String str7="ssssssssssssssssssdtfwserewdd";
String str8="ssssssssssssssssssdtfwserewdd";
String str9="ssssssssssssssssssdtfwserewdd"; pw.println(str);
pw.println(str2);
pw.println(str3);

osw.write(str4+"\r\n");
osw.write(str5+"\r\n");
osw.write(str6+"\r\n");

bw.write(str7);
bw.newLine();
bw.write(str8);
bw.newLine();
bw.write(str9);
}
catch(UnsupportedEncodingException e){
e.printStackTrace();
}
catch(IOException e){
e.printStackTrace();
}
finally{
if(osw!=null)
try{
osw.close();
}catch(IOException e){} if(pw!=null)
pw.close(); if(bw!=null)
try{
bw.close();
}catch(IOException e){}
}
}
}(1)只有pw 和osw 写时  只写如了 pw
(2)只有osw和bw写时  两个都有写入
(3)三个都写入时 只有pw 和bw写入这是怎么回事 我看了API 没看明白 
这三个有什么区别  当然他们构造不同之类的 接受的参数不同 这些我已经看过API里看到了 还有别的吗
Thanks! 

解决方案 »

  1.   

    打个比方:就是 为了 传输 然后有很多方法, 有粗细的网线 可供选择,
    粗线套细线,再套更细的 就这样 这样的好处是你可以选择多样,但是 对于初学者,或者使用的人 感觉 构造函数太恶心 了看的不爽, 呵呵 不过这个 io包中各类 我们sun公司 编程专家们设计 的还是 不错,的确io设计很难 
      

  2.   

    建议楼主不要这样测试         pw.println(str);
                pw.println(str2);
                pw.println(str3);
                
                osw.write(str4+"\r\n");
                osw.write(str5+"\r\n");
                osw.write(str6+"\r\n");
                
                bw.write(str7);
                bw.newLine();
                bw.write(str8);
                bw.newLine();
                bw.write(str9);像这样,pw的流虽然写完了
    但是写完了的同时并没有立即关闭pw流
    等于说输出流是被pw占用的
    下面的同样道理,所以你这样测不出结果还有一个问题就是,往同一个文件里面写
    你这样即便是上一个写成功了
    下一次再写的时候,由于是写入同一个文件,是会把上个文件的内容覆盖掉的
    这样就看不出效果了
      

  3.   

    楼主这样再测试一下import java.io.*;public class WriterDemo 
    {
        public static void main(String[] args) 
        {
            OutputStreamWriter osw=null;
            PrintWriter pw=null;
            BufferedWriter bw=null;
            try{
                osw=new OutputStreamWriter(new FileOutputStream("c:/write1.txt",true),"GBK");
                pw=new PrintWriter("c:/write2.txt","GBK");
                bw=new BufferedWriter(new FileWriter("c:/write3.txt",true));
                String str="9.    分别使用OutputStreamWriter、PrintWriter和BufferedWriter";
                String str2="类将三行字符串写入到文本文件中,";
                String str3="仔细分析有何差别";            String str4="youedkdkdkdkdlkaldalelrladl";
                String str5="youedkdkdkdkdlkaldalelrladl";
                String str6="youedkdkdkdkdlkaldalelrladl";            String str7="ssssssssssssssssssdtfwserewdd";
                String str8="ssssssssssssssssssdtfwserewdd";
                String str9="ssssssssssssssssssdtfwserewdd";            pw.println(str);
                pw.println(str2);
                pw.println(str3);
                pw.flush();
                pw.close();
                
                osw.write(str4+"\r\n");
                osw.write(str5+"\r\n");
                osw.write(str6+"\r\n");
                osw.close();
                
                bw.write(str7);
                bw.newLine();
                bw.write(str8);
                bw.newLine();
                bw.write(str9);
                bw.flush();
                bw.close();            
            }
            catch(UnsupportedEncodingException e){
                e.printStackTrace();
            }
            catch(IOException e){
                e.printStackTrace();
            }
        }
    }
      

  4.   

    pw 被占用 那为什么bw还是写入了呢 
    还有你说下次写的时候会覆盖  那还是有两个一起被写入的情况啊 
    该怎么解释呢 
      

  5.   


    大概是因为pw 与 bw都属于同种流(字符流),而....
    哎,,,说不清。。
      

  6.   

    (1)只有pw 和osw 写时  只写如了 pw 
    你的pw是PrintWriter的流,这是个高级流,可以包装OutputStream和Writer的低级流
    而osw是OutputStreamWriter的流,属于低级流
    而你的代码里又是先写的pw,后写osw,所以在osw执行写入的时候,发现流已经被占用,于是写入失败(2)只有osw和bw写时  两个都有写入 
    bw也是个高级流,可以包装Writer(osw是OutputStreamWriter的流,OutputStreamWriter是继承Writer抽象类的),
    而且又是以向后追加的模式写入,所以没有问题(3)三个都写入时 只有pw 和bw写入 
    这个和你第一个问题相似
    你的顺序是
    pw->osw->bw,而pw->osw的时候,osw是失败的
    而bw又是追加模式写入,所以没问题不知道楼主明白了没有
      

  7.   

    我刚才说的覆盖是这个样子的如果你把osw,pw的顺序换一下
    就是先写osw,再写pw结果是只看到pw,bw的输出
    看不到osw的内容了其实osw也写入了
    只是因为随后用pw来写的时候
    因为pw没有追加模式,所以就重写,把osw写的内容给覆盖了
      

  8.   

                osw=new OutputStreamWriter(new FileOutputStream("c:/write.txt",true),"GBK");
                pw=new PrintWriter("c:/write.txt","GBK");
                bw=new BufferedWriter(new FileWriter("c:/write.txt",true));同时对一个文件操作吗?呵呵!你真强!
      

  9.   

    Buffered的作用,就是缓冲,也就是数据只有在flush或者close得时候才会写入。
      

  10.   


    我自己又试了一下  (1)只说 osw 和 pw
    还是这个顺序 先pw 后osw 然后我在关闭流的时候先关闭pw后关闭osw 这样 osw就可以写入了
    那是不是应该说 最主要是流被占用的问题 而似乎不是高级低级的问题(思考中)
      

  11.   


    不是。如果是流被占用的话
    你上面三个同时写,无论如何只能第一个的得到输出,对吗
    如果按照流被占用的理论的话所以,还是有高级流和低级流的区别
    高级流写的时候先放到缓存中
    这样就不会因为流被占用而写不成
    就像老紫竹说的,flush,close的时候才写出去当然,正式的做法没有像楼主这样的,呵呵
    开着3个流往同一个文件里写
      

  12.   

    看了看源码
    这三个类都继承于抽象类Writer
    而且不管是pw.println() osw.write() bw.write()
    实际上调用的都是父类Writer的方法public void write(String str, int off, int len)
    也就是说 全部调用的是同一个方法
    就是下面这个方法 这个方法是同步的    public void write(String str, int off, int len) throws IOException {
    synchronized (lock) {
        char cbuf[];
        if (len <= writeBufferSize) {
    if (writeBuffer == null) {
        writeBuffer = new char[writeBufferSize];
    }
    cbuf = writeBuffer;
        } else { // Don't permanently allocate very large buffers.
    cbuf = new char[len];
        }
        str.getChars(off, (off + len), cbuf, 0);
        write(cbuf, 0, len);
    }
        }
    在构造PrintWriter的时候 实际内部调用了另一个构造函数
    就是这个    public PrintWriter(String fileName) throws FileNotFoundException {
    this(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(fileName))),
         false);
        }也就是说PrintWriter用的是BufferedWriter的write()方法 而这个方法又调用父类Writer的方法
    OutputStreamWriter的write()方法直接调用父类的方法
    所以都是用的同一个方法
      

  13.   

    又继续看了看源码因为Writer里的write(cbuf, 0, len)是个抽象方法; 所以还是有些区别实际上他们调用的这个write(cbuf, 0, len)的实现 都是OutputStreamWriter里的实现
    但是在BufferedWriter里做了点扩展 有了自动刷新缓冲区的功能
    其他大概都差不多
      

  14.   


    认同,Buffered顾名思义就是缓冲。属于包装流。
      

  15.   

    “Buffered的作用,就是缓冲,也就是数据只有在flush或者close得时候才会写入。 ”这句话也可以说正确 flush不一定是手动 也可能是自动当要写入的数据大于它默认的容量 它就会自动flush但不是只有Buffered能缓冲 其实其他流也是一样 也能自动flush
      

  16.   

    你去写个Buffered的包装流,你试试不用.close() 和 .flush看内容会不会写入文件?
      

  17.   


    会!当要写入的数据大于它默认的容量 就会自动flush  所有流都一样我已经做过很多次测试 看了很多遍源码Buffered的缓冲 实际上缓冲的是N个write()的内容而其他流的缓冲 缓冲的是1个write()或print()的内容
      

  18.   

    虽然这样写是不符合常规的  但我还是写下 我自己的看法
    (1)三个流写似乎不是流占用的问题 他们是三个不同写入流
    如果 我在每一写入后面加一个flush() 那所有的都会写入
    (2)如果每次写完都没有flush,那么就会在close时执行flush功能
    先关闭哪个就先写入哪个的值 这就造成了不一样的输出结果 当然PrintWriter是会覆盖的 
    而我发帖时写的有的osw没有写入  只是因为它的值被覆盖了 所以我以为它没有输入
    (3)而15楼所说的高级流和低级流 我还是没有理解透彻 如果说低级流没有缓存 就会占流 那么就算先写osw后面的也还是会输出啊 比没有被占用  我觉得他们是三个流 而不是一个流 
      

  19.   

    情况和楼主自己最后的回复差不多,当没有设置自动提交时,在楼主的代码中这三个流都是在close()的时候才写入文件,所以顺序应该是osw>pw>bw,楼主的代码在创建ows和bw时都带了参数true,造成了这两个流在写文件时只是往文件末尾添加内容,而pw则不同,在pw=new PrintWriter("c:/write.txt","GBK")一句执行时,文件的内容会被清空,而在pw.close()执行时,pw也会把文件清空,然后把自己的内容写进文件,这就是为什么osw总是写不进去的原因,至于楼主说的“我在每一写入后面加一个flush() 那所有的都会写入”是因为你加了flush的话,流就会在flush()的时候写入文件,写入的顺序就变成了pw>osw>bw,而后两个流都不覆盖,所以都写进去了,但是当你再次执行这个程序的话pw=new PrintWriter("c:/write.txt","GBK")又会把文件清空,所以文件内容没有变化。
      

  20.   

    也是因为PrintWriter和BufferedWriter的问题看过来的.BufferedWriter有8192字符的空间呢.真正做起来也没有等到要给它自动flush()了吧