使用ASCII线处理Java IO的最快方法

我正在通过Socket使用ASCII输入/输出流,速度至关重要。 我听说使用正确的Java技术确实有所作为。 我有一本教科书说使用Buffers是最好的方法,但也建议使用DataInputStreamReader进行链接。

对于输出我使用带有OutputStreamWriter的BufferedOutputStream似乎没问题。 但我不确定输入流的用途。 我正在开发新系列,扫描仪有用吗? 速度至关重要,我需要尽快从网络上获取数据。

谢谢。

PH

只为一笑…

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,即只使用本地进程运行到localhost,在我的机器上运行,并使用适当的“愚蠢”客户端。

 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“1000 char”行。 这只是粗略的吞吐量测试。

在我的机器上,环回,我得到~190MB /秒的传输速率。 字节,而不是位。 190,000线/秒。

我的观点是使用骨库Java套接字的“简单”方式非常快。 这将使任何常见的网络连接饱和(意味着网络将比你的I / O更慢)。

可能“足够快”。

你期待什么样的交通?

如果速度绝对至关重要,请考虑使用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的执行速度不快,因为你需要做更多的工作来将数据“按摩”成一个可用的forms,这样你就可以根据你想做的事情进行validation。 当我在我的机器上运行此代码时,使用45兆字节文件的NIO代码大约快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(); } } } 

Scanner用于分隔文本。 你没有谈论你的数据是什么样的,所以我不能对此发表评论。

如果您只想阅读每个换行符,请使用

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

r.readLine()

当您获得空值时,您将知道您已用尽流中的数据。

就速度而言,它们都只是从流中读取数据。 因此,假设您不需要Scanner的额外function,我没有看到使用Scanner任何特殊原因。

我会用BufferedReader做一些事情:

 Collection lines = new ArrayList(); 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. 

根据您的情况,您可以有一个额外的线程来处理“行”中的项目,因为它会被填充,但是您需要使用不同的结构来支持集合 – 可以同时使用的集合。