Android Reading from an Input stream efficiently

2019-01-03 11:58发布

I am making an HTTP get request to a website for an android application I am making.

I am using a DefaultHttpClient and using HttpGet to issue the request. I get the entity response and from this obtain an InputStream object for getting the html of the page.

I then cycle through the reply doing as follows:

BufferedReader r = new BufferedReader(new InputStreamReader(inputStream));
String x = "";
x = r.readLine();
String total = "";

while(x!= null){
total += x;
x = r.readLine();
}

However this is horrendously slow.

Is this inefficient? I'm not loading a big web page - www.cokezone.co.uk so the file size is not big. Is there a better way to do this?

Thanks

Andy

12条回答
家丑人穷心不美
2楼-- · 2019-01-03 12:41
    byte[] buffer = new byte[1024];  // buffer store for the stream
    int bytes; // bytes returned from read()

    // Keep listening to the InputStream until an exception occurs
    while (true) {
        try {
            // Read from the InputStream
            bytes = mmInStream.read(buffer);

            String TOKEN_ = new String(buffer, "UTF-8");

            String xx = TOKEN_.substring(0, bytes);
查看更多
爷、活的狠高调
3楼-- · 2019-01-03 12:43

The problem in your code is that it's creating lots of heavy String objects, copying their contents and performing operations on them. Instead, you should use StringBuilder to avoid creating new String objects on each append and to avoid copying the char arrays. The implementation for your case would be something like this:

BufferedReader r = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder total = new StringBuilder();
for (String line; (line = r.readLine()) != null; ) {
    total.append(line).append('\n');
}

You can now use total without converting it to String, but if you need the result as a String, simply add:

String result = total.toString();

I'll try to explain it better...

  • a += b (or a = a + b), where a and b are Strings, copies the contents of both a and b to a new object (note that you are also copying a, which contains the accumulated String), and you are doing those copies on each iteration.
  • a.append(b), where a is a StringBuilder, directly appends b contents to a, so you don't copy the accumulated string at each iteration.
查看更多
smile是对你的礼貌
4楼-- · 2019-01-03 12:45

If the file is long, you can optimize your code by appending to a StringBuilder instead of using a String concatenation for each line.

查看更多
Ridiculous、
5楼-- · 2019-01-03 12:48

I am use to read full data:

// inputStream is one instance InputStream
byte[] data = new byte[inputStream.available()];
inputStream.read(data);
String dataString = new String(data);
查看更多
爱情/是我丢掉的垃圾
6楼-- · 2019-01-03 12:52

To convert the InputStream to String we use the BufferedReader.readLine() method. We iterate until the BufferedReader return null which means there's no more data to read. Each line will appended to a StringBuilder and returned as String.

 public static String convertStreamToString(InputStream is) {

        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        StringBuilder sb = new StringBuilder();

        String line = null;
        try {
            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return sb.toString();
    }
}`

And finally from any class where you want to convert call the function

String dataString = Utils.convertStreamToString(in);

complete

查看更多
在下西门庆
7楼-- · 2019-01-03 12:53

Have you tried the built in method to convert a stream to a string? It's part of the Apache Commons library (org.apache.commons.io.IOUtils).

Then your code would be this one line:

String total = IOUtils.toString(inputStream);

The documentation for it can be found here: http://commons.apache.org/io/api-1.4/org/apache/commons/io/IOUtils.html#toString%28java.io.InputStream%29

The Apache Commons IO library can be downloaded from here: http://commons.apache.org/io/download_io.cgi

查看更多
登录 后发表回答