如何将java.lang.Appendable包装到java.io.Writer中? [英] How to wrap a java.lang.Appendable into a java.io.Writer?

查看:76
本文介绍了如何将java.lang.Appendable包装到java.io.Writer中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

UPDATE2:我自己的适配器版本,只在构造函数中调用 instanceof 并在 flush中使用(Java 1.5)delta () close()函数(避免在构造对象后需要任何反射或逻辑)包含在本文的底部。 UPDATE1:Marc Baumbach写了一个简单的适配器,这正是我需要的。包括在下面。原始问题如下。

UPDATE2: My own version of the adapter class, that only calls instanceof in the constructor and uses a (Java 1.5) delta in the flush() and close() functions (avoiding the need for any reflection or logic after object construction), is included at the bottom of this post. UPDATE1: Marc Baumbach wrote a simple Adapter that is exactly what I need. Included below. Original question follows.

需要 java.lang.Appendable 可以接受 java.io.Writer ,因为 Writer 实现可附加

另一种方式呢?我正在使用一个需要编写器的函数,我正在尝试创建另一个调用它的函数,它接受一个appendable并将其传递给原始的writer函数。

What about the other way around? I am using a function that requires a writer, and I am trying to create another function that calls it, which accepts an appendable and passes it to the original writer-function.

我看到你可以扩展 Writer ,它是抽象的,并将所有 write(...)函数重定向到相应的追加(...) -s。但是你还必须实现 flush() close() ,我很清楚如何干净地编写这些包装类可以接受任何可附加。

I see that you can extend Writer, which is abstract, and redirect all write(...) functions to their corresponding append(...)-s. But you also have to implement flush() and close(), and I'm clear on how to write those cleanly so this wrapper-class can accept any Appendable.

我很惊讶在网上或堆栈溢出或者现有的库,解决了这个问题。至少不是我能找到的。

I'm surprised there isn't anything already out there, either on the web or stackoverflow, or in an existing library, that addresses this. At least not that I could find.

我很感激这里的一点指导。谢谢。

I'd appreciate a little guidance here. Thank you.

回答此问题的适配器代码。由Marc Baumbach撰写(我自己的版本如下):

Adapter code that answers this question. Written by Marc Baumbach (my own version is below):

import java.io.Closeable;
import java.io.Flushable;
import java.io.IOException;
import java.io.Writer;

public class AppendableWriterAdapter extends Writer {

      private Appendable appendable;

      public AppendableWriterAdapter(Appendable appendable) {
            this.appendable = appendable;
      }

      @Override
      public void write(char[] cbuf, int off, int len) throws IOException {
            appendable.append(String.valueOf(cbuf), off, len);
      }

      @Override
      public void flush() throws IOException {
            if (appendable instanceof Flushable) {
                  ((Flushable) appendable).flush();
            }
      }

      @Override
      public void close() throws IOException {
            flush();
            if (appendable instanceof Closeable) {
                  ((Closeable) appendable).close();
            }
      }

}






这是我自己的版本,基于Marc,只在构造函数中使用 instanceof ,在 flush() close()。这是为了避免在对象构造之后使用任何逻辑或反射。这也是作为要点发布的: https://gist.github.com/aliteralmind/8494917


Here is my own version, based on Marc's, that only uses instanceof only in the constructor, and a (Java 1.5) delta in flush() and close(). This is to avoid having to use any logic or reflection after object construction. This is also released as a gist: https://gist.github.com/aliteralmind/8494917

此课程包含一个演示,然后是两个无所事事的增量(一个 Flushable ,一个可关闭),主要功能( newWriterForAppendable(apbl)),然后是适配器类本身。

This class contains a demo, followed by two do-nothing deltas (one Flushable, one Closeable), the main function (newWriterForAppendable(apbl)), and then the adapter class itself.

   import  java.io.Closeable;
   import  java.io.Flushable;
   import  java.io.IOException;
   import  java.io.Writer;
/**
   <P>{@code java NewWriterForAppendable}.</P>
 **/
