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

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

问题描述

UPDATE2:我自己的适配器类版本,仅在构造函数中调用 instanceof 并在 flush() 中使用(Java 1.5)增量>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.

反过来呢?我正在使用一个需要编写器的函数,我正在尝试创建另一个调用它的函数,该函数接受一个可附加对象并将其传递给原始编写器函数.

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(...) 函数重定向到它们对应的 append(...)-s.但您还必须实施 <代码>flush()close(),我很清楚如何干净地编写它们,以便这个包装类可以接受任何 Appendable.

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.

令我惊讶的是,网络上或 stackoverflow 上或现有库中没有任何内容可以解决此问题.至少不是我能找到的.

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() 中使用(Java 1.5)delta>close().这是为了避免在对象构造之后必须使用任何逻辑或反射.这也作为 gist 发布: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

这个类包含一个demo,后面是两个什么都不做的deltas(一个Flushable,一个Closeable),主函数(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()> 是否可以清除可能尚未提交或未发送到流的任何其他写入.只需将所有 write 方法直接重定向到 Appendable 中的 append 方法,您就不必担心 flush()close() 除非你的 Appendable 实现了 Closeable 和/或 Flushable.

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() 之前,可能不会发送某些字节.为了绝对安全,我会在相应的方法中测试包装的 Appendable 是否为 CloseableFlushable 并转换它并执行操作嗯.

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天全站免登陆