Android通过socket实现上传大文件到服务器
2018-07-20 来源:open-open
上传文件,我用了两种方式实现,首先是用对象序列化,即把要上传的数据打包成要上传的对象,然后上传。
需要注意的是:序列化的那两个类一定要相同,包括包名。(其实就是客户端和服务器端的javabean类,不过加上Serializable)
本人由于没有处理好服务器端和客户端的包名而使程序不能执行。
同时: 在客户端进行序列化,在服务器端就进行反序列化。
好了,上代码:
首先是序列化的类:
public class UploadFile implements Serializable {
private String title;
private byte[] contentdata;
private String mimetype;
private String type;
private long length;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public byte[] getContentdata() {
return contentdata;
}
public void setContentdata(byte[] contentdata) {
this.contentdata = contentdata;
}
public String getMimetype() {
return mimetype;
}
public void setMimetype(String mimetype) {
this.mimetype = mimetype;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public long getLength() {
return length;
}
public void setLength(long length) {
this.length = length;
}
}
public class MainSocket extends Activity {
private Button butchose=null;
private Button up=null;
private TextView text=null;
private static String filePath=null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setContentView(R.layout.mainsocket);
butchose=(Button)super.findViewById(R.id.socketchose);
text=(TextView)super.findViewById(R.id.socketshow);
up=(Button)super.findViewById(R.id.socketup);
butchose.setOnClickListener(new MyButton());
up.setOnClickListener(new MyButton());
}
//button按钮的不同实现
class MyButton implements OnClickListener{
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.socketup://发送文件按钮
try {
if(text.getText().toString()==null)
{ Toast.makeText(MainSocket.this, "请选择上传文件", 3).show();}
sendup();
} catch (Exception e) {
e.printStackTrace();
}
break;
default:
break;
}
}
}
//发送文件函数
public void sendup() throws Exception{
final Socket socket=new Socket("服务器ip",8897); //建立socket连接
BufferedReader buffer=new BufferedReader(new InputStreamReader(socket.getInputStream()));//构建一个缓冲区,用于存放服务器返回的数据
new Thread(new Runnable(){//开启一个新线程,用于发送数据
@Override
public void run() {
try {
ObjectOutputStream obj=new ObjectOutputStream(socket.getOutputStream());//对象序列化的应用
UploadFile file=MainSocket.this.upfile();//从下面那个函数中得到序列化的对象
obj.writeObject(file);//把对象发送出去
} catch (IOException e) {
e.printStackTrace();
}
}}).start();
String s=buffer.readLine().toString();//得到服务器返回的数据
System.out.println("-------------------返回的数据是"+s);
if(s.equals("true")){
text.setText("操作成功!");
}
else{
text.setText("操作失败");
}
socket.close();
}
//构造序列化对象
public UploadFile upfile(){
UploadFile upfile=new UploadFile();
upfile.setTitle("自行设置");
upfile.setMimetype("自行设置");
try {
File file=new File(filePath);//得到发送的文件
InputStream in=new FileInputStream(file) ;//打开文件的输出流(前台的输入流)
ByteArrayOutputStream ous=new ByteArrayOutputStream();//声明一个字节流
byte[] data=new byte[1024];//缓存数组
int len=0;
while((len=in.read(data))!=-1){//把前面输入流的数据送到字节流中
ous.write(data,0,len);
}
upfile.setContentdata(ous.toByteArray());//把字节流的数据送到javabean中,即序列化对象中
upfile.setLength(file.length());//设置长度
upfile.setType(filePath.substring(filePath.lastIndexOf(".")+1));
} catch (Exception e) {
e.printStackTrace();
}
return upfile;
}
}
服务器端:
package lxf.com;
import java.io.IOException;
import java.net.ServerSocket;
public class server {
public static void main(String[] args) {
try {
ServerSocket socket=new ServerSocket(8897);
while(true){
new Thread(new ServerThread(socket.accept())).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
服务器端实现类:
package lxf.com;
import java.io.File;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.util.UUID;
import lxf.socket.UploadFile;
public class ServerThread implements Runnable {
private String PATH="d:"+File.separator+"lxf"+File.separator;
private UploadFile uploadfile=null;
private Socket socket;
public ServerThread(Socket socekt1){
this.socket=socekt1;
System.out.println("建立新的连接");
}
@Override
public void run() {
try {
ObjectInputStream input=new ObjectInputStream(socket.getInputStream());//进行反序列化
uploadfile=new UploadFile();
this.uploadfile=(UploadFile)input.readObject();//把流数据转换成序列化对象
System.out.println("文件长短是:"+uploadfile.getLength());
System.out.println("文件格式:"+uploadfile.getType());
PrintStream out=new PrintStream(socket.getOutputStream());//建立socket输出流
save();
out.println("true");//给客户端应答
} catch (Exception e) {
e.printStackTrace();
}
finally{
}
}
public boolean save() throws Exception{
File file=new File(PATH+UUID.randomUUID()+"."+uploadfile.getType());//建立一个文件夹
if(!file.getParentFile().exists())//父文件不存在建立父文件
{
file.getParentFile().mkdir();
}
OutputStream output=new FileOutputStream(file);//打开控制台输出流
output.write(uploadfile.getContentdata());//把数据写入文件
output.close();
return true ;
}
}
由于本人每一步写的很细,标的也很细。大家应该可以看懂。
ObjectInputStream与ObjectOutputStream类所读写的对象必须实现了Seralizable接口。对象中的transient和static类型的成员变量不会被读取和写入。
另外,客户端的布局大家可以自行设置。在这里,还有第二种方法:实现多线程多用户断点续传功能,也是用数据流的方式上传。
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点!
本站所提供的图片等素材,版权归原作者所有,如需使用,请与原作者联系。
上一篇:Java实现小数的四舍五入
下一篇:java堆排序算法代码