我想用CS方式传送文件夹中的多个文件,打算将e:\\file 文件夹下的多个文件传送到 d:\\save\\file 文件夹下。
总是出现错误,先附上源码,请高手指教。
---------------------------------------------------------------
服务器端
---------------------------------------------------------------package fileTransfer;import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.BindException;
import java.net.ServerSocket;
import java.net.Socket;
//此为程序的服务端
//程序功能:用CS方式传送文件夹中的多个文件
//打算将客户端e:\\file 文件夹下的多个文件传送到 服务器d:\\save\\file 文件夹下
public class FileTransferServer {

public static final int PORT = 1124;

public static final String SAVE_FILE_PATH = "d:\\save";

boolean started = false;

ServerSocket ss = null; public void start() {
try {
ss = new ServerSocket(PORT);
started = true;
System.out.println("Server machine has started...");
} catch (BindException e) {
System.out.println("this port:"+ PORT +" had been uesed !");
System.out.println("please close all server and try again.");
System.exit(0);
} catch (IOException e) {
e.printStackTrace();
}

try {
while(started) {
Socket s = ss.accept();
Client c = new Client(s);
System.out.println("a client connected.");
new Thread(c).start();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}


class Client implements Runnable {
Socket s = null;
DataInputStream dis = null;
boolean bconnected = false;
public Client(Socket s) {
this.s = s;
try {
dis = new DataInputStream(
new BufferedInputStream(s.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
}
bconnected = true;
}

public void run() {
if(bconnected) {
receiveFolder(SAVE_FILE_PATH);
close();
} else {
System.out.println("this connection failed,please try a again.");
return;
}

} public void close() {
try {
if(dis != null) dis.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
bconnected = false;
}
}


public void receiveFolder(String saveFolderPath) {
String folderPath = null;
try {
folderPath = saveFolderPath + File.separator + dis.readUTF();
System.out.println(folderPath);
File folder = new File(folderPath);
if(!folder.exists()) {
folder.mkdir();
}
//该文件夹下的文件总数
int fileSum = dis.readInt();
System.out.println(fileSum); int bufferSize = 2048;
byte[] buf = new byte[bufferSize];
DataOutputStream dos = null;

for(int i = 0; i < fileSum; i ++) {
String fileName = folderPath + File.separator + dis.readUTF();
long size = dis.readLong();
System.out.println(fileName);
System.out.println("size: " + size); File f = new File(fileName);
f.createNewFile();
dos = new DataOutputStream(new BufferedOutputStream(
new FileOutputStream(f)));
int len = 0;
long passedSize = 0;
while((len = dis.read(buf)) != -1 && passedSize < size) {
passedSize += len;
dos.write(buf,0,len);
dos.flush();  System.out.println("this file has been passed:" 
+ 100 * passedSize / size + "%");
}
if(dos != null) dos.close();
System.out.println(f.getName() + " file has passed");

}
} catch (IOException e) {
e.printStackTrace();
}
}

}

public static void main(String[] args) {
new FileTransferServer().start();
}
}
----------------------------------------------------------------------
这是客户端代码
------------------------------------------------------------------------
package fileTransfer;import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;//此为程序的客户端
//程序功能:用CS方式传送文件夹中的多个文件
//打算将e:\\file 文件夹下的多个文件传送到 d:\\save\\file 文件夹下public class FileTransferClient {
public static final int PORT = 1124;
public static final String IP = "127.0.0.1";

public static final String FILE_PATH = "E:\\file";

boolean bconnected = false;

Socket s = null;
DataOutputStream dos = null;
DataInputStream dis = null;

void connect() {
try {
s = new Socket(IP,PORT);
dos = new DataOutputStream(new BufferedOutputStream(s.getOutputStream()));
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
bconnected = true;


sendFolder(FILE_PATH);
disConnect();
} void disConnect() {
try {
if(dis != null) dis.close();
dos.flush();
if(dos != null) dos.close();
if(s != null) s.close();
} catch (IOException e) {
e.printStackTrace();
}
bconnected = false;
}


public void sendFolder(String folderPath) {
String folderName = folderPath.substring(folderPath.lastIndexOf(File.separator) + 1);  try {
dos.writeUTF(folderName);
dos.flush();
File[] files = new File(folderPath).listFiles();
int sum = files.length; dos.writeInt(sum);
dos.flush();

int bufferSize = 2048;
byte[] buf = new byte[bufferSize];
DataInputStream dis = null;

for(int i = 0; i < files.length; i ++) {
System.out.println(files[i].getName());
System.out.println("size: " + files[i].length());
dos.writeUTF(files[i].getName());
dos.flush();
dos.writeLong(files[i].length());
dos.flush();

dis = new DataInputStream(new BufferedInputStream(
new FileInputStream(files[i])));
int len = 0;
int pass = 0;
while((len = dis.read(buf)) != -1 && pass < files[i].length()) {
pass += len;
dos.write(buf,0,len);
dos.flush();
System.out.println("pass : " + pass);
}

if(dis != null) dis.close();
}

} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(dis != null)
dis.close();
if(dos != null)
dos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

public static void main(String[] args) {
new FileTransferClient().connect();
}
}

解决方案 »

  1.   

    我测试了啊,d:\file\ 下面放一个文件是没有问题的。等我再试一试递归。
      

  2.   

    在Client内,
    sendFolder这个method内,这里至少要这样改。
    if (files[i].isFile()) {
    dis = new DataInputStream(new BufferedInputStream(
    new FileInputStream(files[i])));
    } else {
    sendFolder(files[i].getAbsolutePath());
    }
      

  3.   

        healer_kx,首先非常感谢你对本问题的关心。
         我看了你给的代码,文件传送是一定需要考虑递归的。为了问题简单,我就先不考虑递归吧,我们假定e:\\file只有一层,不知道有什么办法或着想法?
        我已经实现了一种办法:先将文件压缩,再传送到服务器解压,删除多余文件。这种方式到能递归传送,不过我发现在传送大文件是,压缩和解压所占用的时间明显比传送时间长。 
      

  4.   

    使用file.list可以取得所有的文件列表啊,然后一个一个的发送啊。
      

  5.   

    我觉得还是现在就考虑递归的好,我并不觉得它很复杂,
    说是客户端传送给服务器端,但是我觉得,你把它看成是client 操纵 server更合适。你要建立一套简单的协议,
    协议包含以下内容,:
        传送文件的名称,它是file还是dir
        传送文件的内容(限于文件)
        给出某个整文件夹总的size,便于计算 百分比。
        
      

  6.   

    是啊,我之前写过一个MFC的程序,完成包含这个内容,我的经验,你还是要先定义一个协议的。
      

  7.   

    同意楼上的,更通用的方法还是定义个简单协议,给个协议作为参考协议,这里就简称为数据包吧。
      数据包长度:   发送的整个数据包的长度, 定义长度固定 4 byte
      数据包命令字: 发送的数据包的含义,假设 1:发送文件,2:发送文件夹 等,自己定义,  定义长度固定 1 byte
      数据包校验值: 用于校验数据包在传输过程中是否发生改变,可以把数据包的内容通过md5算法计算的结果值填到这里,    定义长度固定 32 byte
      附加项:     附加信息,用于以后扩展, 定义长度固定 1 byte
      数据包内容:数据包内容那个,长度可变。
    数据包长度、数据包命令字、数据包校验值、 附加项简称为数据包头,长度固定。 先从输入流中读取数据包头信息,解析出数据包长度,再读取数据包的内容,然后校验数据包内容。
       
      

  8.   

    每个文件传递完成以后,再new一个socket。我也支持这种做法。