내가 만들고있는 안드로이드 응용 프로그램을 위해 웹 사이트에 HTTP get 요청을하고 있습니다.
DefaultHttpClient를 사용하고 HttpGet을 사용하여 요청을 발행하고 있습니다. 엔티티 응답을 얻고이 페이지에서 html을 가져 오기위한 InputStream 객체를 얻습니다.
그런 다음 다음과 같이 회신을 순환합니다.
BufferedReader r = new BufferedReader(new InputStreamReader(inputStream));
String x = "";
x = r.readLine();
String total = "";
while(x!= null){
total += x;
x = r.readLine();
}
그러나 이것은 엄청나게 느립니다.
이것이 비효율적인가? 큰 웹 페이지 -www.cokezone.co.uk를 로드하지 않으므로 파일 크기가 크지 않습니다. 더 좋은 방법이 있습니까?
감사
앤디
답변
코드의 문제는 많은 무거운 String
객체를 만들고 내용을 복사하고 작업을 수행 한다는 것입니다. 대신, 각 추가에 StringBuilder
새 String
객체를 만들지 않고 char 배열을 복사 하지 않도록 사용해야 합니다. 귀하의 사례에 대한 구현은 다음과 같습니다.
BufferedReader r = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder total = new StringBuilder();
for (String line; (line = r.readLine()) != null; ) {
total.append(line).append('\n');
}
이제 total
로 변환하지 않고 사용할 수 String
있지만 결과를로 필요하면 String
간단히 추가하십시오.
문자열 결과 = total.toString ();
나는 그것을 더 잘 설명하려고 노력할 것입니다 …
a += b
(나a = a + b
) 여기서a
및b
문자열, 복사의 내용입니다 모두a
와b
(당신은 또한 복사합니다 새로운 객체에a
포함, 축적을String
), 당신은 각각의 반복에 그 사본을 다하고 있습니다.a.append(b)
, wherea
isStringBuilder
는에b
내용을 직접 추가a
하므로 반복 할 때마다 누적 된 문자열을 복사하지 않습니다.
답변
스트림을 문자열로 변환하기 위해 내장 메소드를 사용해 보셨습니까? Apache Commons 라이브러리 (org.apache.commons.io.IOUtils)의 일부입니다.
그런 다음 코드는 다음 한 줄입니다.
String total = IOUtils.toString(inputStream);
이에 대한 설명서는 http://commons.apache.org/io/api-1.4/org/apache/commons/io/IOUtils.html#toString%28java.io.InputStream%29 에서 찾을 수 있습니다
.
Apache Commons IO 라이브러리는 다음 위치에서 다운로드 할 수 있습니다.
http://commons.apache.org/io/download_io.cgi
답변
구아바의 또 다른 가능성 :
의존: compile 'com.google.guava:guava:11.0.2'
import com.google.common.io.ByteStreams;
...
String total = new String(ByteStreams.toByteArray(inputStream ));
답변
나는 이것이 충분히 효율적이라고 믿습니다 … InputStream에서 String을 얻으려면 다음 메소드를 호출합니다.
public static String getStringFromInputStream(InputStream stream) throws IOException
{
int n = 0;
char[] buffer = new char[1024 * 4];
InputStreamReader reader = new InputStreamReader(stream, "UTF8");
StringWriter writer = new StringWriter();
while (-1 != (n = reader.read(buffer))) writer.write(buffer, 0, n);
return writer.toString();
}
나는 항상 UTF-8을 사용합니다. 물론 InputStream 외에도 charset을 인수로 설정할 수 있습니다.
답변
이건 어때? 더 나은 성능을 제공하는 것 같습니다.
byte[] bytes = new byte[1000];
StringBuilder x = new StringBuilder();
int numRead = 0;
while ((numRead = is.read(bytes)) >= 0) {
x.append(new String(bytes, 0, numRead));
}
편집 : 실제로이 종류는 스틸 바이트와 모리스 페리 모두를 포함합니다.
답변
Jaime Soriano의 답변보다 다소 빠르며 Adrian의 답변에 멀티 바이트 인코딩 문제가 없으면 다음과 같이 제안합니다.
File file = new File("/tmp/myfile");
try {
FileInputStream stream = new FileInputStream(file);
int count;
byte[] buffer = new byte[1024];
ByteArrayOutputStream byteStream =
new ByteArrayOutputStream(stream.available());
while (true) {
count = stream.read(buffer);
if (count <= 0)
break;
byteStream.write(buffer, 0, count);
}
String string = byteStream.toString();
System.out.format("%d bytes: \"%s\"%n", string.length(), string);
} catch (IOException e) {
e.printStackTrace();
}
답변
어쩌면 ‘한 번에 한 줄씩’을 읽고 문자열을 결합하고 줄 끝을 스캔하지 않도록하고 문자열 조인을 피하기 위해 ‘사용 가능한 모든 항목 읽기’를 시도하십시오.
즉, InputStream.available()
및InputStream.read(byte[] b), int offset, int length)