Here is an example of native Java code that uploads a file using chunks:
final String LF = "\r\n"; // Line separator required by multipart/form-data. Can be static class constant
final String boundary = Long.toHexString(System.currentTimeMillis()); // Just generate some unique random value.
HttpURLConnection connection = (HttpURLConnection) new URL("http://some.com/upload").openConnection();
try {
connection.setDoOutput(true);
connection.setChunkedStreamingMode(4096);
connection.setRequestMethod("POST");
connection.addRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
connection.addRequestProperty("Accept", "application/json");
connection.addRequestProperty("Authorization", myToken);
try (OutputStream os = connection.getOutputStream();
Writer writer = new OutputStreamWriter(os, StandardCharsets.UTF_8)) {
writer.append("--").append(boundary).append(LF);
writer.append("Content-Disposition: form-data; name=\"dataFile\"; filename=\"file.zip\"").append(LF);
writer.append("Content-Type: application/zip").append(LF);
writer.append(LF);
writer.flush();
// Write body
writeBinaryBody(os);
writer.append(LF).append("--").append(boundary).append("--").append(LF);
writer.flush();
os.flush();
}
if (200 != connection.getResponseCode()) {
try (Reader reader = new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8)) {
// Handle error here
}
}
} finally {
connection.disconnect();
}
The code in this example is based on this answer about http file upload from java. The difference is the call to connection.setChunkedStreamingMode(4096); that defines that chunked streaming should be used.
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItemIterator;
import org.apache.commons.fileupload.FileItemStream;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.fileupload.util.Streams;
public class UploadAction extends HttpServlet {
private static final long serialVersionUID = 3447685998419256747L;
private static final String RESP_SUCCESS = "{\"jsonrpc\" : \"2.0\", \"result\" : \"success\", \"id\" : \"id\"}";
private static final String RESP_ERROR = "{\"jsonrpc\" : \"2.0\", \"error\" : {\"code\": 101, \"message\": \"Failed to open input stream.\"}, \"id\" : \"id\"}";
public static final String JSON = "application/json";
public static final int BUF_SIZE = 2 * 1024;
public static final String FileDir = "/home/asjha/uploads/";
private int chunk;
private int chunks;
private String name;
private String user;
private String time;
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String responseString = RESP_SUCCESS;
boolean isMultipart = ServletFileUpload.isMultipartContent(req);
if(isMultipart){
ServletFileUpload upload = new ServletFileUpload();
try {
FileItemIterator iter = upload.getItemIterator(req);
while (iter.hasNext()) {
FileItemStream item = iter.next();
InputStream input = item.openStream();
// Handle a form field.
if(item.isFormField()){
String fileName = item.getFieldName();
String value = Streams.asString(input);
if("name".equals(fileName)){
this.name = value;
}else if("chunks".equals(fileName)){
this.chunks = Integer.parseInt(value);
}else if("chunk".equals(fileName)){
this.chunk = Integer.parseInt(value);
}else if("user".equals(fileName)){
this.user = value;
}else if("time".equals(fileName)){
this.time = value;
}
}
// Handle a multi-part MIME encoded file.
else {
File dstFile = new File(FileDir);
if (!dstFile.exists()){
dstFile.mkdirs();
}
File dst = new File(dstFile.getPath()+ "/" + this.name);
saveUploadFile(input, dst);
}
}
}
catch (Exception e) {
responseString = RESP_ERROR;
e.printStackTrace();
}
}
// Not a multi-part MIME request.
else {
responseString = RESP_ERROR;
}
if(this.chunk == this.chunks - 1){
System.out.println("name"+this.name);
}
resp.setContentType(JSON);
byte[] responseBytes = responseString.getBytes();
resp.setContentLength(responseBytes.length);
ServletOutputStream output = resp.getOutputStream();
output.write(responseBytes);
output.flush();
}
private void saveUploadFile(InputStream input, File dst) throws IOException {
OutputStream out = null;
try {
if (dst.exists()) {
out = new BufferedOutputStream(new FileOutputStream(dst, true),
BUF_SIZE);
} else {
out = new BufferedOutputStream(new FileOutputStream(dst),
BUF_SIZE);
}
byte[] buffer = new byte[BUF_SIZE];
int len = 0;
while ((len = input.read(buffer)) > 0) {
out.write(buffer, 0, len);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != input) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (null != out) {
try {
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
Please refer to plupload for details and on github you can see sample projects by jakobadam and rocky.
Please let me know if multiple file upload is required. Using plupload we can upload any number of files of any sizes. This sample is for single file upload of very large size.
dont forget to include plupload.full.min.js. Hope this helps*emphasized text**
Use a RandomAccessFile. This has already been covered on SO I believe.
java file input with rewind()/reset() capability
Basically you'd just seek to the starting point, write however many bytes you want to from there, and remember the point you stopped writing from.
Try Apache Commons upload. It supports streaming, may be suitable for you.
You can simply break the file up yourself, send it using the Socket API, and re-assemble the file.
Here is an example of native Java code that uploads a file using chunks:
The code in this example is based on this answer about http file upload from java. The difference is the call to
connection.setChunkedStreamingMode(4096);
that defines that chunked streaming should be used.If you are using Java , use Arivus Nioserver gradle dependency -> compile 'org.arivu:nioserver:1.0.3'. No file size constraint.
*It can be done using plupload. Here is sample. My index.html is as under:-
My java backend code(Servlet) is as under:-
Please refer to plupload for details and on github you can see sample projects by jakobadam and rocky.
Please let me know if multiple file upload is required. Using plupload we can upload any number of files of any sizes. This sample is for single file upload of very large size. dont forget to include plupload.full.min.js. Hope this helps*emphasized text**