2013-10-08 5 views
3

다운로드 및 업로드를 위해 네트워크 연결 속도를 분석하는 Android 애플리케이션에서 AsyncTask 클래스를 수행하려고합니다. 지금 다운로드 부분에 대한 작업을하고 있지만 기대했던 결과를 얻지 못하고 있습니다. 나는 15Mbps 다운/업 속도를 일관되게 유지하는 Wi-Fi 네트워크를 테스트 중이지만, 애플리케이션에서 얻는 결과는 겨우 1Mpbs 정도입니다. 내가 속도 테스트 APK를 실행할 때 약 3.5Mbps의 속도로 테스트하고있다. 이 기능은 작동하며 속도가 절반에 불과합니다. 다음 코드가 정확한 결과를 산출해야합니까? 도움에 미리Java/Android로 다운로드 속도를 정확하게 측정하는 방법

try { 
      String DownloadUrl = "http://ipv4.download.thinkbroadband.com:8080/5MB.zip"; 
      String fileName = "testfile.bin"; 


      File dir = new File (context.getFilesDir() + "/temp/"); 
      if(dir.exists()==false) { 
       dir.mkdirs(); 
      } 

      URL url = new URL(DownloadUrl); //you can write here any link 
      File file = new File(context.getFilesDir() + "/temp/" + fileName); 


      long startTime = System.currentTimeMillis(); 
      Log.d("DownloadManager", "download begining: " + startTime); 
      Log.d("DownloadManager", "download url:" + url); 
      Log.d("DownloadManager", "downloaded file name:" + fileName); 

      /* Open a connection to that URL. */ 
      URLConnection ucon = url.openConnection(); 

      //Define InputStreams to read from the URLConnection. 
      InputStream is = ucon.getInputStream(); 
      BufferedInputStream bis = new BufferedInputStream(is); 

      //Read bytes to the Buffer until there is nothing more to read(-1). 
      ByteArrayBuffer baf = new ByteArrayBuffer(1024); 
      int current = 0; 
      while ((current = bis.read()) != -1) { 
       baf.append((byte) current); 
      } 
      long endTime = System.currentTimeMillis(); //maybe 

      /* Convert the Bytes read to a String. */ 
      FileOutputStream fos = new FileOutputStream(file); 
      fos.write(baf.toByteArray()); 
      fos.flush(); 
      fos.close(); 

      File done = new File(context.getFilesDir() + "/temp/" + fileName); 
      Log.d("DownloadManager", "Location being searched: "+ context.getFilesDir() + "/temp/" + fileName); 
      double size = done.length(); 
      if(done.exists()) { 
       done.delete(); 
      } 

      Log.d("DownloadManager", "download ended: " + ((endTime - startTime)/1000) + " secs"); 
      double rate = (((size/1024)/((endTime - startTime)/1000)) * 8); 
      rate = Math.round(rate * 100.0)/100.0; 
      String ratevalue; 
      if(rate > 1000) 
      ratevalue = String.valueOf(rate/1024).concat(" Mbps"); 
      else 
      ratevalue = String.valueOf(rate).concat(" Kbps"); 
      Log.d("DownloadManager", "download speed: "+ratevalue);  
    } catch (IOException e) { 
     Log.d("DownloadManager", "Error: " + e); 
    } 

예 출력

10-08 15:09:52.658: D/DownloadManager(13714): download ended: 70 secs 
10-08 15:09:52.662: D/DownloadManager(13714): download speed: 585.14 Kbps 

감사합니다. 더 나은 방법이 있다면 알려 주시기 바랍니다.

+0

한 번에 한 바이트 씩 읽는다면 상당히 길어질 수 있습니다. 바이트 []를 사용하지 않고 한 번에 여러 KB를 읽는 것이 어떻습니까? – njzk2

+0

일반적으로 매초마다'read'와'append' 호출이 ~ 600K입니다. – njzk2

+0

또한'size','endTime' 및'startTime'가 1024, 1000 및 8처럼 정수이기 때문에 비율 값이 정확하지 않을 수 있습니다. 따라서 long으로 형변환되기 전에 정수로 계산됩니다 부정확 한 mesure를 제공해야하지만 관찰 한 큰 차이에 대해서는 책임을지지 않습니다. – njzk2

답변

2

내 의견에 따라, 여기에 스트림

//Define InputStreams to read from the URLConnection. 
InputStream is = ucon.getInputStream(); 
BufferedInputStream bis = new BufferedInputStream(is); 

//I usually use a ByteArrayOutputStream, as it is more common. 
ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
int red = 0; 
// This size can be changed 
byte[] buf = new byte[1024]; 
while ((red = bis.read(buf)) != -1) { 
    baos.write(buf, 0, red); 
} 

이것이하는 일은 그것이 바이트 [] 버퍼에 읽어들입니다에서 여러 바이트를 읽고, 읽기 바이트의 양을 반환하는 방법의 예입니다. 이것은, OutputStream에 기입 해져 기입하는 바이트 수를 지정합니다.

ByteArrayOutputStream도 비슷하게 동작합니다. 당신이 정말로에만 다운로드 속도에 대해 걱정하는 경우,

// Simply start by defining the fileoutputstream 
FileOutputStream fos = new FileOutputStream(file); 
int red = 0; 
// This size can be changed 
byte[] buf = new byte[1024]; 
while ((red = bis.read(buf)) != -1) { 
    // And directly write to it. 
    fos.write(buf, 0, red); 
} 
long endTime = System.currentTimeMillis(); //maybe 
// Flush after, as this may trigger a commit to disk. 
fos.flush(); 
fos.close(); 

또한 : 당신이 작업을 파일에 쓰기가 읽기 기능보다 훨씬 빠르다는 것을 고려한다면

또는, 당신은 또한 파일에 직접 기록 할 수 있습니다 , 파일에 쓰는 것이 필수적인 것은 아니며 어느 곳에서든지 충분할 수 있습니다.

long size = 0; 
byte[] buf = new byte[1024]; 
while ((red = bis.read(buf)) != -1) { 
    size += red; 
} 
+0

빨리 돌아 오지 못해 죄송합니다. 세부적인 응답에 정말 감사드립니다. 나는 두 가지 방법 모두를 시도해 보았고 궁극적으로는 다운로드 속도에만 집중하고자하는 데이터 크기를 쓰지 않는다는 제안을했습니다. 여러 바이트로 변경된 이후로 내 결과는 그 또는 다른 속도 테스트에 근접해야합니다. 다시 한 번 예를 들어 주셔서 감사 드리며 완벽하게 작동했습니다. – Joffroi