【问题标题】:re-implementation of org.apache.commons.net.io.Util to parse an InputStream重新实现 org.apache.commons.net.io.Util 以解析 InputStream
【发布时间】:2013-09-03 19:41:33
【问题描述】:

org.apache.commons.net.io.Util 使用 InputStream 在流终止之前无法解析live。这是对还是错?

IOUtil 类对我来说是一个黑匣子。它使用org.apache.commons.net.io.Util,但这同样不透明。

具体来说,IOUtil 的行 Util.copyStream(remoteInput, localOutput); 很有趣:

copyStream

public static final long copyStream(InputStream source,
              OutputStream dest)
                             throws CopyStreamException

Same as copyStream(source, dest, DEFAULT_COPY_BUFFER_SIZE);

Throws:
    CopyStreamException

如何读取原始流或其副本进入时?实时 telnet 连接将有一个InputStream,它不会终止。我在 API 中看不到这样的功能。

或者,重新实现 Apache examples.util.IOUtil 会回到原来的问题:

package weathertelnet;

import java.io.IOException;
import java.io.InputStream;
import java.util.logging.Logger;

public class StreamReader {

    private final static Logger LOG = Logger.getLogger(StreamReader.class.getName());
    private StringBuilder stringBuilder = new StringBuilder();
    private InputStream inputStream;

    public StreamReader() {
    }

    public void setInputStream(InputStream inputStream) throws IOException {
        this.inputStream = inputStream;
        readWrite();
    }

    public void readWrite() throws IOException {
        Thread reader = new Thread() {

            @Override
            public void run() {
                do {
                    try {
                        char ch = (char) inputStream.read();
                        stringBuilder.append(ch);
                    } catch (IOException ex) {
                    }
                } while (true);  //never stop reading the stream..
            }
        };

        Thread writer = new Thread() {

            @Override
            public void run() {
                //Util.copyStream(remoteInput, localOutput);
                //somehow write the *live* stream to file *as* it comes in
                //or, use org.apache.commons.net.io.Util to "get the data"
            }
        };
    }
}

要么我有一个根本的误解,要么没有重新实现(或使用反射,也许)这些 API 不允许处理 实时的、未终止的 InputStream

我真的不倾向于在这里使用反射,我认为下一个阶段是开始分解org.apache.commons.net.io.Util 的作用以及它是如何做到的,但这真的是在兔子洞里。它在哪里结束?

http://commons.apache.org/proper/commons-net/apidocs/org/apache/commons/net/io/Util.html#copyStream%28java.io.InputStream,%20java.io.OutputStream%29

【问题讨论】:

  • 问题是如何并发打印和读取 TelnetClient 用于输出的 InputStream。

标签: java io inputstream telnet apache-commons


【解决方案1】:

您可以复制一个流“live”,但当没有更多输入时,InputStream 可能会阻塞。

你可以看到org.apache.commons.net.io.Util#copyStream(...)here的代码

【讨论】:

  • 没关系,如果没有更多的输入,那么就没有什么可读的了。当telnet流(MUD游戏)再次启动时,它会解锁吗?这是呈现困难的流的停止和开始,现场性质(我认为)。如何重新开始阅读?
  • 读取将阻塞,直到再次输入。只需确保您复制的流在每条消息后刷新(通过调用 outputStream.flush()),以便读者尽快看到它。
  • 请看我的回答:)
【解决方案2】:

先输出:

thufir@dur:~$ 
thufir@dur:~$ java -jar NetBeansProjects/SSCCE/dist/SSCCE.jar 
print..
makeString..
cannot remove       java.util.NoSuchElementException
------------------------------------------------------------------------------
*               Welcome to THE WEATHER UNDERGROUND telnet service!            *
------------------------------------------------------------------------------
*                                                                            *
*   National Weather Service information provided by Alden Electronics, Inc. *
*    and updated each minute as reports come in over our data feed.          *
*                                                                            *
*   **Note: If you cannot get past this opening screen, you must use a       *
*   different version of the "telnet" program--some of the ones for IBM      *
*   compatible PC's have a bug that prevents proper connection.              *
*                                                                            *
*           comments: jmasters@wunderground.com                              *
------------------------------------------------------------------------------

Press Return to continue:finally -- waiting for more data..





cannot remove       java.util.NoSuchElementException
finally -- waiting for more data..

------------------------------------------------------------------------------
*               Welcome to THE WEATHER UNDERGROUND telnet service!            *
------------------------------------------------------------------------------
*                                                                            *
*   National Weather Service information provided by Alden Electronics, Inc. *
*    and updated each minute as reports come in over our data feed.          *
*                                                                            *
*   **Note: If you cannot get past this opening screen, you must use a       *
*   different version of the "telnet" program--some of the ones for IBM      *
*   compatible PC's have a bug that prevents proper connection.              *
*                                                                            *
*           comments: jmasters@wunderground.com                              *
------------------------------------------------------------------------------

Press Return to continue:



cannot remove       java.util.NoSuchElementException
^Cthufir@dur:~$ 
thufir@dur:~$ 

然后代码:

thufir@dur:~$ cat NetBeansProjects/SSCCE/src/weathertelnet/Telnet.java 
package weathertelnet;

import static java.lang.System.out;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.logging.Logger;
import org.apache.commons.net.telnet.TelnetClient;

public final class Telnet {

    private final static Logger LOG = Logger.getLogger(Telnet.class.getName());
    private TelnetClient telnetClient = new TelnetClient();

    public Telnet() throws SocketException, IOException {
        InetAddress host = InetAddress.getByName("rainmaker.wunderground.com");
        int port = 3000;
        telnetClient.connect(host, port);

        final InputStream inputStream = telnetClient.getInputStream();
        final ConcurrentLinkedQueue<Character> clq = new ConcurrentLinkedQueue();
        final StringBuilder sb = new StringBuilder();

        Thread print = new Thread() {

            @Override
            public void run() {
                out.println("print..");
                try {
                    char ch = (char) inputStream.read();
                    while (255 > ch && ch >= 0) {
                        clq.add(ch);
                        out.print(ch);
                        ch = (char) inputStream.read();
                    }
                } catch (IOException ex) {
                    out.println("cannot read inputStream:\t" + ex);
                }
            }
        };

        Thread makeString = new Thread() {

            @Override
            public void run() {
                out.println("makeString..");
                do {
                    try {
                        do {
                            char ch = clq.remove();
                            sb.append(ch);
                            // out.println("appended\t" + ch);
                        } while (true);
                    } catch (java.util.NoSuchElementException | ClassCastException e) {
                        out.println("cannot remove\t\t" + e);
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException interruptedException) {
                            out.println("cannot sleep1\t\t" + interruptedException);
                        }
                    } finally {
                        out.println("finally -- waiting for more data..\n\n" + sb + "\n\n\n");
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException interruptedException) {
                            out.println("cannot sleep1\t\t" + interruptedException);
                        }
                    }
                } while (true);
            }
        };
        print.start();
        makeString.start();
    }

    private void cmd(String cmd) throws IOException {//haven't tested yet..
        byte[] b = cmd.getBytes();
        System.out.println("streamreader has\t\t" + cmd);
        int l = b.length;
        for (int i = 0; i < l; i++) {
            telnetClient.sendCommand(b[i]);
        }
    }

    public static void main(String[] args) throws SocketException, IOException {
        new Telnet();
    }
}thufir@dur:~$ 
thufir@dur:~$ 

【讨论】:

    猜你喜欢
    • 2015-09-03
    • 1970-01-01
    • 1970-01-01
    • 2011-08-05
    • 2020-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-15
    相关资源
    最近更新 更多