Javaでコンテンツダウンロード時のプログレス更新処理

このQ&Aのポイント
  • Java(Android)にてサーバーからコンテンツをダウンロード行う際に進捗具合をプログレスバーに表示させる処理を考えています。
  • org.apache.http.HttpResponseのwriteTo(OutputStream)を使用してファイルに直接書き出しているが、書き込みの進捗を取得する方法がわからない。
  • ファイルサイズはHttpResponse response = httpclient.execute(httppost);のgetContentLength()メソッドで取得できる。ネットワークプログラムに関する知識が不足しているため、助けを求めている。
回答を見る
  • ベストアンサー

コンテンツダウンロード時のプログレス更新処理について

コンテンツダウンロード時のプログレス更新処理について Java(Android)にてサーバーからコンテンツをダウンロード行う際に進捗具合をプログレスバーに表示させる処理を考えてます。 org.apache.http.HttpResponseのwriteTo(OutputStream)を使用してファイルに直接書き出してますが書き込みの進捗をどのように取得すればよいのかわかりません。 全体のファイルサイズは下記のように取得出来ました。 HttpResponse response = httpclient.execute(httppost); total = (int)response.getEntity().getContentLength(); 経験不足でネットワークプログラム自体よくわかってませんがよろしくお願いします。

  • Java
  • 回答数1
  • ありがとう数5

質問者が選んだベストアンサー

  • ベストアンサー
  • salsberry
  • ベストアンサー率69% (495/711)
回答No.1

writeTo()を使わずに自分でInputStreamからデータを読んでOutputStreamへ書き込めば、読み込み/書き込み済みのサイズを計算できると思います。下のコードは試していません。 HttpEntity entity = httpResponse.getEntity(); long size = entity.getContentLength(); InputStream is = entity.getContent(); byte[] buf = new byte[1024]; long sum = 0; int n; while ((n = is.read(buf, 0, buf.length)) > 0) { sum += n; → このsumとsizeの値を使ってプログレスバーを表示 bufの内容をOutputStreamへ出力 }

masakazu_s
質問者

お礼

回答ありがとうございます。 非常に簡単なことで申し訳ないです。 おかげさまで上手くできました。

