Java 什么';从InputStream读取数据的最快方式是什么?
我正在尝试从HttpURLConnection的输入流读取:Java 什么';从InputStream读取数据的最快方式是什么?,java,performance,inputstream,Java,Performance,Inputstream,我正在尝试从HttpURLConnection的输入流读取: InputStream input = conn.getInputStream(); InputStreamReader isr = new InputStreamReader((input)); BufferedReader br = new BufferedReader(isr); StringBuilder out = new StringBuilder(""); String output; while ((output =
InputStream input = conn.getInputStream();
InputStreamReader isr = new InputStreamReader((input));
BufferedReader br = new BufferedReader(isr);
StringBuilder out = new StringBuilder("");
String output;
while ((output = br.readLine()) != null) {
out.append(output);
}
当输入流包含大量数据时,这会花费太多时间。有没有可能对其进行优化?这段代码没有什么慢的地方。如果输入足够快的话,你可以用这个每秒读数百万行。您的时间可能根本没有花在读取输入流上,而是在阻塞等待输入或附加到
StringBuilder
中
但你根本不应该这么做。大多数文件可以一次处理一行或一次处理一条记录。编译器一次只处理一个令牌,没有比编译更复杂的文件处理任务了。这是可能的。这可能会快一点,因为Java 8中的新流API内部使用了一种并行机制:
package testing;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.stream.Stream;
public class StreamTest {
/**
* @param args the command line arguments
* @throws java.io.IOException
*/
public static void main(String[] args) throws IOException {
URL url = new URL("http://www.google.com");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setUseCaches(false);
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
Stream<String> s = br.lines();
s.parallel().forEach(System.out::println);
}
}
}
封装测试;
导入java.io.BufferedReader;
导入java.io.IOException;
导入java.io.InputStreamReader;
导入java.net.HttpURLConnection;
导入java.net.URL;
导入java.util.stream.stream;
公共类流测试{
/**
*@param指定命令行参数
*@抛出java.io.IOException
*/
公共静态void main(字符串[]args)引发IOException{
URL=新URL(“http://www.google.com");
HttpURLConnection conn=(HttpURLConnection)url.openConnection();
conn.SETUSECHACHES(假);
if(conn.getResponseCode()==HttpURLConnection.HTTP\u确定){
BufferedReader br=新的BufferedReader(新的InputStreamReader(conn.getInputStream());
流s=br.lines();
s、 parallel().forEach(System.out::println);
}
}
}
在java inputstream中,我们读取了方法(字节b[],off,len)
它将输入流中的数据读取到给定的字节数组中。
这里off是数组的起始索引,len是要读取的最大字节数,b[]是字节数组。
Read方法将尝试读取最大长度的字节数,但此方法返回实际读取的字节数,因为我无法读取所需的字节数。
以下是一个例子:-
FileInputStream i=new FileInputStream("file path");
FIleOutputStream o=new FileOutputStream("file path");
byte a[]=new byte[1024];
for(int j;(j=i.read(a,0,1024))!=-1;){
o.write(a,0,j);
}
与数据通过网络到达所需的时间相比,您认为代码中的瓶颈是什么?您可以为
BufferedReader使用较大/较小的缓冲区大小进行测试。你在其他方面受到网络的限制。是否“太多”实际上比使用其他方式(ftp、浏览器、wget等)下载资源时更多?测量,不要猜测。您期望多少KB/s?您得到多少KB/s?请注意,构建巨大的StringBuilder可能需要很多时间。如果都在内存中,那么会有大量的数组复制和内存分配。@laune:我认为它不太可能比网络慢…@biziclop我确实看到了双/copy来降低速度。检查是一回事,因此评论不是答案;-)如果你说“时间……花在……附加到StringBuilder上”:你是不是反驳了你的说法“这段代码没有什么慢的地方”。我采取了一些措施:等待输入需要12-13秒,读取流+构建StringBuilder需要40-55秒。那么你可能已经完成了fastet实现。也许并发读取将是一种选择:如果您决定切换到Java8,这将非常有用:谢谢您的提示。在我的代码中,bufferedReader.readLine()是占用执行时间最多的一个,事实上并不是更快。20kb的字符串仍然需要10秒左右的时间