outputStream是个虚类阿,具体的是现在子类中实现了

解决方案 »

  1.   

    * @version 1.58, 02/06/02
     * @see     java.io.File
     * @see     java.io.FileDescriptor
     * @see     java.io.FileOutputStream
     * @since   JDK1.0
     */
    public
    class FileInputStream extends InputStream
    {
        /* File Descriptor - handle to the open file */
        private FileDescriptor fd;    private FileChannel channel = null;    /**
         * Creates a <code>FileInputStream</code> by
         * opening a connection to an actual file,
         * the file named by the path name <code>name</code>
         * in the file system.  A new <code>FileDescriptor</code>
         * object is created to represent this file
         * connection.
         * <p>
         * First, if there is a security
         * manager, its <code>checkRead</code> method
         * is called with the <code>name</code> argument
         * as its argument.
         * <p>
         * If the named file does not exist, is a directory rather than a regular
         * file, or for some other reason cannot be opened for reading then a
         * <code>FileNotFoundException</code> is thrown.
         *
         * @param      name   the system-dependent file name.
         * @exception  FileNotFoundException  if the file does not exist,
         *                   is a directory rather than a regular file,
         *                   or for some other reason cannot be opened for
         *                   reading.
         * @exception  SecurityException      if a security manager exists and its
         *               <code>checkRead</code> method denies read access
         *               to the file.
         * @see        java.lang.SecurityManager#checkRead(java.lang.String)
         */
        public FileInputStream(String name) throws FileNotFoundException {
            this(name != null ? new File(name) : null);
        }    /**
         * Creates a <code>FileInputStream</code> by
         * opening a connection to an actual file,
         * the file named by the <code>File</code>
         * object <code>file</code> in the file system.
         * A new <code>FileDescriptor</code> object
         * is created to represent this file connection.
         * <p>
         * First, if there is a security manager,
         * its <code>checkRead</code> method  is called
         * with the path represented by the <code>file</code>
         * argument as its argument.
         * <p>
         * If the named file does not exist, is a directory rather than a regular
         * file, or for some other reason cannot be opened for reading then a
         * <code>FileNotFoundException</code> is thrown.
         *
         * @param      file   the file to be opened for reading.
         * @exception  FileNotFoundException  if the file does not exist,
         *                   is a directory rather than a regular file,
         *                   or for some other reason cannot be opened for
         *                   reading.
         * @exception  SecurityException      if a security manager exists and its
         *               <code>checkRead</code> method denies read access to the file.
         * @see        java.io.File#getPath()
         * @see        java.lang.SecurityManager#checkRead(java.lang.String)
         */
        public FileInputStream(File file) throws FileNotFoundException {
    String name = (file != null ? file.getPath() : null);
    SecurityManager security = System.getSecurityManager();
    if (security != null) {
        security.checkRead(name);
    }
    fd = new FileDescriptor();
    open(name);
        }    /**
         * Creates a <code>FileInputStream</code> by using the file descriptor
         * <code>fdObj</code>, which represents an existing connection to an
         * actual file in the file system.
         * <p>
         * If there is a security manager, its <code>checkRead</code> method is
         * called with the file descriptor <code>fdObj</code> as its argument to
         * see if it's ok to read the file descriptor. If read access is denied
         * to the file descriptor a <code>SecurityException</code> is thrown.
         * <p>
         * If <code>fdObj</code> is null then a <code>NullPointerException</code>
         * is thrown.
         *
         * @param      fdObj   the file descriptor to be opened for reading.
         * @throws     SecurityException      if a security manager exists and its
         *                 <code>checkRead</code> method denies read access to the
         *                 file descriptor.
         * @see        SecurityManager#checkRead(java.io.FileDescriptor)
         */
        public FileInputStream(FileDescriptor fdObj) {
    SecurityManager security = System.getSecurityManager();
    if (fdObj == null) {
        throw new NullPointerException();
    }
    if (security != null) {
        security.checkRead(fdObj);
    }
    fd = fdObj;
        }    /**
         * Opens the specified file for reading.
         * @param name the name of the file
         */
        private native void open(String name) throws FileNotFoundException;    /**
         * Reads a byte of data from this input stream. This method blocks
         * if no input is yet available.
         *
         * @return     the next byte of data, or <code>-1</code> if the end of the
         *             file is reached.
         * @exception  IOException  if an I/O error occurs.
         */
        public native int read() throws IOException;
      

  2.   

    /**
         * Flushes this buffered output stream. This forces any buffered 
         * output bytes to be written out to the underlying output stream. 
         *
         * @exception  IOException  if an I/O error occurs.
         * @see        java.io.FilterOutputStream#out
         */
        public synchronized void flush() throws IOException {
            flushBuffer();
    out.flush();
        }
    这是BufferedOutputStream里面覆写的flush()
      

  3.   

    你没看见它是怎么覆盖的????
    public synchronized void flush() throws IOException {
            flushBuffer();
    out.flush();
    }
    ???out.flush()
    还不是直接调的java.io.OutputStream类的flush()public BufferedOutputStream(OutputStream out) {
    this(out, 512);
    }
    这是BufferedOutputStream的构造方法
      

  4.   

    好像你怎么封装
    最后都会调到java.io.OutputStream类的flush()
      

  5.   

    强,果然高手。友情Up
    将“流氓无赖”测试到底
    ——始于2003年7月
    树欲止而风不停,行云流水匆匆去;
    树梢蚂蚱凭空望,江边浪花碎巨石; 支持“流金岁月”!!!
    发送框,少个“右键菜单,选择粘贴”;
    ——2003年12月24日am^@^
      

  6.   

    你没看见它是怎么覆盖的????
    public synchronized void flush() throws IOException {
            flushBuffer();
    out.flush();
    }
    ???out.flush()
    还不是直接调的java.io.OutputStream类的flush()public BufferedOutputStream(OutputStream out) {
    this(out, 512);
    }
    这是BufferedOutputStream的构造方法________________________________________________________________
    老大,你怎么忘了OutputStream是个abstract class吗?是调OutputStream,但是传进来的具体的对象你知道是什么吗?可能是FileOutputStream,也可能是ObjectOutputStream或者其他的啊,但肯定不是OutputStream的实例对吧:)
      

  7.   

    哦,看上去是直接调用了父类OutputStream的flush()呀.
    怎么回事?
      

  8.   

    老大!BufferedOutputStream.flush()里调用的是out.flush(),不是super.flush();如果实际的out对象没有覆盖flush()方法,当然是调用OuputStream.flush(),会么都不做。如果实际的out对象覆盖了flush()方法,那就是调用out中的具体的flush()实现了。请再仔细看一下OutputStream的flush方法说明:
    public void flush()
               throws IOException
        Flushes this output stream and forces any buffered output bytes to be written out. The general contract of flush is that calling it is an indication that, if any bytes previously written have been buffered by the implementation of the output stream, such bytes should immediately be written to their intended destination. 
        The flush method of OutputStream does nothing.
    注意"by the implementation of the output stream"。
      

  9.   

    试一下:FileOutputStream fos = new FileOutputStream("test");
    OutputStream os = new BufferedOutputStream(fos, 512);
    os.write('a');
    os.write('b');
    fos.close();和:FileOutputStream fos = new FileOutputStream("test");
    OutputStream os = new BufferedOutputStream(fos, 512);
    os.write('a');
    os.write('b');
    os.flush();
    fos.close();的区别。
      

  10.   

    不可忽视的一点,不是buffer的流,没有必要flush。
      

  11.   

    flush()到底起什么作用哦?
    哪位大大能说一下~
      

  12.   

    嘿,哥几个怎么在这个问题上争论了半天. :)
    mymoto(忽忽)最早贴出来的就已经是正解了.
    public synchronized void flush() throws IOException {
        flushBuffer();
        out.flush();
    }
    这个当然是覆盖了,没有flushBuffer的调用那行.而调用被装饰的out的flush方法也是必须的,你怎么知道被装饰的out是个什么对象?
    这里是decorator的典型例子,这样的实现是很正常的.
      

  13.   

    Flush()是在数据量较大时使用,可以提高系统的效率。如果没有强行清空缓存数据,只有当缓存数据满时,才会打包发送出去。
      

  14.   

    flush用于将缓冲区的数据立即写入,好像在应该由子类来实现,而且不同的JRE的实现应该不同。我感觉即使是在native级写入磁盘,也不能保证直接写入介质可能还在磁盘的缓冲区里面呢。linux和unix的系统API有直接跳过缓冲区写硬盘的机制。windows下好像也有类似功能。
    flush应该是空的。
      

  15.   

    个人看法:
    java.io.OutputStream
    是一个抽象的类,向flush这样的方法,必须子类完成这个方法
    而java.io.FilterOutputStream和java.io.BufferedOutputStream
    都是基于装饰模式的子类,而不是具体实现的子类。
    换句话说,每个java.io.FilterOutputStream和java.io.BufferedOutputStream
    里面都会有一个OutputStream类型的变量out,FilterOutputStream/BufferedOutputStream
    只管心在调用变量out之前应当干些什么,当他们需要完成的工作完成后,在调用
    out的具体方法。建议仔细的看完装饰模式以后,再好好的分析!一定会有很好的解释!祝你好运!
      

  16.   

    大家都没仔细看  都是凭空说的我可是调试了socket的OutputStream最终就是封装的OutputStream
    源代码都在   大家不会仔细看看难到我会菜到连里氏换原则和装饰模式都不知道的地步我看到好些人都说socket的outputstream要flush的  否则数据可能发布出去
    我就去看了看源码    发现事实跟不是那么回事   就是贴子开头我说的各位兄弟姐妹们   没有研究可不要乱说哦
      

  17.   

    cbhyk() ( ) 
    不可忽视的一点,不是buffer的流,没有必要flush。如果是这样的话我总觉得有违设计模式 集体那条我也说不准  最小接口原则???
    只有这个BufferedOutputStream类用得着的话 
    没必要把这个方法提到所有输出类的父类中
      

  18.   

    public synchronized void flush() throws IOException {
            flushBuffer();
    out.flush();
    }
    _______________________________________________________________
    这里的out应该不会再是BufferedOutputStream,否则会有递归嫌疑(out.flush),其他代码还没看,大家讨论吧
      

  19.   

    out.flush(); 比如说out是一个FileOutputStream类的对象
    那么他调用的是FileOutputStream类的flush方法
    你看看FileOutputStream的源文件里有这个方法么
    他是调用了FileOutputStream的父类  也就是OutputStream类的flush方法你可以说我的out是BufferedOutputStream类的对象  
    你看看BufferedOutputStream的构造方法  他是用输入流构造的
    终归还以FileOutputStream这类的东西  最后调用的还是OutputStream类的flush方法我说得还清楚吧
      

  20.   

    FileOutputStream和SocketOutputStream都是没的buffer的,所以不需要实现flush(),所以一般在使用它们的时候用BufferedOutputStream装饰,来获得buffer的能力。    ObjectOutputStream也是覆盖了flush()方法的。    你的意思是,flush()不是所有OutputStream都需要的行为,不该出现在OutputStream抽象类里面?如果flush()不放到OutputStream里面,那Writer里面要不要呢?如果Writer里面需要,那该如何实现?    如果按...原则来设计IO库的话,可能应该定义一个interface Buffered,该interface包含flush()方法,BufferedOutputStream、PrintWriter、ObjectOutputStream都实现Buffered,在用到OutputStream和Writer的地方这样写(?):
      if(out instanceof Buffered)
            ((Buffered) out).flush();
    以及:
        if(writer instanceof Buffered)
            ((Buffered) writer).flush();    也许flush()方法是为了IO库方便使用才放到OutputStream和Writer里面的吧。    同理,Object类里面的wait(),notify(),hashCode()是不是也不要呢?
      

  21.   

    楼上的写的和我想地一样
    就应该这么实现  haha  要是这么设计  用错的人应该很少
    这个破方法用在基类了   错用的人的数量可能是非常庞大的   我肯定hoho
    看看楼上的回答  就知道了  说的靠边的只有一两位你没看见socket出现错误了   
    好多解答的人   
    说socket容易产生错误  得用flush方法
    他们不知道 这完全是错误的   还有PrintWriter和BufferedOutputStream的实现一样
    最后都掉用了OutputStream的flush方法这是源代码看看
    public void flush() {
    try {
        synchronized (lock) {
    ensureOpen();
    out.flush();//这里还是FileOutputStream这类的flush方法
        }
    }
    catch (IOException x) {
        trouble = true;
    }
        }
    应为有缓存的OutputStream装饰的是没缓存的OutputStream  
    最终调用的还是没有缓存OutputStream这类的flush方法 
    既然是个空方法  这不是脱了裤子放屁么同理,Object类里面的wait(),notify(),hashCode()是不是也不要呢?
    这个我就不敢苟同了   每个对象都有对象锁  
    所以wait()和notify()放在object里也不无不可  
    hashCode()也算是对象的标示 也没什么问题呀java已经有了serializable接口   再有个flushable接口有什么不可以的
      

  22.   

    父类应该是所有子类共性的抽象比如有个动物类  
    有的动物会行走  把walk放到动物类中
    有的动物会游泳  把swim放到动物类中然后让会游泳不会行走的动物的walk方法设为空方法
    然后让会行走不会游泳的动物的swim方法设为空方法然后就成类动物类里就有行走又有游泳的方法
    然后想让他游泳就游泳  想让他走路就走路  不挺好么好像不是很好吧
      

  23.   

    flush 不是让OutputStream调用的
    而是应该用在Writer中吧
      

  24.   

    TO jokerjava(冷血):你这样的抽象是不合理的.既然父类应该是所有子类共性的抽象,那就不应该把walk和swim放到父类中,而可能是 move .
    walk和swim并不是所有子类的共性.有的动物move实现采用walk的方式,有的动物采用swim来实现move. etc.
      

  25.   

    如此的话,加一个Synchronizable、Hashable也未尝不可啊
      

  26.   

    我说的抽象当然不合理   说明这个flush一样  
    flush只有buffer的outputstream才有用  没有buffer的outputstream就没用
    这不和动物类的walk方法同样的道理还有如果 icecloud(冰云) 的下面这种说法成立
    ------------------------------
    flush 不是让OutputStream调用的
    而是应该用在Writer中吧
    ------------------------------这不明显有违java接口的原则   哪有接口出来只给一部分子类用的
      

  27.   

    不知sun上面有没io库的设计文档,找来看一看为何如此设计
      

  28.   

    我说的抽象当然不合理   说明这个flush一样  
    flush只有buffer的outputstream才有用  没有buffer的outputstream就没用
    这不和动物类的walk方法同样的道理还有如果 icecloud(冰云) 的下面这种说法成立
    ------------------------------
    flush 不是让OutputStream调用的
    而是应该用在Writer中吧
    ------------------------------这不明显有违java接口的原则   哪有接口出来只给一部分子类用的****************************************************************
    *  <机能概要>                                                   *
    *    装饰模式                                                   *
    ****************************************************************
    上面说了,java io库使用的就是装饰模式进行的设计,FilterInputStream和FilterOutputStream是2个用来“提供decorators以控制InputStream和OutputStream”的classes。他们都是抽象类,所以他们为所有被装饰类的对象提供共通接口。我们说了,设计IO库的时候,太多的subclasses会变得不切实际。I/O程序库要动用许多不同的功能组和,这也正是为什么要使用Decorator模式的原因。不过,想来,Decorator模式也是有缺点的,它会使程序代码的复杂性增加(虽然它给你带来了很大的编程弹性)。
      

  29.   

    BufferedOutStream类里的方法:public synchronized void flush() throws IOException {
            flushBuffer();
            ^^^^^^^^^^^^^^看了那么多感觉楼主钻了牛角尖了,没有看到这条语句.
            这里已经完成了清空缓冲区的功能了.
    out.flush();
    }实际上应用一般为了提高性能会为流处理提供一个缓存功能,无论在什么时候都保
    证能够方便访问到该方法,在父类中提供该方法是有必要的.至于什么模式之类的东
    西,未必会为API作者所考虑.映象中类似空方法在Java API中还有很多,就不一一列举了.
      

  30.   

    OutputStream可是基类
    应该是别的类装饰他   不是他装饰别的类楼上说的我早就看见了
    该说得我想已经说得很清楚了   具体怎么判断由大家了
      

  31.   

    TO jokerjava(冷血):
    你自己已经说了:
    <<flush只有buffer的outputstream才有用 没有buffer的outputstream就没用>>那么如果你设计这些类库,你会怎么处理flush方法?会放到什么地方?如果映射到上文提到的关于动物move的方法,就是有的动物会移动,有的动物不会移动(假设说珊瑚虫不会移动),那么按照你的说法,move方法就不属于动物了?
      

  32.   

    基本上说,java的io库大都因为要提高程序执行效率,都要包装入bufferStream,但是也有少数几个类没有用到buffer。并且一些其他的类也实现了自己的flush实现方法,比如说
    PipedOutputStream
    实现方法如下:
        public synchronized void flush() throws IOException {
    if (sink != null) {
                synchronized (sink) {
                    sink.notifyAll();
                }
    }
        }
    这个时候,如果调用BufferOutputStream构造时候传入的是PipedOutputStream,那么在BufferOutputStream中调用flush()的时候,代码如下
        public synchronized void flush() throws IOException {
            flushBuffer();
    out.flush();
        }
    那就是既实现了BufferOutputStream,又实现了PipedOutputStream的flush
      

  33.   

    那就是既实现了BufferOutputStream(的flush),又实现了PipedOutputStream的flush
    上面少写了
      

  34.   

    TO xiaohaiz(老土进城,两眼通红)  在前面cbhyk()已经说了
    如果按...原则来设计IO库的话,可能应该定义一个interface Buffered,该interface包含flush()方法,BufferedOutputStream、PrintWriter、ObjectOutputStream都实现Buffered,在用到OutputStream和Writer的地方这样写(?):
      if(out instanceof Buffered)
            ((Buffered) out).flush();
    以及:
        if(writer instanceof Buffered)
            ((Buffered) writer).flush();
    这个解决方案不可以么   TO mymoto(忽忽)   
    但是也有少数几个类没有用到buffer