67,513
社区成员
发帖
与我相关
我的任务
分享
package io;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.net.Socket;
/**
* 文件传输,客户端,负责连接FileServer并将其所传送过来的文件无条件记录下来
*/
public class FileClient {
public static final String SERVER = "localhost";
public static final int PORT = 8823;
public static final String DIR_PATH = "D:\\BO\\client";
public static File rootdir = new File(DIR_PATH);
byte[] buffer = new byte[16 * 1024]; // 16K缓存大小
/**
* @param msg 输出日志
*/
private void log(Object msg) {
System.out.println(msg);
}
void start() throws Exception {
Socket socket = new Socket(SERVER, PORT);
try {
log("成功连接服务器端,准备接收文件");
DataInputStream socketIn = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
while (readInTheFile(rootdir, socketIn));
} finally {
socket.close();
}
}
boolean readInTheFile(File dir, DataInputStream socketIn) throws Exception {
// 获取头部信息:文件大小、文件名长度、文件名
long filesize = socketIn.readLong();
if (filesize < 0) {
log("服务器端文件发送已经结束");
return false;
}
int namesize = socketIn.readInt();
socketIn.read(buffer, 0, namesize);
String filename = new String(buffer, 0, namesize);
log("得到文件信息,文件大小:" + filesize + "\t文件名长度:" + namesize + "\t" + filename);
// 准备本地写入文件
File file = new File(dir, filename);
FileOutputStream out = new FileOutputStream(file);
// 从服务器端获取文件内容,并写入本地
int size; // 记录每次读取大小
try {
while (true) {
size = (int) ((buffer.length < filesize) ? buffer.length : filesize);
size = socketIn.read(buffer, 0, size);
if (size <= 0)
break;
out.write(buffer, 0, size);
filesize -= size;
}
} finally {
out.close();
}
return true;
}
public static void main(String[] args) throws Exception {
new FileClient().start();
}
}
package io;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.net.ServerSocket;
import java.net.Socket;
/**
* 文件传输,服务端,负责将制定目录下的文件无条件发给FileClient
*/
public class FileServer {
public static final int PORT = 8823;
public static final String DIR_PATH = "D:\\BO\\server";
public static File rootdir = new File(DIR_PATH);
byte[] buffer = new byte[16 * 1024]; // 16K缓存大小
/**
* @param msg 输出日志
*/
private void log(Object msg) {
System.out.println(msg);
}
/**
* 服务启动函数
* @throws Exception 懒得写捕获异常及处理了
*/
void start() throws Exception {
ServerSocket serverSocket;
Socket socket;
while (true) {
serverSocket = new ServerSocket(PORT);
log("服务端就绪,等待客户端连接");
// 侦听并接受到此套接字的连接。此方法在进行连接之前一直阻塞。
socket = serverSocket.accept();
log("有客户端连接上来了,已建立Socket链接");
// 准备好输出(因为不关心客户端发什么信息过来,所以输入流也不管它了)
DataOutputStream socketOut = new DataOutputStream(socket.getOutputStream());
// 借助递归处理所有的目录下的文件
log("准备传输所有文件");
sendAllFile(rootdir, socketOut);
log("文件传输完成");
// 发送结束标志
socketOut.writeLong(-1);
serverSocket.close();
}
}
/**
* 借助递归处理所有的目录下的文件
* @param fileOrDir 文件或目录
* @param socketOut 面向FileClient的输出流
*/
private void sendAllFile(File fileOrDir, DataOutputStream socketOut) throws Exception {
if (fileOrDir.isDirectory()) {
File[] fs = fileOrDir.listFiles();
log("找到目录[" + fileOrDir.getName() + "],其下子目录及文件数:" + fs.length);
for (int i = 0; i < fs.length; i++) {
sendAllFile(fs[i], socketOut);
}
} else {
log("准备传输文件:" + fileOrDir.getName());
writeOutTheFile(fileOrDir, socketOut);
}
}
/**
* 文件发送
* @param file 文件
* @param socketOut 面向FileClient的输出流
*/
public void writeOutTheFile(File file, DataOutputStream socketOut) throws Exception {
// 先准备好文件名和总长度信息
String filename = file.getName();
byte[] bytename = filename.getBytes();
long fileSize = file.length();
int nameSize = bytename.length;
// 1、发送长度信息
log("发送长度信息:" + fileSize + "\t\t" + filename + ":" + nameSize);
socketOut.writeLong(fileSize);
socketOut.writeInt(nameSize);
// 2、发送文件名
socketOut.write(bytename);
// 3、发送文件内容
FileInputStream in = new FileInputStream(file);
int size; // 记录每次读取大小
try {
while ((size = in.read(buffer)) > 0) {
socketOut.write(buffer, 0, size);
}
} finally {
in.close();
}
socketOut.flush();
// 4、如果高兴的话,可以再发个MD5文件校验码,让FileClient去检查下所接收数据是否正确。
}
public static void main(String arg[]) throws Exception {
new FileServer().start();
}
}