回答編集履歴
3
微修正
answer
CHANGED
@@ -77,7 +77,7 @@
|
|
77
77
|
do { // whileでも書けなくはないけど、1回は必ず内側を通る場合do-whileのほうが書きやすい
|
78
78
|
// 外側ループ毎の初期化処理
|
79
79
|
offset = 0; // offsetのリセット
|
80
|
-
Arrays.fill(data, 0); // 0埋めされてる必要はあるか?uploadの仕様次第
|
80
|
+
Arrays.fill(data, (byte)0); // 0埋めされてる必要はあるか?uploadの仕様次第
|
81
81
|
// あと、uploadの処理が非同期の場合は新しくnewしたほうが安全かも
|
82
82
|
next = false; // 繰り返しフラグのリセット
|
83
83
|
|
2
ソースコード追記
answer
CHANGED
@@ -20,4 +20,92 @@
|
|
20
20
|
といった感じなのですが、
|
21
21
|
この処理で行くと26回送った時点で13Mb近くのデータが送られていないとおかしいのです・・・
|
22
22
|
実装の全体を見たわけではないので他の部分で送信データ量が制限されている可能性もありますが、
|
23
|
-
ちょっと納得できない部分があるので参考程度に・・・
|
23
|
+
ちょっと納得できない部分があるので参考程度に・・・
|
24
|
+
|
25
|
+
--- 10/17 追記 ---
|
26
|
+
スキル・知識というものはやってみないと身につかないものです。
|
27
|
+
吐きながら覚えていきましょう。
|
28
|
+
穴あきのソースを書いたのでこんな感じでやってみてください。
|
29
|
+
```Java
|
30
|
+
public static void uploadPer512KBytes(InputStream in) throws IOException {
|
31
|
+
boolean next; // 繰り返しフラグ
|
32
|
+
|
33
|
+
// ストリームが終わるまでデータを読み込む外側ループ処理
|
34
|
+
do { // whileでも書けなくはないけど、1回は必ず内側を通る場合do-whileのほうが書きやすい
|
35
|
+
|
36
|
+
next = false; // 繰り返しフラグは外側ループの頭で毎回初期化する
|
37
|
+
|
38
|
+
// 512kbのデータを読み込む内側ループ処理
|
39
|
+
while ((bytesRead = in.read(data, offset, data.length - offset)) != -1) {
|
40
|
+
|
41
|
+
innerLoop++: // これはいくつになるかわからん
|
42
|
+
|
43
|
+
if (offset >= data.length) {
|
44
|
+
next = true; // ストリームの終わり以外で抜けるので繰り返しフラグをtrueに
|
45
|
+
break;
|
46
|
+
}
|
47
|
+
|
48
|
+
} // ストリームの終わりで抜けた場合は繰り返しフラグはfalseのまま
|
49
|
+
|
50
|
+
// 読み込んだデータの送信
|
51
|
+
if (offset >= 1) { // offset=0の状態でここに来ることがあるので
|
52
|
+
upload(bais);
|
53
|
+
}
|
54
|
+
|
55
|
+
outerLoop++; // これが4になるはず
|
56
|
+
|
57
|
+
} while(next); // 繰り返しフラグが立っている場合は外側処理をループ
|
58
|
+
}
|
59
|
+
```
|
60
|
+
下のコードは答え合わせ?用の動作未確認コードです。
|
61
|
+
吐いたら見てください。
|
62
|
+
```Java
|
63
|
+
// 答え合わせ?用
|
64
|
+
|
65
|
+
|
66
|
+
|
67
|
+
|
68
|
+
public static void uploadPer512KBytes(InputStream in) throws IOException {
|
69
|
+
int offset;
|
70
|
+
int bytesRead;
|
71
|
+
byte[] data = new byte[524288];// バッファ
|
72
|
+
boolean next;
|
73
|
+
int outerLoop = 0;
|
74
|
+
int innerLoop = 0;
|
75
|
+
|
76
|
+
// ストリームが終わるまでデータを読み込む外側ループ処理
|
77
|
+
do { // whileでも書けなくはないけど、1回は必ず内側を通る場合do-whileのほうが書きやすい
|
78
|
+
// 外側ループ毎の初期化処理
|
79
|
+
offset = 0; // offsetのリセット
|
80
|
+
Arrays.fill(data, 0); // 0埋めされてる必要はあるか?uploadの仕様次第
|
81
|
+
// あと、uploadの処理が非同期の場合は新しくnewしたほうが安全かも
|
82
|
+
next = false; // 繰り返しフラグのリセット
|
83
|
+
|
84
|
+
// 512kbのデータを読み込む内側ループ処理
|
85
|
+
while ((bytesRead = in.read(data, offset, data.length - offset)) != -1) {
|
86
|
+
offset += bytesRead;
|
87
|
+
innerLoop++: // これはいくつになるかわからん
|
88
|
+
if (offset >= data.length) {
|
89
|
+
next = true; // ストリームの終わり以外で抜けるので繰り返しフラグをtrueに
|
90
|
+
break;
|
91
|
+
}
|
92
|
+
} // ストリームの終わりで抜けた場合は繰り返しフラグはfalseのまま
|
93
|
+
|
94
|
+
// 読み込んだデータの送信
|
95
|
+
if (offset >= 1) { // offset=0の状態でここに来ることがあるので
|
96
|
+
// 端っこのデータを処理する時、
|
97
|
+
// 引数1つのコンストラクタでは余計な部分まで処理することにならないか?
|
98
|
+
// uploadの仕様次第だが、引数3つのコンストラクタを使ったほうがいいような・・・
|
99
|
+
// ByteArrayInputStream bais = new ByteArrayInputStream(data, 0, offset);
|
100
|
+
ByteArrayInputStream bais = new ByteArrayInputStream(data);
|
101
|
+
// バッファに格納した分アップロード
|
102
|
+
upload(bais);
|
103
|
+
}
|
104
|
+
|
105
|
+
// offsetとdataの初期化処理は、ここでやることもできる。
|
106
|
+
// 最初の1回だけあらかじめデータを入れておきたい場合はここで
|
107
|
+
|
108
|
+
outerLoop++; // これが4になるはず
|
109
|
+
} while(next); // 繰り返しフラグが立っている場合は外側処理をループ
|
110
|
+
}
|
111
|
+
```
|
1
修正
answer
CHANGED
@@ -1,2 +1,23 @@
|
|
1
1
|
InputStreamの実体がただのInputStreamである場合は、
|
2
|
-
BufferedInputStreamでラップしてみてください。
|
2
|
+
BufferedInputStreamでラップしてみてください。
|
3
|
+
|
4
|
+
--- 追記・・・というより書き直し ---
|
5
|
+
BufferedInputStream多分関係ありませんでした。
|
6
|
+
で、他に修正できそうなところがあったので書こうと思うのですが、
|
7
|
+
コメントで状態を確認してみたらよくわからなくなってきました。
|
8
|
+
とりあえず書いておきます。
|
9
|
+
|
10
|
+
問題が発生していると思われるのは、While文の中です。
|
11
|
+
バッファが埋まる、またはストリームが終わるまでデータを繰り返し読み込む、
|
12
|
+
という処理を行っていると思うのですが、その中でuploadメソッドが呼ばれているため、
|
13
|
+
バッファが埋まり切っていない状態のデータを複数回送信してしまっているものと思います。
|
14
|
+
※複数回の所が実行毎に違うのは、InputStreamにデータを入れる側の転送速度が実行毎に変わっているからだと思っています。
|
15
|
+
|
16
|
+
これを修正するには、While文を抜けた後でuploadメソッドを呼ぶように修正するだけなのですが、
|
17
|
+
それだとバッファ分の512Kbしか送れなくなるので、ストリームが終わったかを確認し、
|
18
|
+
ストリームが終わるまで処理を繰り返すWhile文を外側に作る必要があります。
|
19
|
+
|
20
|
+
といった感じなのですが、
|
21
|
+
この処理で行くと26回送った時点で13Mb近くのデータが送られていないとおかしいのです・・・
|
22
|
+
実装の全体を見たわけではないので他の部分で送信データ量が制限されている可能性もありますが、
|
23
|
+
ちょっと納得できない部分があるので参考程度に・・・
|