Java InputStream 에서 네트워크 응답 응답 응답 데 이 터 를 읽 는 방법!(중요)

질문
======================================================================
원리 설명 
1. InputStream. read ()     데이터 흐름 에서 데 이 터 를 읽 을 때 그림 이 간단 하고 Input Stream. read () 방법 을 자주 사용 합 니 다.이 방법 은 흐름 에서 한 바이트 만 읽 을 때마다 효율 이 매우 낮다.     더 좋 은 방법 은 InputStream. read (byte [] b) 나 InputStream. read (byte [] b, int off, int len) 방법 으로 한 번 에 여러 개의 바이트 를 읽 는 것 이다. 
2. InputStream 클래스 에 대한 available () 방법    한 번 에 여러 개의 바이트 를 읽 으 려 면 InputStream. available () 방법 을 자주 사용 합 니 다. 이 방법 은 읽 기와 쓰기 작업 전에 데이터 흐름 에 몇 개의 바이트 가 읽 을 수 있 는 지 알 수 있 습 니 다.주의해 야 할 것 은 이 방법 이 로 컬 파일 에서 데 이 터 를 읽 을 때 일반적으로 문제 가 발생 하지 않 지만 네트워크 작업 에 사용 된다 면 자주 문제 가 발생 할 수 있다 는 것 이다.예 를 들 어 Socket 통신 을 할 때 상대방 이 1000 개의 바 이 트 를 보 냈 는데 자신의 프로그램 이 available () 방법 을 호출 하 는 것 은 900 이나 100, 심지어 0 밖 에 얻 지 못 했 기 때문에 이상 하 게 도 원인 을 찾 지 못 했다.사실 이 는 인터넷 통신 이 중단 적 이 고 한 줄 의 바이트 가 몇 차례 에 걸 쳐 발송 되 기 때문이다.로 컬 프로그램 이 available () 방법 을 호출 할 때 0 을 받 을 수 있 습 니 다. 이것 은 상대방 이 아직 응답 하지 않 았 을 수도 있 고 상대방 이 이미 응답 을 했 을 수도 있 지만 데 이 터 는 아직 로 컬 에 전달 되 지 않 았 습 니 다.상대방 이 1000 개의 바이트 를 당신 에 게 보 냈 습 니 다. 아마도 3 차례로 나 누 어 도 착 했 을 것 입 니 다. 그러면 3 번 의 available () 방법 을 사용 해 야 데이터 총 수 를 모두 얻 을 수 있 습 니 다.
      코드 를 이렇게 쓰 면:
int count = in.available();  
  byte[] b = new byte[count];  
  in.read(b);

네트워크 작업 을 할 때 오류 가 발생 합 니 다. available () 방법 을 호출 할 때 보 낸 데이터 가 아직 도착 하지 않 았 을 수도 있 습 니 다. 당신 이 얻 은 count 는 0 입 니 다.         이렇게 고 쳐 야 합 니 다.
int count = 0;  
 while (count == 0) {  
  //count = in.available();  
  
  count=response.getEntity().getContentLength();//(HttpResponse response)  
 }  
 byte[] b = new byte[count];  
 in.read(b); 

3. InputStream. read (byte [] b) 와 InputStream. read (byte [] b, int off, int len) 에 관 한 두 가지 방법 은 모두 흐름 에서 여러 개의 바이트 를 읽 는 데 사용 되 는데 경험 이 있 는 프로그래머 들 은 이 두 가지 방법 이 자신 이 읽 고 싶 은 개수 의 바이트 를 자주 읽 지 못 한 다 는 것 을 알 게 될 것 이다.예 를 들 어 첫 번 째 방법 은 프로그래머 가 b. length 바이트 를 읽 기 를 원 하 는데 실제 상황 은 시스템 이 이렇게 많이 읽 지 못 하 는 경우 가 많다 는 것 이다.자바 의 API 설명 을 자세히 읽 어 보면 이 방법 은 이렇게 많은 바이트 를 읽 을 수 있다 는 보장 이 없 으 며, 최대 이렇게 많은 바이트 (최소 1 개) 만 읽 을 수 있다 는 것 을 알 수 있다.따라서 프로그램 이 count 바이트 를 읽 으 려 면 다음 코드 를 사용 하 는 것 이 좋 습 니 다.
  byte[] bytes = new byte[count];  
  int readCount = 0; //               
  while (readCount < count) {  
   readCount += in.read(bytes, readCount, count - readCount);  
  }  

이 코드 를 사용 하면 중간 에 IO 이상 이 발생 하거나 데이터 흐름 의 끝 (EOFException) 이 되 지 않 는 한 count 바이트 를 읽 을 수 있 습 니 다.
==========================================================================================
코드 공유
다음은 제 가 쓴 테스트 코드 세 션 을 공유 하여 참고 하 시기 바 랍 니 다.
    /** 
         * <b>     URL       </b> 
         * @param <font color="#efac10"><a href="http://www.baidu.com">_url:   URL</a></font> 
         * @return 
         * @throws ClientProtocolException 
         * @throws IOException 
         */  
        public String getReponse(String _url) throws ClientProtocolException, IOException  
        {  
            String readContent=null;  
            DefaultHttpClient httpclient = new DefaultHttpClient();  
            HttpGet httpget = new HttpGet(SinaJsonTest.SinaUrl);  
            System.out.println("0.Send the URL to Sina Sever....");  
            HttpResponse response = httpclient.execute(httpget);  
            HttpEntity entity = response.getEntity();  
      
            System.out.println("1.Get Response Status: " + response.getStatusLine());  
            if (entity != null) {  
                System.out.println("  Get ResponseContentEncoding():"+entity.getContentEncoding());  
                System.out.println("  Content Length():"+entity.getContentLength());  
                //getResponse  
                InputStream in=entity.getContent();  
                int count = 0;  
                while (count == 0) {  
                 count = Integer.parseInt(""+entity.getContentLength());//in.available();  
                }  
                byte[] bytes = new byte[count];  
                int readCount = 0; //               
                while (readCount <= count) {  
                 if(readCount == count)break;  
                 readCount += in.read(bytes, readCount, count - readCount);  
                }  
                  
                //        
                readContent= new String(bytes, 0, readCount, "UTF-8"); // convert to string using bytes  
      
                System.out.println("2.Get Response Content():
"+readContent); } return readContent; }

다음으로 전송:http://blog.csdn.net/hurryjiang/article/details/6688247

좋은 웹페이지 즐겨찾기