###前提・実現したいこと
Javaで、受け取ったInputStream(主に動画のデータなど)を一定のバイト数毎にアップロードできる形で出力したいです。
MineTypeも付与したいです。
###発生している問題・エラーメッセージ
エラー等は発生していません。
ただ、アップロードされたデータの数が想定よりも多いです。
分割前のバイト数 / 分割するバイト数 = 想定の分割データ数になっていないのです。
1.7MBほどのデータを512KBで分割させましたが、26個のデータに分割されてしまいました。
また、データが正しくアップロードされているのかも現状確認できません。
###該当のソースコード
public static void uploadPer512KBytes(InputStream in) throws IOException { int offset = 0; int bytesRead = 0; byte[] data = new byte[524288]; int loop = 1; while ((bytesRead = in.read(data, offset, data.length - offset)) != -1) { offset += bytesRead; ByteArrayInputStream bais = new ByteArrayInputStream(data); // ここで、連番を振って、データbaisをアップロードする処理 // その際、正しくMineTypeを付与したい(※"application/octet-stream"でよい) upload(bais); loop++; if (offset >= data.length) { break; } } }
###補足情報(言語/FW/ツール等のバージョンなど)
そもそも、自分のやろうとしている方式が正しいのかも分からない状態です。
どんな些細な情報でも助かりますので、宜しくお願い致します。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答2件
0
ベストアンサー
InputStreamの実体がただのInputStreamである場合は、
BufferedInputStreamでラップしてみてください。
--- 追記・・・というより書き直し ---
BufferedInputStream多分関係ありませんでした。
で、他に修正できそうなところがあったので書こうと思うのですが、
コメントで状態を確認してみたらよくわからなくなってきました。
とりあえず書いておきます。
問題が発生していると思われるのは、While文の中です。
バッファが埋まる、またはストリームが終わるまでデータを繰り返し読み込む、
という処理を行っていると思うのですが、その中でuploadメソッドが呼ばれているため、
バッファが埋まり切っていない状態のデータを複数回送信してしまっているものと思います。
※複数回の所が実行毎に違うのは、InputStreamにデータを入れる側の転送速度が実行毎に変わっているからだと思っています。
これを修正するには、While文を抜けた後でuploadメソッドを呼ぶように修正するだけなのですが、
それだとバッファ分の512Kbしか送れなくなるので、ストリームが終わったかを確認し、
ストリームが終わるまで処理を繰り返すWhile文を外側に作る必要があります。
といった感じなのですが、
この処理で行くと26回送った時点で13Mb近くのデータが送られていないとおかしいのです・・・
実装の全体を見たわけではないので他の部分で送信データ量が制限されている可能性もありますが、
ちょっと納得できない部分があるので参考程度に・・・
--- 10/17 追記 ---
スキル・知識というものはやってみないと身につかないものです。
吐きながら覚えていきましょう。
穴あきのソースを書いたのでこんな感じでやってみてください。
Java
1public static void uploadPer512KBytes(InputStream in) throws IOException { 2 boolean next; // 繰り返しフラグ 3 4 // ストリームが終わるまでデータを読み込む外側ループ処理 5 do { // whileでも書けなくはないけど、1回は必ず内側を通る場合do-whileのほうが書きやすい 6 7 next = false; // 繰り返しフラグは外側ループの頭で毎回初期化する 8 9 // 512kbのデータを読み込む内側ループ処理 10 while ((bytesRead = in.read(data, offset, data.length - offset)) != -1) { 11 12 innerLoop++: // これはいくつになるかわからん 13 14 if (offset >= data.length) { 15 next = true; // ストリームの終わり以外で抜けるので繰り返しフラグをtrueに 16 break; 17 } 18 19 } // ストリームの終わりで抜けた場合は繰り返しフラグはfalseのまま 20 21 // 読み込んだデータの送信 22 if (offset >= 1) { // offset=0の状態でここに来ることがあるので 23 upload(bais); 24 } 25 26 outerLoop++; // これが4になるはず 27 28 } while(next); // 繰り返しフラグが立っている場合は外側処理をループ 29}
下のコードは答え合わせ?用の動作未確認コードです。
吐いたら見てください。
Java
1// 答え合わせ?用 2 3 4 5 6public static void uploadPer512KBytes(InputStream in) throws IOException { 7 int offset; 8 int bytesRead; 9 byte[] data = new byte[524288];// バッファ 10 boolean next; 11 int outerLoop = 0; 12 int innerLoop = 0; 13 14 // ストリームが終わるまでデータを読み込む外側ループ処理 15 do { // whileでも書けなくはないけど、1回は必ず内側を通る場合do-whileのほうが書きやすい 16 // 外側ループ毎の初期化処理 17 offset = 0; // offsetのリセット 18 Arrays.fill(data, (byte)0); // 0埋めされてる必要はあるか?uploadの仕様次第 19 // あと、uploadの処理が非同期の場合は新しくnewしたほうが安全かも 20 next = false; // 繰り返しフラグのリセット 21 22 // 512kbのデータを読み込む内側ループ処理 23 while ((bytesRead = in.read(data, offset, data.length - offset)) != -1) { 24 offset += bytesRead; 25 innerLoop++: // これはいくつになるかわからん 26 if (offset >= data.length) { 27 next = true; // ストリームの終わり以外で抜けるので繰り返しフラグをtrueに 28 break; 29 } 30 } // ストリームの終わりで抜けた場合は繰り返しフラグはfalseのまま 31 32 // 読み込んだデータの送信 33 if (offset >= 1) { // offset=0の状態でここに来ることがあるので 34 // 端っこのデータを処理する時、 35 // 引数1つのコンストラクタでは余計な部分まで処理することにならないか? 36 // uploadの仕様次第だが、引数3つのコンストラクタを使ったほうがいいような・・・ 37 // ByteArrayInputStream bais = new ByteArrayInputStream(data, 0, offset); 38 ByteArrayInputStream bais = new ByteArrayInputStream(data); 39 // バッファに格納した分アップロード 40 upload(bais); 41 } 42 43 // offsetとdataの初期化処理は、ここでやることもできる。 44 // 最初の1回だけあらかじめデータを入れておきたい場合はここで 45 46 outerLoop++; // これが4になるはず 47 } while(next); // 繰り返しフラグが立っている場合は外側処理をループ 48}
投稿2017/10/16 02:48
編集2017/10/17 02:47総合スコア1280
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/10/16 03:01
2017/10/16 03:58
2017/10/16 04:14
2017/10/16 04:52
2017/10/16 05:04
2017/10/16 05:07
2017/10/16 05:10 編集
2017/10/16 05:56
2017/10/16 05:59
2017/10/16 08:07 編集
2017/10/16 08:06
2017/10/16 08:19 編集
2017/10/16 08:19
2017/10/16 09:04 編集
2017/10/17 02:07 編集
2017/10/17 02:01
2017/10/17 02:37
2017/10/17 04:51
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。