這篇文章主要介紹了Android編程使用HTTP協議與TCP協議實現上傳文件的方法,結合實例形式較爲詳細的分析了Android使用HTTP協議與TCP協議的具體步驟與實現文件傳輸的相關技巧,需要的朋友可以參考下
http://www.jb51.net/article/77410.htm
本文實例講述了Android編程使用HTTP協議與TCP協議實現上傳文件的方法。分享給大家供大家參考,具體如下:
Android上傳文件有兩種方式,第一種是基於Http協議的HttpURLConnection,第二種是基於TCP協議的Socket。 這兩種方式的區別是使用HttpURLConnection上傳時內部有緩存機制,如果上傳較大文件會導致內存溢出。如果用TCP協議Socket方式上傳就會解決這種弊端。
HTTP協議HttpURLConnection
1. 通過URL封裝路徑打開一個HttpURLConnection
2.設置請求方式以及頭字段:Content-Type、Content-Length、Host
3.拼接數據發送
示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
private
static final String BOUNDARY =
"---------------------------7db1c523809b2" ; //數據分割線 public
boolean uploadHttpURLConnection(String username, String password, String path)
throws Exception { //找到sdcard上的文件 File file =
new File(Environment.getExternalStorageDirectory(), path); //仿Http協議發送數據方式進行拼接 StringBuilder sb =
new StringBuilder(); sb.append( "--"
+ BOUNDARY + "\r\n" ); sb.append( "Content-Disposition: form-data; name=\"username\""
+ "\r\n" ); sb.append( "\r\n" ); sb.append(username +
"\r\n" ); sb.append( "--"
+ BOUNDARY + "\r\n" ); sb.append( "Content-Disposition: form-data; name=\"password\""
+ "\r\n" ); sb.append( "\r\n" ); sb.append(password +
"\r\n" ); sb.append( "--"
+ BOUNDARY + "\r\n" ); sb.append( "Content-Disposition: form-data; name=\"file\"; filename=\""
+ path + "\""
+ "\r\n" ); sb.append( "Content-Type: image/pjpeg"
+ "\r\n" ); sb.append( "\r\n" ); byte [] before = sb.toString().getBytes( "UTF-8" ); byte [] after = ( "\r\n--"
+ BOUNDARY + "--\r\n" ).getBytes( "UTF-8" ); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod( "POST" ); conn.setRequestProperty( "Content-Type" ,
"multipart/form-data; boundary="
+ BOUNDARY); conn.setRequestProperty( "Content-Length" , String.valueOf(before.length + file.length() + after.length)); conn.setRequestProperty( "HOST" ,
"192.168.1.16:8080" ); conn.setDoOutput( true ); OutputStream out = conn.getOutputStream(); InputStream in =
new FileInputStream(file); out.write(before); byte [] buf =
new byte [ 1024 ]; int
len; while
((len = in.read(buf)) != - 1 ) out.write(buf,
0 , len); out.write(after); in.close(); out.close(); return
conn.getResponseCode() == 200 ; } |
TCP協議Socket
1.我們可以使用Socket發送TCP請求,將上傳數據分段發送
示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
public
boolean uploadBySocket(String username, String password, String path)
throws Exception { // 根據path找到SDCard中的文件 File file =
new File(Environment.getExternalStorageDirectory(), path); // 組裝表單字段和文件之前的數據 StringBuilder sb =
new StringBuilder(); sb.append( "--"
+ BOUNDARY + "\r\n" ); sb.append( "Content-Disposition: form-data; name=\"username\""
+ "\r\n" ); sb.append( "\r\n" ); sb.append(username +
"\r\n" ); sb.append( "--"
+ BOUNDARY + "\r\n" ); sb.append( "Content-Disposition: form-data; name=\"password\""
+ "\r\n" ); sb.append( "\r\n" ); sb.append(password +
"\r\n" ); sb.append( "--"
+ BOUNDARY + "\r\n" ); sb.append( "Content-Disposition: form-data; name=\"file\"; filename=\""
+ path + "\""
+ "\r\n" ); sb.append( "Content-Type: image/pjpeg"
+ "\r\n" ); sb.append( "\r\n" ); // 文件之前的數據 byte [] before = sb.toString().getBytes( "UTF-8" ); // 文件之後的數據 byte [] after = ( "\r\n--"
+ BOUNDARY + "--\r\n" ).getBytes( "UTF-8" ); // 由於HttpURLConnection中會緩存數據, 上傳較大文件時會導致內存溢出, 所以我們使用Socket傳輸 Socket socket =
new Socket(url.getHost(), url.getPort()); OutputStream out = socket.getOutputStream(); PrintStream ps =
new PrintStream(out,
true , "UTF-8" ); // 寫出請求頭 ps.println( "POST /14_Web/servlet/LoginServlet HTTP/1.1" ); ps.println( "Content-Type: multipart/form-data; boundary="
+ BOUNDARY); ps.println( "Content-Length: "
+ String.valueOf(before.length + file.length() + after.length)); ps.println( "Host: 192.168.1.199:8080" ); InputStream in =
new FileInputStream(file); // 寫出數據 out.write(before); byte [] buf =
new byte [ 1024 ]; int
len; while
((len = in.read(buf)) != - 1 ) out.write(buf,
0 , len); out.write(after); in.close(); out.close(); return
true ; } |
搭建服務器,完成上傳功能
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
package
cn.test.web.servlet; import
java.io.File; import
java.io.IOException; import
java.util.List; import
javax.servlet.ServletException; 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.disk.DiskFileItemFactory; import
org.apache.commons.fileupload.servlet.ServletFileUpload; public
class LoginServlet extends
HttpServlet { private
static final
long serialVersionUID = 1L; @Override public
void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { doPost(request, response); } @Override public
void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { boolean
isMultipart = ServletFileUpload.isMultipartContent(request); if
(isMultipart) try
{ FileItemFactory factory =
new DiskFileItemFactory(); ServletFileUpload upload =
new ServletFileUpload(factory); List<FileItem> items = upload.parseRequest(request); File dir =
new File(request.getSession().getServletContext().getRealPath( "/WEB-INF/upload" )); //創建目錄 dir.mkdir(); for
(FileItem item : items) if
(item.isFormField()) System.out.println(item.getFieldName() +
": " + item.getString()); else { item.write( new
File(dir,item.getName().substring(item.getName().lastIndexOf( "\\" )+ 1 ))); } }
catch (Exception e) { e.printStackTrace(); } else
{ System.out.println(request.getMethod()); System.out.println(request.getParameter( "username" )); System.out.println(request.getParameter( "password" )); } } } |
希望本文所述對大家Android程序設計有所幫助。