http://blog.csdn.net/zsw101259/article/details/7768908
1、多线程文件的上传,数据流向
1)、客户端Socket:
①out File对象
②out 文件内容
③in 服务端反馈信息
2)、服务端的处理
①每接收一个Socket,创建一个线程去处理这个Socket
②in File对象:判断文件的类型、选择不同的传输方式、创建File对象关联文件
③in 文件内容:填充File对象关联文件内容
④填充完File文件,给客户端反馈
2、代码:
1)客户端:字符流
- import java.net.*;
- import java.io.*;
- /**
- * @author Administrator @zsw 2012-7-18 上午09:21:04
- *
- * 需求:从客户端上传文本文件到服务端
- *
- * 客户端上传:
- * ①定义Socket、文件输入流、Socket输出流、Socket输入流
- * ②从文件输入读取文件,
- * 添加:首先上传文件File对象和文件类型int filetype
- * ③将读到的数据写入Socket输出流中
- * ④关闭资源
- */
- public class TextUploadClient2 {
- public static void main(String[] args) throws Exception{
- File file=new File("D:\\1.txt");
- //①:定义资源
- Socket s=new Socket("127.0.0.1",10007);
- BufferedReader bufr=new BufferedReader(new FileReader(file));
- //字符流转换成字节流
- BufferedWriter bufout=new BufferedWriter(
- new OutputStreamWriter(s.getOutputStream()));
- // PrintWriter out=new PrintWriter(s.getOutputStream(),true);
- BufferedReader bufin=new BufferedReader(
- new InputStreamReader(s.getInputStream()));
- //将文件对象传到服务器
- ObjectOutputStream oos=new ObjectOutputStream(s.getOutputStream());
- oos.writeObject(file);
- //②上传数据
- String line=null;
- while((line=bufr.readLine())!=null){
- // System.out.println(line);
- bufout.write(line);
- bufout.newLine();
- bufout.flush();
- }
- //③告诉服务器,客户端已经传完了。并接收服务端的反馈信息
- s.shutdownOutput();//关闭客户端的输出流,相当于在流中写-1
- String line2=null;
- while((line2=bufin.readLine())!=null){
- if("success".equals(line2)){
- System.out.println("上传文件成功!");
- break;
- }
- }
- //④关闭资源
- bufr.close();
- s.close();
- }
- }
2)客户端:字符流
- import java.io.*;
- import java.net.*;
- /**
- * @author Administrator @zsw 2012-7-18 下午06:45:41
- *客户端:
- *①服务端点:Socket、流
- *②读取客户端的图片数据
- *③通过Socket输出流将数据发给服务端
- *④读取服务端反馈信息
- *⑤关闭资源
- */
- public class UploadPicClient2 {
- public static void main(String[] args) throws Exception{
- File file=new File("D:\\1.mp3");
- //①服务端点:
- Socket s=new Socket("127.0.0.1",10007);
- FileInputStream fis=new FileInputStream(file);
- OutputStream out=s.getOutputStream();
- InputStream in=s.getInputStream();
- //将文件对象传到服务器
- ObjectOutputStream oos=new ObjectOutputStream(s.getOutputStream());
- oos.writeObject(file);
- //②读取图片
- byte[]buf=new byte[1024*2];
- int len=0;
- while((len=fis.read(buf))!=-1){
- //③发送数据到服务端
- out.write(buf, 0, len);
- }
- //给服务端发送结束标记
- s.shutdownOutput();
- //④读取服务端反馈信息
- len=0;
- while((len=in.read(buf))!=-1){
- String str=new String(buf,0,len);
- System.out.println("服务端反馈:"+str);
- }
- //⑤关闭资源
- fis.close();
- s.close();
- }
- }
3)服务端:使用多线程
- import java.io.*;
- import java.net.*;
- /**
- * 总结:多线程文件的上传,数据流向
- * 1、客户端Socket:①out File对象 ②out 文件内容 ③in 服务端反馈信息
- *
- * 3、服务端的处理
- * ①每接收一个Socket,创建一个线程去处理这个Socket
- * ②in File对象:判断文件的类型、选择不同的传输方式、创建File对象关联文件
- * ③in 文件内容:填充File对象关联文件内容
- * ④填充完File文件,给客户端反馈
- *
- *
- * @author Administrator @zsw 2012-7-18 下午07:03:47
- * 此类在UploadPicServer.java上面做改进,使用了多线程.
- *
- *1单线程服务端:有局限,当A客户连接上来后,<br>
- *被服务器接收后, 服务端执行具体流程中,这时,B客户端连接,只有等待。
- *因为服务端还没有处理完A客户端的请求,
- *还没有循环回来执行下次 accept方法,所以暂时获取不到B客户端对象
- *
- *2解决思路:那么为了可以让多个客户端同时并发的访问服务器,
- *服务端最好就是将每一个客户端封装到一个单独的线程中。
- *
- *
- *
- */
- /*
- * 如何定义线程呢: 明确每一个客户端要在服务端执行的代码,将该代码放入run方法中
- */
- //3、线程类
- class UploadThread implements Runnable {
- // 客户端、文件、文件类型(简单点0表示文本、1表示字节流)
- private Socket s;
- UploadThread(Socket s) {
- this.s = s;
- }
- public void run() {
- try {
- Thread.sleep(5000);
- new FileUpload().upload(s);
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
- // 1、主程序
- public class UploadPicByThread {
- public static void main(String[] args) throws Exception {
- // ①定义服务端点:
- ServerSocket ss = new ServerSocket(10007);
- //②为每一个客户端开启一个
- int cNum=0;
- while (true) {
- Socket s = ss.accept();
- cNum++;
- new Thread(new UploadThread(s)).start();
- System.out.println("上传成功文件数:"+cNum);
- }
- }
- }
4、服务端:业务类,根据不同的上传,选择不同的方式
- import java.io.*;
- import java.net.*;
- // 2、业务类
- public class FileUpload {
- public void upload(Socket s) {
- try {
- ObjectInputStream ois=new ObjectInputStream(s.getInputStream());
- File file=(File)ois.readObject();
- //当发现文件存在时,修改文件名:如 1.mp3->(count++)1.mp3
- String name=file.getName();//原始文件名
- File dir=new File("D:\\tx\\");
- file=new File(dir,name);
- int count=0;
- while(file.exists()){
- count++;
- file=new File(dir,"("+count+")"+name);
- }
- /*当时文本文件时,调用文本上传方法
- * 否则调用字符流上传方法
- */
- if(name.endsWith(".txt")){
- textUpload(s,file);
- }else{
- picUpload(s,file);
- }
- } catch (Exception e) {
- System.out.println(e);
- System.out.println("上传失败");
- }
- }
- // ①图片等多媒体文件上传(字节流)
- public void picUpload(Socket s, File file) throws Exception{
- //打印客户端
- String ip=s.getInetAddress().getHostAddress();
- System.out.println(ip+"....connect 准备上传"+file.getName());
- FileOutputStream fos = new FileOutputStream(file);
- InputStream in = s.getInputStream();
- OutputStream out = s.getOutputStream();
- // ②读取数据
- int len = 0;
- byte[] buf = new byte[1024 * 2];
- while ((len = in.read(buf)) != -1) {
- fos.write(buf, 0, len);
- }
- // ③给客户端反馈
- System.out.println(file.getName()+"服务端接收完成");
- out.write("success".getBytes());
- // 给客户端发送结束标记
- s.shutdownOutput();
- // ④关闭资源
- fos.close();
- s.close();
- }
- // ②文本上传(字符流)
- public void textUpload(Socket s, File file) throws Exception {
- //打印客户端连接的
- String ip=s.getInetAddress().getHostAddress();
- System.out.println(ip+"....connect 准备上传"+file.getName());
- BufferedWriter bufw = new BufferedWriter(new FileWriter(file));
- // Socket 输出输入
- BufferedReader bufin = new BufferedReader(new InputStreamReader(
- s.getInputStream()));
- BufferedWriter bufout = new BufferedWriter(new OutputStreamWriter(
- s.getOutputStream()));
- // ②:读数据、写到文件、判断结束、反馈成功
- String line = null;
- /*
- * 服务端收不到line=null的情况,必须在流中添加结束标记 s.shutdownOutput();
- * 关闭客户端的输出流,相当于在流中写-1,line就可以=null
- */
- // 获取标记符(即时间值)
- while ((line = bufin.readLine()) != null) {
- bufw.write(line);
- bufw.newLine();
- bufw.flush();
- }
- System.out.println(file.getName()+"数据接收成功!");
- bufout.write("success");
- bufout.newLine();
- bufout.flush();
- s.shutdownOutput();
- // 关闭资源
- bufw.close();
- s.close();
- }
- }