1

Socket を介して ASCII 入出力ストリームを使用していますが、速度が重要です。適切な Java 手法を使用すると、実際に違いが生じると聞いたことがあります。Buffers を使用することが最善の方法であると書かれている教科書がありますが、DataInputStreamReader との連鎖も提案しています。

出力には、BufferedOutputStream と OutputStreamWriter を使用していますが、これは問題ないようです。しかし、入力ストリームに何を使用すればよいかわかりません。私は新しい行に取り組んでいるので、スキャナーは役に立ちますか? 速度は非常に重要です。できるだけ早くネットワークからデータを取得する必要があります。

ありがとう。

PH

4

4 に答える 4

3

ただ笑いのために...

socket = new ServerSocket(2004, 10);
connection = socket.accept();
in = connection.getInputStream();
InputStreamReader isr = new InputStreamReader(in);
BufferedReader br = new BufferedReader(isr);
String line = null;
do {
    line = br.readLine();
} while (!"done".equals(line));

LOOPBACKを使用します。つまり、ローカルプロセスを使用して、私のマシン上で、適切に「ばかげた」クライアントを使用してローカルホストに実行します。

requestSocket = new Socket("localhost", 2004);
out = requestSocket.getOutputStream();
PrintWriter pw = new PrintWriter(out);
String line =  "...1000 characters long..."; 
for (int i = 0; i < 2000000 - 1; i++) {
    pw.println(line);
}
line = "done";
pw.println(line);
pw.flush();

これは2Mの「1000char」行を送信することに注意してください。これは単なる大まかなスループットテストです。

私のマシンでは、ループバックで、最大190MB/秒の転送速度が得られます。ビットではなくバイト。190,000行/秒

私のポイントは、ボーンストックJavaソケットを使用する「洗練されていない」方法は非常に高速であるということです。これにより、一般的なネットワーク接続が飽和状態になります(つまり、ネットワークによって、ここでのI / Oよりも速度が低下します)。

おそらく「十分に速い」。

どのようなトラフィックを期待していますか?

于 2010-01-22T02:01:59.700 に答える
1

速度が絶対に重要な場合は、NIOの使用を検討してください。これは、まったく同じ質問に対して投稿されたコード例です。

http://lists.apple.com/archives/java-dev/2004/Apr/msg00051.html

編集:これは別の例です

http://www.java2s.com/Code/Java/File-Input-Output/UseNIOtoreadatextfile.htm

編集2:さまざまなアプローチのパフォーマンスの測定を開始するために、このマイクロベンチマークを作成しました。一部の人々は、データを使用可能な形式に「マッサージ」するためにより多くの作業を行う必要があるため、NIOのパフォーマンスが向上しないとコメントしています。そのため、実行しようとしていることに基づいて検証できます。このコードを自分のマシンで実行したとき、NIOコードは45メガバイトのファイルで約3倍、100メガバイトのファイルで5倍高速でした。

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.util.Scanner;

public class TestStuff {

    public static void main(final String[] args)
            throws IOException, InterruptedException {

        final String file_path = "c:\\test-nio.txt";
        readFileUsingNIO(file_path);
        readFileUsingScanner(file_path);

    }

    private static void readFileUsingScanner(final String path_to_file)
            throws FileNotFoundException {
        Scanner s = null;

        final StringBuilder builder = new StringBuilder();
        try {
            System.out.println("Starting to read the file using SCANNER");
            final long start_time = System.currentTimeMillis();
            s = new Scanner(new BufferedReader(new FileReader(path_to_file)));
            while (s.hasNext()) {
                builder.append(s.next());
            }
            System.out.println("Finished!  Read took " + (System.currentTimeMillis() - start_time) + " ms");
        }
        finally {
            if (s != null) {
                s.close();
            }
        }

    }

    private static void readFileUsingNIO(final String path_to_file)
            throws IOException {
        FileInputStream fIn = null;
        FileChannel fChan = null;
        long fSize;
        ByteBuffer mBuf;

        final StringBuilder builder = new StringBuilder();
        try {
            System.out.println("Starting to read the file using NIO");
            final long start_time = System.currentTimeMillis();
            fIn = new FileInputStream("c:\\test-nio.txt");
            fChan = fIn.getChannel();
            fSize = fChan.size();
            mBuf = ByteBuffer.allocate((int) fSize);
            fChan.read(mBuf);
            mBuf.rewind();
            for (int i = 0; i < fSize; i++) {
                //System.out.print((char) mBuf.get());
                builder.append((char) mBuf.get());
            }
            fChan.close();
            fIn.close();
            System.out.println("Finished!  Read took " + (System.currentTimeMillis() - start_time) + " ms");
        }
        catch (final IOException exc) {
            System.out.println(exc);
            System.exit(1);
        }
        finally {
            if (fChan != null) {
                fChan.close();
            }
            if (fIn != null) {
                fIn.close();
            }
        }

    }
于 2010-01-21T18:56:35.207 に答える
0

AScannerは区切りテキストに使用されます。あなたのデータがどのように見えるかについて話していないので、それについてコメントすることはできません.

各改行文字まで読みたいだけの場合は、使用します

BufferedReader r = new BufferedReader(new InputStreamReader(Socket.getInputStream()))

r.readLine()

null 値を取得すると、ストリーム内のデータを使い果たしたことがわかります。

速度に関する限り、どちらもストリームからデータを読み取っているだけです。したがって、 の追加機能が必要ないと仮定するとScanner、それを使用する特別な理由は見当たりません。

于 2010-01-21T18:33:07.253 に答える
-1

私は次の行に沿ってBufferedReaderで何かをします:

Collection<String> lines = new ArrayList<String>();
BufferedReader reader = new BufferedReader( new InputStreamReader( Foo.getInputStream()));
while(reader.ready())
{
    lines.add( reader.readLine());
}

myClass.processData(lines); //Process the data after it is off the network.

状況に応じて、「行」の項目がいっぱいになると処理する追加のスレッドを作成できますが、コレクションをバックアップするために別の構造を使用する必要があります。これは同時に使用できます。

于 2010-01-21T18:46:10.433 に答える