関連するQ&A

  • サーブレットでのファイルダウンロードについて

    サーブレットでファイルのダウンロードを 行うプログラムを作成しているのですが ときどきダウンロードするファイルが切れている 場合があります。 なので実際のファイルとダウンロード時のファイル の違いがあった場合はJSPでalert表示を行いたい のですが、うまく実行できません。 処理としては response.setHeader(......) response.setContentType(......) 等の設定を行い ダウンロードするファイルのInputStream を作成、OutputStreamにgetOutputStream() を取得してwriteしています。 上記のwriteする時に件数をカウントして このサーブレットの呼び元のjspに返却したい のですが、取得ができません。 何か参考になるサイトなどないでしょうか? よろしくお願いします。

    • ベストアンサー
    • Java
  • AndroidアプリのXML送受信

    Androidのアプリとサーバー間でXMLを送受信するという処理を考えています。 http://blog.5ive.info/archives/1040 のsampleを参考にしたのですが、判らない事があります。 ------------------------------------------------------------------------------------------- 【以下、sampleを抜粋】 //[クライアント設定] HttpClient httpclient = new DefaultHttpClient(); HttpPost httppost = new HttpPost(url); //[POST送信するデータを格納] List<NameValuePair> nameValuePair = new ArrayList<NameValuePair>(1); nameValuePair.add(new BasicNameValuePair("name", "simo")); nameValuePair.add(new BasicNameValuePair("text", "hello!")); //-----[POST送信] httppost.setEntity(new UrlEncodedFormEntity(nameValuePair)); HttpResponse response = httpclient.execute(httppost); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); response.getEntity().writeTo(byteArrayOutputStream); ------------------------------------------------------------------------------------------- 送信する際にList<NameValuePair>というListに格納していますが、NameとValueと2つのパラメータが必要で、XMLのデータのみの送信にNameは必要ありません。 単純にXMLのデータだけを送信したいのですが、httppostでデータを送信するにはList<NameValuePair>を使用するしかないのでしょうか? もし駄目なら、AndroidでXMLを送受信するにはどうしたら良いのでしょうか?

  • HTTPでPOSTしてgooメールにログイン

    Javaを使用して、HTTPでgooメールにログインしたいのですが、うまくいきません。 サンプルを探して試しているのですが、レスポンスに「302」が返却されます。 HTTPヘッダの情報が足りないのか、POSTするデータが足りないのか、 はたまた、その他なにかしらが足りないのか、ご存知の方がおりましたら、教えて頂けないでしょうか? 以下apacheのhttpclientを使ったレスポンスに「302」が返却されるプログラムです。 public class http_test { public static void main(String[] args) { try { String url = "https://login.mail.goo.ne.jp/id/authn/Login"; String id = "gooID"; // gooID ※質問用にダミー値を設定 String pass = "password"; // パスワード ※質問用にダミー値を設定 String params = "uname="+ id +"&pass=" + pass + "&Site=mail.goo.ne.jp&Success=http://mail.goo.ne.jp"; HttpPost httpPost = new HttpPost( url ); DefaultHttpClient httpClient = new DefaultHttpClient(); StringEntity paramEntity = new StringEntity( params ); paramEntity.setChunked( false ); paramEntity.setContentType( "application/x-www-form-urlencoded" ); httpPost.setEntity( paramEntity ); HttpResponse response = httpClient.execute( httpPost ); int status = response.getStatusLine().getStatusCode(); if ( status != HttpStatus.SC_OK ) { // ここで「302」が返却される System.out.println(status); throw new Exception( "" ); } }catch(Exception e) { e.printStackTrace(); } } }

  • ApacheサーバによるコンテンツのFTPダウンロードに関して

    ApacheでWebサーバを構築しています。 ファイルをダウンロードさせるサイトを作りたいのですが、FTPでファイルをダウンロードさせるには、コンテンツをどのように置けば、よろしいのでしょうか? 参考となるURLを教えていただければ、幸いです。 以上、よろしくお願いいたします。

  • javascriptによるプログレスバーの表示制御

    javascriptで任意の処理を実行中に、HTMLのプログレスバーの表示を制御する方法をご教示ください。 ただし、JQueryなどのライブラリは使わないものとします。 実現したい処理は以下です。 (1):処理開始時にプログレスバーを表示  (HTMLに定義されている<progress>を表示) (2):処理A実行 (3):プログレスバーの進捗を50%に更新 (4):処理B実行 (5):プログレスバーの進捗を100%に更新 (6):処理終了時にプログレスバーを非表示 上記を実現するために、例えば以下のようなコードを書いても、(1)~(6)の全処理が終わった結果が画面に反映されるため、画面上はプログレスバーは表示されません。 <progress id="prog" max="100" value="0" style="display:none">Loading...</progress> <script> //(1):処理開始時にプログレスバーを表示 document.getElementById("prog").style.display = 'block'; //(2):処理A実行(仮の処理としてsleep) Sleep(3); //(3):プログレスバーの進捗を50%に更新 document.getElementById("prog").value = '50'; //(4):処理B実行(仮の処理としてsleep) Sleep(3); //(5):プログレスバーの進捗を100%に更新 document.getElementById("prog").value = '100'; //(6):処理終了時にプログレスバーを非表示 document.getElementById("prog").style.display = 'none'; //Sleepメソッド(テスト用) function Sleep(T){ var d1 = new Date().getTime(); var d2 = new Date().getTime(); while( d2 < d1+1000*T ){ d2=new Date().getTime(); } return; }; </script> プログレスバーの進捗を更新する度に、画面にその内容を反映するにはどのようにしたらよいのでしょうか。

  • HttpPostでクエリが送信できない

    とりあえずAndroidのソースなのでAndroidのカテゴリにします 次のようなスクリプトをeclipseで組んでみたのですが、実際に実行するとparamsで指定したクエリが全く送信できていません。javaです。 connectUrlはhttp://shindanmaker.com/(診断ページ番号)で、 paramsには "u" : (診断内容) "from" : ""(空の文字列) が入っています。 文字化けは大丈夫です。 アドバイスお願いします。 public String httpPostRequest( String connectUrl, List<NameValuePair> params, String encode ){ //-----[クライアント設定] try { HttpClient httpclient = new DefaultHttpClient(); // MultipartEntity entity = new MultipartEntity(); //テキストの送信 // for( NameValuePair pair : params ){ // entity.addPart( pair.getName(), new StringBody(pair.getValue(),Charset.forName(HTTP.UTF_8))); // } // entity.addPart(filePair.getName(), new FileBody(file,"application/octet-stream")); HttpPost httppost = new HttpPost(connectUrl); httppost.setURI(new URI(connectUrl)); httppost.setHeader("User-Agent", "Android"); httppost.setHeader("Content-type","text/html"); httppost.setHeader("Content-Type", "multipart/form-data"); httppost.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE,false); //-----[POST送信] httppost.setEntity(new UrlEncodedFormEntity(params, encode)); HttpResponse response = httpclient.execute(httppost); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); response.getEntity().writeTo(byteArrayOutputStream); //-----[サーバーからの応答を取得] if(response.getStatusLine().getStatusCode() != HttpStatus.SC_OK){ Toast.makeText(this, "[error]: "+response.getStatusLine(), Toast.LENGTH_LONG).show(); return null; } // return EntityUtils.toString( response.getEntity());//.getBytes( encode ).toString(); return byteArrayOutputStream.toString(); } catch (Exception e){ e.printStackTrace(); return null; } }

  • Javaのファイルダウンロードについて

    Javaでファイルのダウンロード機能を作成しています。 環境はWebサーバにapache、APサーバにGlassfish、連携としてmod_jk、あとはJava6を使用しています。 InpusStreamでファイルパスから取得しresponse.getOutputStream()に書き込む処理writeにて org.apache.catalina.connector.ClientAbortExceptionが発生してしまいます。 その際にダウンロードのポップアップ(開く、保存、キャンセル)が開きますがExceptionが発生しているため保存できません。 ただしファイルのサイズによっては正常に保存できます。(ファイルサイズが500Mくらいだとダメ) なお、ClientAbortExceptionはキャンセル押したときに発生すると思われますがそのほかにどのような場合に発生するのでしょうか? また、対処方法を知っていましたらご教授ください。

  • 探しています~プログレスバーのまき戻しについて

    何か処理中のものがあり、進捗状態がプログレスバーに表示されているのですが、キャンセルボタンを押すとその処理を中断できて、それまで進んでいたプログレスバーの進捗が徐々に減っていき、最終的にゼロに戻るという仕組みの画面というか、UIを探しています。 ソフトのインストールとかファイルのコピーとか色々探しているのですがなかなか見つかりません。 似たような動作をするプログラムを作りたいので参考にしたいのですが・・・。 どなたか知っている方がいれば教えてください!

  • Zend Framework で大きなファイルをダウンロードしたい

    ホームページをtarでバックアップしてZend Frameworkでダウンロードしたいのですが、 http://php.benscom.com/manual/ja/function.readfile.php を参考に次の様にしてみたところ、数Mbyte程度のファイルはダウンロードできましたが大きなファイル(200Mbyte)ではエラーになりました。 public function DownloadAction(){ $file = "test.bin"; $this->_helper->viewRenderer->setNoRender(); $response = $this->getResponse(); $response->clearAllHeaders(); $response->clearBody(); $response->setRawHeader('Content-Description: File Transfer'); $response->setRawHeader('Content-Type: application/octet-stream'); $response->setRawHeader('Content-Disposition: attachment; filename='.basename($file)); $response->setRawHeader('Content-Transfer-Encoding: binary'); $response->setRawHeader('Expires: 0'); $response->setRawHeader('Cache-Control: must-revalidate, post-check=0, pre-check=0'); $response->setRawHeader('Pragma: public'); $response->setRawHeader('Content-Length: ' . filesize($file)); $response->sendHeaders(); $response->setBody(file_get_contents($file)); $response->outputBody(); } それで $response->setBody(file_get_contents(&$file)); $response->outputBody(); の部分を $handle = fopen($file, "rb"); $contents = ''; while (!feof($handle)) { $contents = fread($handle, 8192); $response->setBody($contents); $response->outputBody(); } fclose($handle); とかにしてみましたがこれもファイルが途中で切れてしまいました。 php.iniのメモリ量を増やす以外に、何か方法がありますでしょうか?

    • ベストアンサー
    • PHP
  • Xercesを使ったjavaでのXML解析

    DOMを使ってXML文書を解析するJavaのソースコードで、DOMパーサは、クラス org.apache.xerces.parsers.DOMParserで参照している下記のプログラムで、 [Fatal Error] :17:109: The entity name must immediately follow the '&' in the entity reference. org.xml.sax.SAXParseException; lineNumber: 17; columnNumber: 109; The entity name must immediately follow the '&' in the entity reference. のエラーが出てしまって、解決策が分かりかねています。Javaのネットワークプログラミングに詳しい方、御教示願えればと思います。 package nikkei; import java.io.ByteArrayInputStream; import org.apache.xerces.parsers.DOMParser; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; public class TwitterSearch { public static void main(String[] args) throws Exception { TwitterSearch search = new TwitterSearch(); search.search("日経ソフトウエア"); } public void search(String keyword) throws Exception { SearchAPIClient client = new SearchAPIClient(); String xml = client.execute(keyword); parse(xml); } private void parse(String xml) throws Exception { DOMParser parser = new DOMParser(); try { parser.parse(new InputSource(new ByteArrayInputStream(xml.getBytes()))); Document doc = parser.getDocument(); NodeList entries = doc.getElementsByTagName("entry"); for (int i = 0; i < entries.getLength(); i++) { String name = null; String tweet = null; Element entry = (Element) entries.item(i); NodeList titleList = entry.getElementsByTagName("title"); if (titleList.getLength() == 1) { tweet = titleList.item(0).getTextContent(); } NodeList authorList = entry.getElementsByTagName("author"); if (authorList.getLength() == 1) { Element author = (Element) authorList.item(0); NodeList nameList = author.getElementsByTagName("name"); if (nameList.getLength() == 1) { name = nameList.item(0).getTextContent(); } } System.out.println(name + "さんのツイート"); System.out.println("\t" + tweet); } } catch (Exception e) { e.printStackTrace(); } } } package nikkei; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.util.EntityUtils; public class SearchAPIClient { public String execute(String keyword) throws Exception { String url = "https://twitter.com/search?q=" + keyword; HttpClient httpClient = new DefaultHttpClient(); HttpGet httpGet = new HttpGet(url); HttpResponse response = httpClient.execute(httpGet); HttpEntity entity = response.getEntity(); if (entity != null) { return EntityUtils.toString(entity); } else { return null; } } } よろしくお願いいたします。

    • ベストアンサー
    • Java

専門家に質問してみよう