这里简单展现一下 Thrift 的文件传输功能
一 . 设计 Thrift 的接口定义
新建 Thrift 接口定义文件 Interface.thrift , 作为客户端和服务端进行通信说明,里面内容如下 :
// -------------------------------------------------------------------- File
struct FileData
{
1:required string name, // 文件名字
2:required binary buff, // 文件数据
}
// -------------------------------------------------------------------- Service
service FileInfoExtractService
{
bool uploadFile(1:FileData filedata); // 文件解析函数
}
命令行切换到 Interface.thrift 文件所在目录,执行> thrift.exe -gen java Interface.thrift , 生成文件 FileData.java 和 FileService.java , 这两个文件在 Thrift 的 Server 端 和 Client 端都会被用上。
二 . 建立 Thrift 的 Client 端项目
1. Client 项目包含 3 个文件:除了步骤一中生成的 FileData.java 和 FileService.java 之外,新建一个 App.java 文件作为程序入口
2. Client 项目中 FileData.java 和 FileService.java 的具体代码由 Thrift 生成,这里略
3. Client 项目中 App.java 的代码如下:
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.transport.TFramedTransport;
import org.apache.thrift.transport.TSocket;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.nio.ByteBuffer;
public class App
{
/**
* 类内测试 main 函数
* */
public static void main(String[] args)
{
// 测试文件路径
String filePath = "C:\\Users\\jiangmengya\\Desktop\\1.jpg";
// 构造文件数据
byte[] bytes = toByteArray(filePath);
FileData fileData = new FileData();
fileData.name = filePath;
fileData.buff = ByteBuffer.wrap(bytes);
// 构造Thrift客户端,发起请求
try
{
TSocket socket = new TSocket("localhost", 12345);
socket.setSocketTimeout(60 * 1000);
TFramedTransport framedTransport = new TFramedTransport(socket);
framedTransport.open();
TBinaryProtocol binaryProtocol = new TBinaryProtocol(framedTransport);
FileService.Client client = new FileService.Client(binaryProtocol);
client.uploadFile(fileData);
}
catch (Exception x)
{
x.printStackTrace();
}
}
/**
* 文件转化为字节数组
* */
private static byte[] toByteArray(String filePath){
byte[] buffer = null;
try {
File file = new File(filePath);
FileInputStream fis = new FileInputStream(file);
ByteArrayOutputStream bos = new ByteArrayOutputStream(1000);
byte[] b = new byte[1000];
int n;
while ((n = fis.read(b)) != -1) {
bos.write(b, 0, n);
}
fis.close();
bos.close();
buffer = bos.toByteArray();
} catch (Exception e) {
e.printStackTrace();
}
return buffer;
}
}
三. 建立 Thrift 的 Server 端项目
1. Server 项目包含 4 个文件:除了步骤一中生成的 FileData.java 和 FileService.java 之外,新建一个 App.java 文件作为程序入口, 新建一个 FileServiceImpl.java 文件来对 Thrift 服务进行具体的实现
2. Server 项目中 FileServiceImpl.java 的代码如下:
import org.apache.thrift.TException;
import java.io.FileOutputStream;
import java.nio.channels.FileChannel;
public class FileServiceImpl implements FileService.Iface
{
@Override
public boolean uploadFile(FileData filedata) throws TException
{
System.out.println("uploadFile function has been called.");
// 写到文件
String filePath = "C:\\Users\\jiangmengya\\Desktop\\2.jpg";
try
{
java.io.File file = new java.io.File(filePath);
FileOutputStream fos = new FileOutputStream(file);
FileChannel channel = fos.getChannel();
channel.write(filedata.buff);
channel.close();
}
catch (Exception x)
{
x.printStackTrace();
return false;
}
return true;
}
}
3. Server 项目中 App.java 的代码如下:
import org.apache.thrift.TProcessor;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TThreadedSelectorServer;
import org.apache.thrift.transport.TFramedTransport;
import org.apache.thrift.transport.TNonblockingServerSocket;
import org.apache.thrift.transport.TNonblockingServerTransport;
import org.apache.thrift.transport.TTransportFactory;
public class App
{
public static void main(String[] args)
{
try
{
// 创建非阻塞的 Transport
TNonblockingServerTransport serverSocket = new TNonblockingServerSocket(12345);
// 创建 Processor
TProcessor processor = new FileService.Processor
(new FileServiceImpl());
// 创建 transport factory , Nonblocking 使用 TFramedTransport
TTransportFactory transportFactory = new TFramedTransport.Factory();
// 创建 protocol factory
TBinaryProtocol.Factory protocolFactory = new TBinaryProtocol.Factory();
// 创建 arguments
TThreadedSelectorServer.Args tArgs = new TThreadedSelectorServer.Args(serverSocket);
tArgs.processor(processor);
tArgs.transportFactory(transportFactory);
tArgs.protocolFactory(protocolFactory);
// 创建 server
TServer server = new TThreadedSelectorServer(tArgs);
// 启动 server
server.serve();
}
catch (Exception x)
{
x.printStackTrace();
}
}
}
四. 运行项目
1. 运行 Server 项目 App
2. 运行 Client 项目 App
3. 输出:
uploadFile function has been called.
(同时,Client 指定的图片 1.jpg 也会被拷贝传输到 Server 指定的路径下成为 2.jpg)