- PR -

WEBアプリケーションのダウンロード処理について

投稿者投稿内容
酢味噌
会議室デビュー日: 2002/10/01
投稿数: 10
投稿日時: 2002-10-01 11:00
先ほど超がつくほどの会議室違いを犯し、赤面中の酢味噌です。
ここで改めて質問させてください。

現在Java,Tomcat,Apache,Oracleを使用してWEBアプリケーションを作ってます。
JSPでマスタ名を指定してOracleにあるマスタを全件ダウンロードさせる処理を
作っているのですが、ダウンロードする件数が大きくなると時間が異常にかかります。
処理の流れは

JSPでマスタを指定

メインサーブレットでダウンロードを行うサーブレットを呼ぶ

サーブレットでマスタ取得のBeanを実行させる

取得結果を〜.csvとしてダウンロード

となっています。
Oracleから持ってきたデータをカンマ編集しながら変数に格納している辺りが
問題なのではと思うのですが、どう対応すべきかわかりません。
必要であればソースも掲載します。
アドバイスよろしくお願いします。
ron
常連さん
会議室デビュー日: 2002/08/19
投稿数: 46
投稿日時: 2002-10-01 11:37
はじめまして。

 自分もそんなにJavaは詳しくないのですが、ソースとダウンロードデータの
データ件数、データサイズぐらいを教えていただけると、アドバイスをする人も
し易くなると思います。

 ちなみにカンマ編集が遅いと思っているそうですが、StringBufferで文字列の連結
等を行っていますか?

Anthyhime
ぬし
会議室デビュー日: 2002/09/10
投稿数: 437
投稿日時: 2002-10-01 12:49
CSVを生成している部分のソースを見せてください。
酢味噌
会議室デビュー日: 2002/10/01
投稿数: 10
投稿日時: 2002-10-01 13:02
ronさん、Anthyhimeさん
レスありがとうございました。
サーブレットのソースの抜粋です。
見にくい部分もあるかと思われますがぜひお願いします。
DLしようとしているデータですが、項目数が90項目、件数が1万件弱です。


try{
 //ダウンロード処理
 String s = dataGet();

 aResponse.setContentType("application/octet-stream");
 aResponse.addHeader("Content-Disposition","attachment;filename=" +fileName+ ".csv\"");

 DataOutputStream out = new DataOutputStream(aResponse.getOutputStream());
 String line;
 StringReader stringReader = new StringReader(s);
 BufferedReader bufReader = new BufferedReader(stringReader);
 while((line = bufReader.readLine()) != null){
 out.writeBytes(new String((line + "\n").getBytes("SJIS"),"ISO8859_1"));
}
 out.close();
 out.flush();
 stringReader.close();

}catch(Exception exception){
System.out.println(exception);
throw new OriginalException("ダウンロードエラー");
}


public String dataGet() throws OriginalException{
try{
String s="";

if(fileName.equals("XXXXMST")){
LogPrint.writeLog(4," GetDownLoadMst:dataGet() ileName="+fileName);
s = getMst();

}
LogPrint.writeLog(4," GetDownLoadMst:dataGet() END");
return s;

}catch(Exception e){
System.out.println(e);
throw new XXXXException("データ格納エラー");
}



private String getMst() throws OriginalException{
try{
//Bean発行
GetXXXMstListBean GetXXXMstListBean = new GetXXXMstListBean();

//Beanにダウンロードするマスタファイル名をセット
GetXXXMstListBean.setFileName(fileName);

//Bean実行
GetXXXMstListBean.Execute();

//データ格納用変数
String s = "";

//XXXMSTのデータを格納
for(int dataCount=0;dataCount<GetLoginMstListBean.getSomeSystemIds().size();dataCount++){

s += (GetXXXMstListBean.getAAAA().get(dataCount).toString())+",'";
s += (GetXXXMstListBean.getBBBB().get(dataCount).toString())+",'";
s += "\n";
}
return s;
}catch(Exception e){
throw new XXXXException("データ格納エラー");
}
}
amnaky
ベテラン
会議室デビュー日: 2002/09/13
投稿数: 75
お住まい・勤務地: 東京
投稿日時: 2002-10-01 13:31
とりあえず、
+=
で文字列を連結するよりも
StringBufferクラスを使用したほうがいいです。
なぜかはJavaDocかなにかを読むといいと思います。

あと、コレクションでデータを保持していると思いますが、
何のクラスを使用していますか。
配列か、Vector,ArrayList,LinkedList
など。
Indexでランダムアクセスすると遅くなる場合が
あります。
酢味噌
会議室デビュー日: 2002/10/01
投稿数: 10
投稿日時: 2002-10-01 13:38
レスありがとうございます。
データの保持にはVectorを使用しています。
早速StringBufferを使ってやってみようと思ったら、
別のプログラムを作るように指示が出たのでそちらを片付けてからにします。
未記入
ぬし
会議室デビュー日: 2002/03/28
投稿数: 255
投稿日時: 2002-10-01 14:38
>とりあえず、
>+=
>で文字列を連結するよりも
>StringBufferクラスを使用したほうがいいです。
>なぜかはJavaDocかなにかを読むといいと思います。
これって,そもそも連結した単一の文字列を作る必要が無いのでは?
途中結果を直接,出力ストリームに流すだけで良さそうなんですが.

いずれにせよ,基礎の基礎もまるでなってないのは確かなようです.
Anthyhime
ぬし
会議室デビュー日: 2002/09/10
投稿数: 437
投稿日時: 2002-10-01 15:02
だいぶ早くなったと思うけどなー。

private String getMst() throws OriginalException {
try {
GetLoginMstListBean getLoginMstListBean = new GetLoginMstListBean();

getLoginMstListBean.setFileName(fileName);

//まずVectorのサイズはあらかじめ大体わかっているなら
//new Vector(10000)
//とかして十分なサイズを確保すること
getLoginMstListBean.Execute();

//データ格納用変数
//まず容量が大体わかっている場合はその分の容量を確保する
StringBuffer s = new StringBuffer(500000);

//CollectionAPIのsize()はループ途中で変化する可能性がないなら
//あらかじめキャッシュしておく
int someSystemIdSize = getLoginMstListBean.getSomeSystemIds().size();

//Listへのポインタも変化する可能性がないならあらかじめキャッシュしておく
List aaa = getLoginMstListBean.getAAAA();
List bbb = getLoginMstListBean.getBBBB();

for (int dataCount = 0; dataCount < someSystemIdSize; dataCount++) {
//文字列の連結には必ずStringBufferを利用すること
s.append(aaa.get(dataCount));
s.append(",'");
s.append(bbb.get(dataCount));
s.append(",'");
s.append("\n");
}
return s.toString();
}
catch (Exception e) {
throw new XXXXException("データ格納エラー");
}
}

悪夢を統べるもの wrote
>>これって,そもそも連結した単一の文字列を作る必要が無いのでは?
>>途中結果を直接,出力ストリームに流すだけで良さそうなんですが.
>>
>>いずれにせよ,基礎の基礎もまるでなってないのは確かなようです

まぁ、ほかのクラスで再利用するかもしれないですから・・・。

ん、まてよ、このAAAとかBBBとかがカラム名だとするとこれがCCC、DDD・・・IIIとかがあるのかな?

スキルアップ/キャリアアップ(JOB@IT)