Skip to content

Commit aa3058b

Browse files
committed
流上传前获得流的大小
1 parent 1db7b3b commit aa3058b

File tree

4 files changed

+201
-14
lines changed

4 files changed

+201
-14
lines changed

src/main/java/com/qiniu/api/io/IoApi.java

Lines changed: 107 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import java.io.File;
44
import java.io.FileInputStream;
5+
import java.io.FileOutputStream;
56
import java.io.InputStream;
67
import java.io.UnsupportedEncodingException;
78
import java.nio.charset.Charset;
@@ -27,16 +28,17 @@ public class IoApi {
2728
public static final int WITH_CRC32 = 2;
2829

2930
private static PutRet put(String uptoken, String key, File file,
30-
PutExtra extra) {
31+
PutExtra extra, String filename) {
3132

3233
if (!file.exists() || !file.canRead()) {
3334
return new PutRet(new CallRet(Config.ERROR_CODE, new Exception(
3435
"File does not exist or not readable.")));
3536
}
37+
extra = extra == null ? new PutExtra() : extra;
3638
MultipartEntity requestEntity = new MultipartEntity();
3739
try {
3840
requestEntity.addPart("token", new StringBody(uptoken));
39-
AbstractContentBody fileBody = buildFileBody(file, extra);
41+
AbstractContentBody fileBody = buildFileBody(file, extra, filename);
4042
requestEntity.addPart("file", fileBody);
4143
setKey(requestEntity, key);
4244
setParam(requestEntity, extra.params);
@@ -62,11 +64,19 @@ private static PutRet put(String uptoken, String key, File file,
6264
return new PutRet(ret);
6365
}
6466

65-
private static FileBody buildFileBody(File file,PutExtra extra){
67+
private static FileBody buildFileBody(File file,PutExtra extra, final String filename){
6668
if(extra.mimeType != null){
67-
return new FileBody(file, extra.mimeType);
69+
return new FileBody(file, extra.mimeType){
70+
public String getFilename() {
71+
return filename == null ? super.getFilename() : filename;
72+
}
73+
};
6874
}else{
69-
return new FileBody(file);
75+
return new FileBody(file){
76+
public String getFilename() {
77+
return filename == null ? super.getFilename() : filename;
78+
}
79+
};
7080
}
7181
}
7282

@@ -85,11 +95,13 @@ private static void setParam(MultipartEntity requestEntity, Map<String, String>
8595
}
8696
}
8797

88-
private static PutRet putStream(String uptoken, String key, InputStream reader,PutExtra extra, String fileName) {
98+
private static PutRet putStream(String uptoken, String key, InputStream reader,
99+
PutExtra extra, String fileName, long length) {
100+
extra = extra == null ? new PutExtra() : extra;
89101
MultipartEntity requestEntity = new MultipartEntity();
90102
try {
91103
requestEntity.addPart("token", new StringBody(uptoken));
92-
AbstractContentBody inputBody = buildInputStreamBody(reader, extra, fileName != null ? fileName : "null");
104+
AbstractContentBody inputBody = buildInputStreamBody(reader, extra, fileName, length);
93105
requestEntity.addPart("file", inputBody);
94106
setKey(requestEntity, key);
95107
setParam(requestEntity, extra.params);
@@ -109,22 +121,103 @@ private static PutRet putStream(String uptoken, String key, InputStream reader,P
109121
return new PutRet(ret);
110122
}
111123

112-
private static InputStreamBody buildInputStreamBody(InputStream reader,PutExtra extra, String fileName){
124+
private static AbstractContentBody buildInputStreamBody(InputStream reader,
125+
PutExtra extra, String fileName, final long length){
126+
fileName = fileName != null ? fileName : "null";
113127
if(extra.mimeType != null){
114-
return new InputStreamBody(reader, extra.mimeType, fileName);
128+
return new InputStreamBody(reader, extra.mimeType, fileName){
129+
public long getContentLength() {
130+
return length;
131+
}
132+
};
115133
}else{
116-
return new InputStreamBody(reader, fileName);
134+
return new InputStreamBody(reader, fileName){
135+
public long getContentLength() {
136+
return length;
137+
}
138+
};
117139
}
118140
}
119141

142+
143+
private static PutRet putStream0(String uptoken, String key, InputStream reader,
144+
PutExtra extra, String fileName, long length){
145+
length = length <= 0 ? getLength(reader) : length;
146+
if(length != -1) {
147+
return putStream(uptoken,key,reader,extra, fileName, length);
148+
}else{
149+
return toPutFile(uptoken, key, reader, extra, fileName);
150+
}
151+
152+
}
153+
154+
private static long getLength(InputStream is){
155+
try {
156+
return is.available();
157+
} catch (Exception e) {
158+
return -1;
159+
}
160+
}
161+
162+
private static PutRet toPutFile(String uptoken, String key,
163+
InputStream reader, PutExtra extra, String fileName) {
164+
File file = null;
165+
try{
166+
file = copyToTmpFile(reader);
167+
return put(uptoken, key, file, extra, fileName);
168+
}finally{
169+
if(file != null){
170+
try{file.delete();}catch(Exception e){}
171+
}
172+
}
173+
}
174+
175+
176+
private static File copyToTmpFile(InputStream from){
177+
FileOutputStream os = null;
178+
try{
179+
File to = File.createTempFile("qiniu_", ".tmp");
180+
os = new FileOutputStream(to);
181+
byte[] b = new byte[64 * 1024];
182+
int l;
183+
while ((l = from.read(b)) != -1) {
184+
os.write(b, 0, l);
185+
}
186+
os.flush();
187+
return to;
188+
}catch(Exception e){
189+
throw new RuntimeException("create tmp file failed.", e);
190+
}finally{
191+
if (os != null){
192+
try{os.close();}catch(Exception e){}
193+
}
194+
if (from != null){
195+
try{from.close();}catch(Exception e){}
196+
}
197+
}
198+
}
199+
200+
120201
public static PutRet put(String uptoken,String key,InputStream reader,PutExtra extra){
121-
return putStream(uptoken,key,reader,extra, null);
202+
return putStream0(uptoken,key,reader,extra, null, -1);
122203
}
123204

124205
public static PutRet put(String uptoken,String key,InputStream reader,PutExtra extra, String fileName){
125-
return putStream(uptoken,key,reader,extra, fileName);
206+
return putStream0(uptoken,key,reader,extra, fileName, -1);
126207
}
127208

209+
/**
210+
* @param uptoken
211+
* @param key
212+
* @param reader
213+
* @param extra
214+
* @param fileName
215+
* @param length 部分流 is.available() == 0,此时可指定内容长度
216+
* @return
217+
*/
218+
public static PutRet put(String uptoken,String key,InputStream reader,PutExtra extra, String fileName, long length){
219+
return putStream0(uptoken,key,reader,extra, fileName, length);
220+
}
128221

129222
public static PutRet Put(String uptoken,String key,InputStream reader,PutExtra extra)
130223
{
@@ -145,7 +238,7 @@ public static PutRet putFile(String uptoken, String key, File file, PutExtra ext
145238
return new PutRet(new CallRet(Config.ERROR_CODE, e));
146239
}
147240
}
148-
return put(uptoken, key, file, extra);
241+
return put(uptoken, key, file, extra, null);
149242
}
150243

151244
private static long getCRC32(File file) throws Exception {
@@ -171,4 +264,5 @@ private static long getCRC32(File file) throws Exception {
171264
}
172265
return crc;
173266
}
267+
174268
}

src/main/java/com/qiniu/api/resumableio/StreamSliceUpload.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ public StreamSliceUpload(InputStream is,
3030
@Override
3131
protected boolean hasNext() {
3232
try {
33-
return is != null && is.available() > 0;
33+
// 部分流 is.available() == 0,此时通过设定的内容长度判断,
34+
return is != null && (is.available() > 0 || currentBlockIdx * BLOCK_SIZE < contentLength);
3435
} catch (IOException e) {
3536
return false;
3637
}
@@ -39,6 +40,7 @@ protected boolean hasNext() {
3940
@Override
4041
protected UploadBlock buildNextBlockUpload() throws IOException {
4142
long left = is.available();
43+
left = left > 0 ? left : (contentLength - currentBlockIdx * BLOCK_SIZE);
4244
long start = currentBlockIdx * BLOCK_SIZE;
4345
int len = (int) Math.min(BLOCK_SIZE, left);
4446

src/test/java/com/qiniu/testing/IOTest.java

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,11 @@
55
import java.util.Map;
66
import java.util.UUID;
77

8+
import org.apache.http.HttpEntity;
9+
import org.apache.http.HttpResponse;
10+
import org.apache.http.client.ClientProtocolException;
11+
import org.apache.http.client.HttpClient;
12+
import org.apache.http.client.methods.HttpGet;
813
import org.json.JSONObject;
914

1015
import junit.framework.TestCase;
@@ -14,6 +19,8 @@
1419
import com.qiniu.api.io.IoApi;
1520
import com.qiniu.api.io.PutExtra;
1621
import com.qiniu.api.io.PutRet;
22+
import com.qiniu.api.net.Http;
23+
import com.qiniu.api.resumableio.ResumeableIoApi;
1724
import com.qiniu.api.rs.PutPolicy;
1825
import com.qiniu.api.rs.RSClient;
1926

@@ -98,6 +105,65 @@ private String getJsonValue(JSONObject jsonObject, String name){
98105
return null;
99106
}
100107
}
108+
109+
public void testNoLengthStream() throws Exception {
110+
PutPolicy p = new PutPolicy(bucketName);
111+
p.returnBody = "{\"key\": $(key), \"hash\": $(etag),\"mimeType\": $(mimeType)}";
112+
String upToken = p.token(mac);
113+
114+
HttpEntity en = getHttpEntity("http://qiniuphotos.qiniudn.com/gogopher.jpg");
115+
116+
class MyInputStream extends InputStream{
117+
InputStream in;
118+
MyInputStream(InputStream is){
119+
this.in = is;
120+
}
121+
122+
@Override
123+
public int read() throws IOException {
124+
// TODO Auto-generated method stub
125+
return in.read();
126+
}
127+
128+
public int available() throws IOException {
129+
throw new IOException();
130+
}
131+
132+
public void close() throws IOException {
133+
in.close();
134+
}
135+
136+
}
137+
138+
139+
140+
PutRet ret = IoApi.put(upToken, key, new MyInputStream(en.getContent()), null, en.getContentType().getValue());
141+
142+
System.out.println(ret);
143+
assertTrue(ret.ok());
144+
System.out.println("is.available() = " + en.getContent().available());
145+
}
146+
147+
public void testSetLengthStream() throws Exception {
148+
PutPolicy p = new PutPolicy(bucketName);
149+
p.returnBody = "{\"key\": $(key), \"hash\": $(etag),\"mimeType\": $(mimeType)}";
150+
String upToken = p.token(mac);
151+
152+
HttpEntity en = getHttpEntity("http://qiniuphotos.qiniudn.com/gogopher.jpg");
153+
PutRet ret = IoApi.put(upToken, key, en.getContent(), null, en.getContentType().getValue(), en.getContentLength());
154+
155+
System.out.println(ret);
156+
assertTrue(ret.ok());
157+
System.out.println("is.available() = " + en.getContent().available());
158+
}
159+
160+
private HttpEntity getHttpEntity(String url) throws ClientProtocolException, IOException{
161+
HttpClient client = Http.getClient();
162+
HttpGet httpget = new HttpGet(url);
163+
HttpResponse res = client.execute(httpget);
164+
return res.getEntity();
165+
}
166+
101167

102168
@Override
103169
public void tearDown() {

src/test/java/com/qiniu/testing/ResumeableioTest.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@
77
import java.io.IOException;
88
import java.util.UUID;
99

10+
import org.apache.http.HttpEntity;
11+
import org.apache.http.HttpResponse;
12+
import org.apache.http.client.ClientProtocolException;
13+
import org.apache.http.client.HttpClient;
14+
import org.apache.http.client.methods.HttpGet;
1015
import org.json.JSONException;
1116
import org.json.JSONObject;
1217

@@ -17,6 +22,7 @@
1722
import com.qiniu.api.config.Config;
1823
import com.qiniu.api.io.PutRet;
1924
import com.qiniu.api.net.CallRet;
25+
import com.qiniu.api.net.Http;
2026
import com.qiniu.api.resumableio.ResumeableIoApi;
2127
import com.qiniu.api.rs.PutPolicy;
2228
import com.qiniu.api.rs.RSClient;
@@ -108,7 +114,26 @@ private void uploadStream() throws AuthException, JSONException, FileNotFoundExc
108114
assertEquals(mimeType, mt);
109115
}
110116
}
117+
118+
public void testStream() throws Exception {
119+
PutPolicy p = new PutPolicy(bucketName);
120+
p.returnBody = "{\"key\": $(key), \"hash\": $(etag),\"mimeType\": $(mimeType)}";
121+
String upToken = p.token(mac);
122+
123+
HttpEntity en = getHttpEntity("http://qiniuphotos.qiniudn.com/gogopher.jpg");
124+
PutRet ret = ResumeableIoApi.put(en.getContent(), upToken, currentKey, en.getContentType().getValue(), en.getContentLength());
125+
126+
System.out.println(ret);
127+
assertTrue(ret.ok());
128+
System.out.println("is.available() = " + en.getContent().available());
129+
}
111130

131+
private HttpEntity getHttpEntity(String url) throws ClientProtocolException, IOException{
132+
HttpClient client = Http.getClient();
133+
HttpGet httpget = new HttpGet(url);
134+
HttpResponse res = client.execute(httpget);
135+
return res.getEntity();
136+
}
112137

113138
@Override
114139
public void tearDown() {

0 commit comments

Comments
 (0)