public class NewWriterForAppendable  {
   /**
      <P>Demonstrates {@code newWriterForAppendable(apbl)} for creating a new {@code Writer} that wraps around {@code System.out} (writes to the console).</P>
    **/
   public static final void main(String[] igno_red)  {
      try  {
         NewWriterForAppendable.newWriterForAppendable(System.out).write("hello");
      }  catch(IOException iox)  {
         throw  new RuntimeException("WriterForAppendableXmpl", iox);
      }
   }
   /**
      <P>A {@code Flushable} whose {@code flush()} function does nothing. This is used by {@link #newWriterForAppendable(Appendable ap_bl) newWriterForAppendable}{@code (apbl)} as a (Java 1.5) delta.</P>

      @see  #newWriterForAppendable(Appendable) newWriterForAppendable(apbl)
    **/
   public static final Flushable FLUSHABLE_DO_NOTHING = new Flushable()  {
      public void flush()  {
      }
   };
   /**
      <P>A {@code Closeable} whose {@code close()} function does nothing. This is used by {@link #newWriterForAppendable(Appendable ap_bl) newWriterForAppendable}{@code (apbl)} as a (Java 1.5) delta.</P>

      @see  #newWriterForAppendable(Appendable) newWriterForAppendable(apbl)
    **/
   public static final Closeable CLOSEABLE_DO_NOTHING = new Closeable()  {
      public void close()  {
      }
   };
   /**
      <P>Creates a new {@code java.io.Writer} that wraps around a {@code java.lang.Appendable}. It properly {@link java.io.Writer#flush() flush}es and {@link java.io.Writer#close() close}s appendables that happened to also be {@link java.io.Flushable}s and/or {@link java.io.Closeable Closeable}s. This uses {@code instanceof} only in the constructor, and a delta in {@code flush()} and {@code close()}, which avoids having to use any logic or reflection after object construction.</P>

      <P>This function is released as a <A HREF="https://gist.github.com/aliteralmind/8494917">gist</A>, and is an example of the <A HREF="http://en.wikipedia.org/wiki/Adapter_pattern#Object_Adapter_pattern">Object Adapter pattern</A>. Thanks to <A HREF="http://stackoverflow.com/users/1211906/marc-baumbach">Marc Baumbach</A> on <A HREF="http://stackoverflow.com">{@code stackoverflow}</A> for the assistance. See (viewed 1/18/2014)
      <BR> &nbsp; &nbsp; <CODE><A HREF="http://stackoverflow.com/questions/21200421/how-to-wrap-a-java-lang-appendable-into-a-java-io-writer">http://stackoverflow.com/questions/21200421/how-to-wrap-a-java-lang-appendable-into-a-java-io-writer</A></CODE></P>

      @return  A new writer that uses an appendable to do its output.
      @see  #FLUSHABLE_DO_NOTHING
      @see  #CLOSEABLE_DO_NOTHING
    **/
   public static final Writer newWriterForAppendable(Appendable ap_bl)  {
      return  (new WFA(ap_bl));
   }
   private NewWriterForAppendable()  {
      throw  new IllegalStateException("constructor: Do not instantiate.");
   }
}
class WFA extends Writer  {
   private final Appendable apbl;
   private final Flushable  flbl;
   private final Closeable  clbl;
   public WFA(Appendable ap_bl)  {
      if(ap_bl == null)  {
         throw  new NullPointerException("ap_bl");
      }
      apbl = ap_bl;

      //Avoids instanceof at every call to flush() and close()
      flbl = (Flushable)((ap_bl instanceof Flushable) ? ap_bl
         :  NewWriterForAppendable.FLUSHABLE_DO_NOTHING);
      clbl = (Closeable)((ap_bl instanceof Closeable) ? ap_bl
         :  NewWriterForAppendable.CLOSEABLE_DO_NOTHING);
   }
   @Override
   public void write(char[] a_c, int i_ndexStart, int i_ndexEndX) throws IOException {
      apbl.append(String.valueOf(a_c), i_ndexStart, i_ndexEndX);
   }
   @Override
   public Writer append(char c_c) throws IOException {
      apbl.append(c_c);
      return  this;
   }
   @Override
   public Writer append(CharSequence c_q) throws IOException {
      apbl.append(c_q);
      return  this;
   }
   @Override
   public Writer append(CharSequence c_q, int i_ndexStart, int i_ndexEndX) throws IOException  {
      apbl.append(c_q, i_ndexStart, i_ndexEndX);
      return  this;
   }
   @Override
   public void flush() throws IOException {
      flbl.flush();
   }
   @Override
   public void close() throws IOException {
      flush();
      clbl.close();
   }

}


推荐答案

通常在 Writer 中, flush() close()用于清除可能尚未提交或发送到流的任何其他写入。只需将所有写入方法直接重定向到 Appendable中的追加方法你不必担心 flush() close()除非你的可附加实现可关闭和/或可刷新

Typically in a Writer, the flush() and close() are there to cleanup any additional writes that may not have been committed or sent to the stream. By simply redirecting all of the write methods directly to the append methods in the Appendable you won't have to worry about flush() and close() unless your Appendable implements Closeable and/or Flushable.

一个很好的例子就像的BufferedWriter 。当您在此处调用 write()时,它可能不会立即将所有字节发送到最终输出/流。在您 flush() close()之前,可能无法发送一些字节。为了绝对安全,如果可关闭可以冲洗在相应的方法中并投射它并执行操作。

A good example is something like BufferedWriter. When you are calling write() on that, it may not be sending all of the bytes to the final output/stream immediately. Some bytes may not be sent until you flush() or close() it. To be absolutely safe, I would test the wrapped Appendable if it is Closeable or Flushable in the corresponding method and cast it and perform the action as well.

这是一个非常标准的设计模式,称为适配器模式

This is a pretty standard design pattern called the Adapter pattern.

这可能是一个很好的实现此适配器: http://pastebin.com/GcsxqQxj

Here is what is likely a good implementation for this adapter: http://pastebin.com/GcsxqQxj

这篇关于如何将java.lang.Appendable包装到java.io.Writer中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