我想发布一个大视频(近1 GB).
我正在使用FTP将视频发送到服务器,但上传会在一段时间后停止.在服务器上视频崩溃,但我可以上传较小的视频.
我还使用HTTP将视频发送到服务器,作为Base64编码字符串发送,但编码时出现内存不足异常.
解决方法
使用HTTP POST,并将内容发布为
Form-based File Upload(mime类型:multipart / form-data).该系统是Web上的标准,用于发送表单和/或上载文件.
使用HTTP chunked post模式,因此不需要预先知道大小,并且您可以以小部分流式传输任何文件.您仍然必须在服务器上(例如在PHP中)制作一些代码来接受该文件并执行所需的操作.
使用HttpURLConnection启动连接.然后使用我附加的类发送数据.它将创建正确的标题等,您将使用它作为OutputStream将原始数据写入其中,然后调用close,您就完成了.您可以覆盖其onHandleResult来处理生成的错误代码.
public class FormDataWriter extends FilterOutputStream{ private final HttpURLConnection con; /** * @param formName name of form in which data are sent * @param fileName * @param fileSize size of file,or -1 to use chunked encoding */ FormDataWriter(HttpURLConnection con,String formName,String fileName,long fileSize) throws IOException{ super(null); this.con = con; con.setDoOutput(true); String boundary = generateBoundary(); con.setRequestProperty(HTTP.CONTENT_TYPE,"multipart/form-data; charset=UTF-8; boundary="+boundary); { StringBuilder sb = new StringBuilder(); writePartHeader(boundary,formName,fileName==null ? null : "filename=\""+fileName+"\"","application/octet-stream",sb); headerBytes = sb.toString().getBytes("UTF-8"); sb = new StringBuilder(); sb.append("\r\n"); sb.append("--"+boundary+"--\r\n"); footerBytes = sb.toString().getBytes(); } if(fileSize!=-1) { fileSize += headerBytes.length + footerBytes.length; con.setFixedLengthStreamingMode((int)fileSize); }else con.setChunkedStreamingMode(0x4000); out = con.getOutputStream(); } private byte[] headerBytes,footerBytes; private String generateBoundary() { StringBuilder sb = new StringBuilder(); Random rand = new Random(); int count = rand.nextInt(11) + 30; int N = 10+26+26; for(int i=0; i<count; i++) { int r = rand.nextInt(N); sb.append((char)(r<10 ? '0'+r : r<36 ? 'a'+r-10 : 'A'+r-36)); } return sb.toString(); } private void writePartHeader(String boundary,String name,String extraContentDispositions,String contentType,StringBuilder sb) { sb.append("--"+boundary+"\r\n"); sb.append("Content-Disposition: form-data; charset=UTF-8; name=\""+name+"\""); if(extraContentDispositions!=null) sb.append("; ").append(extraContentDispositions); sb.append("\r\n"); if(contentType!=null) sb.append("Content-Type: "+contentType+"\r\n"); sb.append("\r\n"); } @Override public void write(byte[] buffer,int offset,int length) throws IOException{ if(headerBytes!=null) { out.write(headerBytes); headerBytes = null; } out.write(buffer,offset,length); } @Override public void close() throws IOException{ flush(); if(footerBytes!=null) { out.write(footerBytes); footerBytes = null; } super.close(); int code = con.getResponseCode(); onHandleResult(code); } protected void onHandleResult(int code) throws IOException{ if(code!=200 && code!=201) throw new IOException("Upload error code: "+code); } }