本地:
先看下项目结构
MainActivity.java
package com.huxq.uploadexample; import java.io.File; import android.annotation.SuppressLint; import android.app.Activity; import android.app.ProgressDialog; import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.os.Message; import android.util.Log; import android.view.View; import android.widget.Toast; public class MainActivity extends Activity implements OnUploadListener { // 服务器路径,换成自己的 private String urlString = "http://192.168.1.2:8080/UploadTest/Upload"; /** * 上传文件的路径 */ String filePath; /** * 上传的文件名 */ String fileName; ProgressDialog dialog; /** * 在读取文件流的时候,同一进度会多次回调,通过这个标记,只有在进度更新的情况下才会更新ui 节省资源 */ int oldProcess; @SuppressLint("HandlerLeak") private Handler handler = new Handler() { public void handleMessage(android.os.Message msg) { Log.i("process", "process" + msg.arg1); dialog.setProgress(msg.arg1); // 第一次没有显示dialog的时候显示dialog if (!dialog.isShowing()) { Log.i("process", "show"); dialog.show(); } else { if (msg.arg1 == 100) {// 提示用户上传完成 dialog.dismiss(); toast("上传完成!"); } } }; }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initProgressDialog(); } public void upLoad(View v) { if (Environment.getExternalStorageState().equals( Environment.MEDIA_MOUNTED)) { // toast("上传"); String sdcardPath = Environment.getExternalStorageDirectory() .getAbsolutePath(); filePath = sdcardPath + "/Abook/"; File file = new File(filePath); // 这里我选的是Abook文件夹下第五个文件上传,得根据自己的实际情况来,否则肯定出错。 fileName = file.list()[4]; filePath += fileName; Log.i("file.size", "size=" + file.list().length + "filePath" + filePath); } else { toast("没有内存卡"); return; } new Thread() { public void run() { try { String response = HttpUtil.sendFile(urlString, filePath, fileName, MainActivity.this); Log.i("response", "response" + response); } catch (Exception e) { e.printStackTrace(); } }; }.start(); } @Override public void onUpload(double process) { process = process * 100; int currentProcess = (int) process; dialog.setProgress(currentProcess); // 避免重复发消息,可以把if给去掉看看会发生什么 if (currentProcess > oldProcess) { Message msg = handler.obtainMessage(); msg.arg1 = (int) process; handler.sendMessage(msg); } oldProcess = currentProcess; } public void initProgressDialog() { dialog = new ProgressDialog(this); dialog.setMax(100); dialog.setProgress(0); dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); dialog.setCancelable(false); dialog.setCanceledOnTouchOutside(false); dialog.setTitle("正在努力上传..."); } public void toast(String text) { Toast.makeText(getApplicationContext(), text, Toast.LENGTH_SHORT) .show(); } }HttpUtil.java
public static String sendFile(String urlPath, String filePath, String newName,OnUploadListener listener) throws Exception { String end = "\r\n"; String twoHyphens = "--"; String boundary = "******"; URL url = new URL(urlPath); HttpURLConnection con = (HttpURLConnection) url.openConnection(); //下载需要将setDoInput方法的参数值设为true con.setDoInput(true); //上传需要将setDoOutput方法的参数值设为true con.setDoOutput(true); //禁止HttpURLConnection使用缓存 con.setUseCaches(false); //使用POST请求,必须大写 con.setRequestMethod("POST"); //以下三行设置http请求头信息 con.setRequestProperty("Connection", "Keep-Alive"); con.setRequestProperty("Charset", "UTF-8"); //在模拟web页面向服务器端上传文件时,每个文件的开头需要有一个分界符, //分界符需要在http请求头中指定。boundary是任意一个字符串,一般为****** con.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary); DataOutputStream ds = new DataOutputStream(con.getOutputStream()); ds.writeBytes(twoHyphens + boundary + end); //上传文件相关信息,这些信息包括请求参数名,上传文件名,文件类型,但并不限于此 ds.writeBytes("Content-Disposition: form-data; " + "name=\"file1\";filename=\"" + newName + "\"" + end); ds.writeBytes(end); //获得文件的输入流,通过流传输文件。在这里我重写了FileInputStream,为了监听上传进度 CustomFileInputStream fStream = new CustomFileInputStream(filePath); fStream.setOnUploadListener(listener); /* 设置每次写入1024bytes */ int bufferSize = 1024; byte[] buffer = new byte[bufferSize]; int length = -1; // 从文件读取数据至缓冲区 while ((length = fStream.read(buffer)) != -1) { //将资料写入DataOutputStream中 ds.write(buffer, 0, length); } ds.writeBytes(end); ds.writeBytes(twoHyphens + boundary + twoHyphens + end); fStream.close(); ds.flush(); //上传完成以后获取服务器的反馈 InputStream is = con.getInputStream(); int ch; StringBuffer b = new StringBuffer(); while ((ch = is.read()) != -1) { b.append((char) ch); } ds.close(); return b.toString(); }CustomFileInputStream.java
package com.huxq.uploadexample; import java.io.File; import java.io.FileDescriptor; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; public class CustomFileInputStream extends FileInputStream { private OnUploadListener listener; private int total, done; private double process; public CustomFileInputStream(File file) throws FileNotFoundException { super(file); available(); } public CustomFileInputStream(FileDescriptor fd) { super(fd); available(); } public CustomFileInputStream(String path) throws FileNotFoundException { super(path); available(); } @Override public int read(byte[] buffer, int byteOffset, int byteCount) throws IOException { done += byteCount; process = 1.0 * done / total; if (listener != null) { listener.onUpload(process); } return super.read(buffer, byteOffset, byteCount); } public void setOnUploadListener(OnUploadListener listener) { this.listener = listener; } @Override public int available() { try { // 获取文件的总大小 total = super.available(); } catch (IOException e) { e.printStackTrace(); } return total; } }OnUploadListener.java
package com.huxq.uploadexample; public interface OnUploadListener { void onUpload(double process); }
服务器端通过一个servlet来接收文件流,然后写入磁盘就行了。
Upload.java
package com.huxq.test; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.util.Iterator; import java.util.List; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileItemFactory; import org.apache.commons.fileupload.FileUploadException; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; /** * Servlet implementation class Upload */ @WebServlet("/Upload") public class Upload extends HttpServlet { private static final long serialVersionUID = 1L; /** * 文件保存路径 */ private final String savaPath="E:\\uploads/"; /** * Default constructor. */ public Upload() { } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse * response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { boolean isMultipart = ServletFileUpload.isMultipartContent(request); if (isMultipart) { FileItemFactory factory = new DiskFileItemFactory(); ServletFileUpload upload = new ServletFileUpload(factory); List items; try { items = upload.parseRequest(request); Iterator iter = items.iterator(); // 可以接收多个文件 while (iter.hasNext()) { FileItem item = (FileItem) iter.next(); if (item.isFormField()) { // 普通文本信息处理 String paramName = item.getFieldName(); String paramValue = item.getString(); System.out.println(paramName + ":" + paramValue); } else { // 上传文件信息处理 String fileName = item.getName(); byte[] data = item.get(); String filePath = savaPath + fileName; File file = new File(savaPath); if (!file.exists()) { file.mkdirs(); } System.out.println("filePath:" + filePath); File file2 = new File(filePath); if (file2.exists()) file2.delete(); FileOutputStream fos = new FileOutputStream(file2); fos.write(data); fos.close(); } } response.getWriter().write("UPLOAD_SUCCESS"); } catch (FileUploadException e) { e.printStackTrace(); response.getWriter().write("UPLOAD_FAILED"); } } } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse * response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
这里需要两个jar包,分别是commons-fileupload-1.3.1.jar和commons-io-2.4.jar
所有想说的都在代码里了,如果有不清楚的可以下载下载Demo或者留言一起探讨。
原文地址:http://blog.csdn.net/footballclub/article/details/43636813