• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:ファイルのダウンロードが遅い)

ファイルのダウンロードが遅い

satomi3951の回答

  • ベストアンサー
回答No.1

1バイトずつ読み込んでいる&全部読み込んでから送ってるので遅いのでしょう。 ブロック単位で読む&逐次送信するといいですよ。 File zipFile = new File("ファイルパス", "temp.zip"); response.setContentType("application/octet-stream; charset=Windows-31J"); response.setHeader("Content-Disposition","attachment; filename=\"temp.zip\""); response.setContentLength(zipFile.length); int len; byte[] buf = new byte[1024]; InputStream is = new FileInputStream(zipFile); ServletOutputStream os = response.getOutputStream(); while((len = is.read(buf)) >= 0){ // bufのサイズまで読み込む、実際に読んだ長さはlenに入る os.write(buf, 0, len); // 読み込んだサイズ分送信する } is.close(); os.close();

Kafka_F
質問者

お礼

早急なご回答有難うございます。 ご教授して頂いた方法に変更して実行してみました。 読み込みとレスポンス送信は1秒たらずでできるようになりました。 ただ、いまだにすぐにダイアログが表示されません。 os.close();の後は何も処理はしておらず、returnで戻してるだけなのですが・・・。 今回の環境と実行は、大量データがDBにある時かつ大量データの 抽出する目的でおこなっています。 データが少ない時は全く問題がありませんでした。 大量データのテストの時は、DBから抽出するのに3分→CSV作成に8分→ 圧縮は1秒の過程です。でも、圧縮後のzpファイルは15kb程なので ファイルが重過ぎることではないと思います。 なにか他に原因があるのでしょうか?

関連するQ&A

  • テキストファイルが読み込めない

    みなさんはじめまして、下記ソースなんですが「FileInputStream fi = new FileInputStream(inputFile);」の手前までは処理が流れるの ですが、その後の処理が流れなくて困っています。 ターゲットとなる「test.txt」ファイルはHTML・JAVAソースファイル クラスファイルと同じフォルダに存在します。 特に保存先等を指定していないので、必然的に同じフォルダ内を見てフ ァイルを読み込みに行くんですけど、読み込まず、そのまま処理が流れ てしまいます。 どこかやり方がいけないところがあるんでしょうか? public String FileInput(){ byte data[] = new byte[16]; String number = ""; try { File inputFile = new File("test.txt"); FileInputStream fi = new FileInputStream(inputFile); /* データを読み込み */ if(fi.read(data)== 16){       /* 0バイト目から9バイト目までを読み込み */ if(new String(data,0,9).equals("010105502")){         /* 0バイト目から16バイト目までをnumberに代入 */ number = new String(data,0,16); } } fi.close(); } catch(FileNotFoundException e){ e.printStackTrace(); } catch(IOException e){} return(number); }

    • ベストアンサー
    • Java
  • ファイル圧縮について。

    ファイル圧縮について質問させてください。 以下のようなメソッドを作成したのですが、 public run(String strFiles[], String strZipFileName) { int i = 0; int iLen = 0; FileInputStream fis = null; FileOutputStream fos = null; ZipOutputStream zos = null; ZipEntry zent = null; byte[] buf = new byte[1024*10*10]; try { fos = new FileOutputStream(strZipFileName); zos = new ZipOutputStream(fos); for (i = 0; i < strFiles.length(); i++) { fis = new FileInputStream(strFiles[i]); zent = new ZipEntry(strFiles[i]); zos.putNextEntry(zent); while (-1 != (iLen = fis.read(buf))) { zos.write(buf, 0, iLen); } zos.flush(); zos.closeEntry(); fis.close(); } } catch(Exception e) { System.err.println(e); } finally { try { zos.close(); // ※1 fos.close(); // ※2 } catch(Exception e) { System.err.println(e); } } } サイズの小さいファイルや、 特定のサイズのファイル(13k程度)を対象とした時、 高い確率で、空の圧縮ファイルが作成される事があります。 ログを出力しながら確認すると、このような現象が起きた場合、 圧縮ファイルをcloseする直前(※1)では作成されたファイルはサイズがあるのですが、 圧縮ファイルをcloseした直後(※2)ではファイルのサイズが0になってしまいます。 また、2台あるサーバの内、1台だけでこの現象が起こっています。 javaのバージョンは1.3です。 何故このような現象が起こってしまうのか、 ご存知の方がいらっしゃいましたら教えていただけないでしょうか。 宜しくお願いします。

    • ベストアンサー
    • Java
  • strutsでファイルダウンロード(WinでOK,linuxでNG)

    strutsでWindowsのexeファイルのダウンロードを実装しましたが、Windows上のtomcatにdeployすると正常にダウンロードできるのに、linux(fedora-core3)上のtomcatにdeployすると、ダウンロードしたファイルがhtmlになってしまいます。 hoge.exeという名前のファイルはダウンロードできるのですが、それが実はテキストで、メモ帳で開くと、ダウンロード画面のhtmlが表示されます。 この状況は何によって生み出されているのでしょうか。 お分かりになる方、ヒントをお願いいたします。 以下にファイルダウンロード部のソース(抜粋)を掲載させていただきます。 ----- 以下ソース ----- protected void download(HttpServletResponse response, String fileType, String filename) { try { // exeファイルのダウンロード時 if (fileType.equals("application/octet-stream")) { response.setHeader("Content-Disposition", "attachment; filename=" + filename); } response.setContentType(fileType); BufferedInputStream bis = new BufferedInputStream(new FileInputStream(filename)); BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream()); byte[] buf = new byte[128]; int size; while ((size = bis.read(buf, 0, buf.length)) != -1) { bos.write(buf, 0, size); } bos.close(); bis.close(); } catch (IOException e) { throw new thisSystemException("could not send file[" + filename + "]"); }

    • ベストアンサー
    • Java
  • ファイルの入出力をするプログラム

    1週間前からJAVAを勉強しております。 簡単な練習で、テキストファイル(test.txt)に縦一列に並んでいる数字を読み込み別のテキストファイルに書き込むプログラムを作っておりますが FileInputStream file = new FileInputStream("test.txt"); file.read(buf_byte); for(i=0;i<=10;i++)buf_char[i]=(char)buf_byte[i]; という感じで恐らく回りくどいことをしてると思いますが、ダイレクトに文字を読み込む方法がわかりません。 よろしくお願いします。

    • ベストアンサー
    • Java
  • JAVAで別端末へファイル転送

    JAVAで端末から端末にファイルを自動的に転送するプログラムを作成しています。転送手段はUNC(\\path)形式で以下のソースのように転送しています。 -------------------------------------------------- ※READ_FILE → 送信側ファイルパス  WRITE_FILE → 受信側ファイルパス //ファイルを読み込む FileInputStream readFile = new FileInputStream(READ_FILE); //読み込んだファイルを書き込む File writeFile = new File(WRITE_FILE); writeFile.createNewFile(); FileOutputStream fo = new FileOutputStream(writeFile); int count = 0; byte[] buf = new byte[16384]; while ((count=readFile.read(buf)) != -1) { fo.write(buf, 0, count); } readFile.close(); fo.close(); -------------------------------------------------- ここで問題になってしまったのが、認証です。エクスプローラでその端末の認証をすませてしまえば、問題なくこのソースは通るのですが、認証せずに実行すると FileInputStream readFile = new FileInputStream(READ_FILE); のところで落ち FileNotFoundException:(ログオン失敗: ユーザー名を認識できないか、またはパスワードが間違っています。) となってしまいます。 JAVAで認証するためにログオンするようなクラスはありますか?そのクラスの使い方、ソース、参考になるようなホームページがありましたら、教えてください。 よろしくお願い致します。

  • Javaアプリでデバイスファイルを制御

    SDIOインターフェイスにより接続されたSDIOホスト機器とSDIOデバイス機器との間で、SDIOホスト機器上で動作するJava swingアプリから、SDIOデバイス機器へ、通信試験をしています。SDIOホスト上で動作環境は以下の通りです。 OS:Ubuntu 12.10 server Java:version7 ホスト上で動作するSDIOデバイス機器用のデバイスドライバ:ttyドライバ 以下のプログラムでwriteは正常に動くのですが、readが実行されません。 ttyドライバは、デバイスファイルとして、別の場所にてFile file = new File("/dev/ttyPontos0;で宣言しています。reaed関数のin.available();の戻り値は、0が変えてきてしまいreadできないという状態です。お気付きの点ありましたら、大変ありがたいです。宜しくお願い致します。 public void actionPerformed(ActionEvent event) {   int i,rev_bytes; if(event.getActionCommand().equals("register_read")) { char[] cmd1 = {'s','h','o','w',' ','r','e','g',' ','-','r',' ','0','x',/*11*/'0','0','4','0','5','4','A','0','\r'}; byte[] txdata = new byte[cmd1.length]; byte[] rxdata = new byte[126];          for(i=0;i<cmd1.length;i++) { txdata[i]=(byte)cmd1[i]; } logfild.setText("register_read\n");     send_byte2(txdata,cmd1.length);/*byte列を送信*/ }else if(event.getActionCommand().equals("register_write_all")) { byte[] rxdata = new byte[126];        logfild.setText("receive\n");     rev_bytes=receive2(rxdata); String f = new String(rxdata); logfild.setText("rxdata=\n"+ f); } } public void send_byte2(byte[] senddata,int length) { try {       /*fileは別の場所で宣言しています*/ out = new FileOutputStream(file); out.write(senddata); out.close();/*書込み終了*/ logfild.append("\nFileOutputStream1_success\n"); } catch (IOException e) { // TODO 自動生成された catch ブロック logfild.append("FileOutputStream1_fail\n"); e.printStackTrace(); } } /*バッファにあるだけ受信する*/ public int receive2(byte[] receive) { int Bytes=0,num; try {        /*fileは別の場所で宣言しています*/ FileInputStream in = new FileInputStream(file); num=in.available();//read可能なバイト数を返す logfild.append("read_num\n"+num); Bytes=in.read(receive); in.close(); } catch (IOException e) { logfild.append("read_fail\n"); e.printStackTrace(); } return Bytes; }

  • javaで大容量テキストファイルの読み込みについて

    お世話になっております。 現在javaにて大容量のテキストファイル(100M以上)を読み込んで、 特定の文字が含まれている行のみを別ファイルへ抽出するという プログラムを作成しています。 現在のロジックでは、 File file = new File( "読み込みファイル" ); byte[] b = new byte[ (int) file.length() ]; FileInputStream fis = new FileInputStream(file); fis.read(b); String str = new String(b, "Shift-JIS"); return str; 上記の様なのようなロジックのメソッドを作成し、 返り値の文字列を改行コードでsplitし、パターンマッチングして行を抽出する方法をとっています。 しかしこの方法だと、OutOfMemoryErrorが発生していまい、 30MB以上のファイルを読み込むことができません。 原因がJVMのメモリ領域の問題なのは理解していますが、 readLineをでためしてみると処理終了があまりにも遅すぎるため、 なるべく現在の手法を改良する方向で作成したいのですが、 一回目 :0 ~ 30000000byte まで 二回目 :30000001 ~ 60000000byte まで の様にJVMの設定はいじらない方法でファイルのデータを、 指定バイトから指定バイトまで読み込む方法等なないでしょうか? それ以外でも処理が早く、 大容量のテキストファイルを読み込む方法がありましたら、 そちらでも問題ありません。 ぜひとも知恵をお貸しください。 宜しくお願いします。

    • ベストアンサー
    • Java
  • Zipファイル解凍処理について

    こんにちわ。 Javaの解凍処理について質問です。 Test.zipがあって、その中身が「テスト.xls」とした時、うまく解凍ができません。 Zipファイルの中身が日本語名ではなく、「Test.xls」であれば正常に解凍ができます。 下記の書き方では日本語名のファイルの入ったZipファイルを解凍することはできないのでしょうか? どなたかご教授お願い致します。 String fname = null; FileInputStream fis = null; BufferedInputStream bis = null; ZipInputStream zis = null; ZipEntry zent = null; FileOutputStream fos = null; try { fis = new FileInputStream(FilePath); bis = new BufferedInputStream(fis); zis = new ZipInputStream(bis); byte[] buf = new byte[1024]; int len; // アーカイブ中に含まれるファイル情報の取得 while ((zent = zis.getNextEntry()) != null) { int intResult = zent.toString().indexOf("."); int intLength = zent.toString().length(); //ファイル名の変更(フォルダ名+社員コード)StringBuffer BuffRename = new StringBuffer(); BuffRename.append("D:\\test\\"); BuffRename.append(zent.getName().substring(0,intResult)); BuffRename.append(SyainCd); BuffRename.append(zent.getName().substring(intResult,intLength)); fname = BuffRename.toString(); //書き込みファイルをオープン fos = new FileOutputStream(fname); while (-1 != (len = zis.read(buf, 0, buf.length))) { fos.write(buf, 0, len); } //★★★ fos.close(); } Catch・finallyは省略

  • ファイル転送が正常に動作しない

    サーバ側からクライアント側へファイル転送をJavaで行おうとしています。 そこで以下のようなプログラムを作成し、実行するのですが 実行自体はうまくいき、1つめのファイルはきちんと転送できるのですが、 2つめのファイルが転送完了後に確認すると0バイトとなっており、 きちんと動作しません。どうするべきでしょうか。 サーバ側 ※上でソケットはつないであります。 if(command.equals("put.") == true){ System.out.println("putモードに入りました"); // カーネル(linux.uml)の送信 String filename1 = args[1]; byte[] data1 = new byte[1024]; //ストリームの作成 FileInputStream fin1= new FileInputStream(filename1); BufferedOutputStream out2 = new BufferedOutputStream(sock.getOutputStream()); System.out.println("送信ファイル : " + filename1); //int totalSize1 = 0; int len1; while((len1 = fin1.read(data1)) != -1){ out2.write(data1); } out.flush(); fin1.close(); System.out.println(filename1 + "を送信完了しました"); // ルートファイルシステム(uml-root-hardy)の送信 String filename2 = args[2]; byte[] data2 = new byte[1024]; //ストリームの作成 FileInputStream fin2 = new FileInputStream(filename2); //ファイルの内容を読み出し、送信する System.out.println("送信ファイル" + filename2); //long totalSize2 = 0; long len2 = 0; while((len2 = fin2.read(data2)) != -1){ out2.write(data2); } out.flush(); fin2.close(); System.out.println(filename2 + "を送信完了しました"); } クライアント側 ※上でソケットはつないであります。 if(change.equals("put.") == true){ System.out.println("putモードに入りました"); // 2つのファイルを転送する // カーネル(linux.uml)の転送 String filename1 = args[2]; System.out.println("受信するファイル : " + filename1); // FileOutputStreamの作成 FileOutputStream fout1 = new FileOutputStream(filename1); BufferedInputStream in2 = new BufferedInputStream(sock.getInputStream()); int recvMsgSize1; int bufSize = 1024; byte[] byteBuffer1 = new byte[bufSize]; //int totalByte1 = 0; while((recvMsgSize1 = in2.read(byteBuffer1)) != -1){ fout1.write(byteBuffer1); } System.out.println(filename1 + "を受信完了しました"); fout1.close(); // ルートファイルシステム(uml-root-hardy)の転送 String filename2 = args[3]; System.out.println("受信するファイル : " + filename2); FileOutputStream fout2 = new FileOutputStream(filename2); long recvMsgSize2; //byte[] byteBuffer = new byte[bufSize]; byte[] byteBuffer2 = new byte[bufSize]; //long totalByte2 = 0; while((recvMsgSize2 = in2.read(byteBuffer2)) != -1){ fout2.write(byteBuffer2); } System.out.println(filename2 + "を受信完了しました"); fout2.close(); } またプログラム中では、サーバ、クライアントでそれぞれ len1,len2(サーバ側)、recvMsgSize1,recvMsgSize2(クライアント側) に警告で「ローカル変数len1(recvMsgSize1)は読み取られません」 と出ています。 どのように解決するべきでしょうか。

    • ベストアンサー
    • Java
  • C#テキストファイルから1バイト除去する

    数ギガのテキストファイルがあり、語尾の1バイト(EOF)を瞬時に除去したいと思います。 バイトで読んで1バイトのみ出力しないと言う方法が一番簡単ですが、時間がかかる上、巨大ファイルには向きません。 下記語尾を置換するソースを書きましたが、除去の方法がわかりません。初心者ですので、簡単にお願いします。 FileStream fs = new FileStream("test.txt", FileMode.Open); byte[] b = new byte[1]; fs.Seek(fs.Length - 1, SeekOrigin.Begin); fs.Write(b, 0, 1); fs.Close();