吐槽net下没有靠谱的FastDFS的sdk之使用thrift实现JAVA和C#互通

时间:2024-04-27 19:37:41

 

 事情是这样的,在一个新项目中引入了fastdfs,用这玩意做一些小数据的存储还是很方便的,然后在nuget上就找到了一个FastDFS的sdk,如下图:

吐槽net下没有靠谱的FastDFS的sdk之使用thrift实现JAVA和C#互通

一眼就看到了这个top1的sdk,应该会比较靠谱。。。简单的在项目中应用了一下没啥问题就忽悠上线了,然后就悲剧了,测试那边反馈说上传了一个

人群,拉下来的时候少了几个人,我的使用方式是将一批customerid按照bitmap的形式存到byte[]数组传到fastdfs,最后硬着头皮追踪下来发现是这个所谓

的sdk在upload的时候在bytes数组处理上出了bug,这下无语了,哎,nuget上这写sdk的估计也就是个人写着玩玩丢上去的,哪里敢用到生产上,还好在测

试环境发现了,不然又得出什么乱子了。

一:解决办法

  问题还得要解决,不过庆幸的是,fastdfs是阿里的一个大牛YuQing写的,那应该有java的sdk更靠谱一点,用maven的话更方便。

        <dependency>
<groupId>net.oschina.zcx7878</groupId>
<artifactId>fastdfs-client-java</artifactId>
<version>1.27.0.0</version>
</dependency>

pull下来以后,这个sdk果然是fastdfs的作者写的,这下子安全感暴增,测试了一下,那个bug用这个sdk果然就没有问题了。。。开心~~~~

吐槽net下没有靠谱的FastDFS的sdk之使用thrift实现JAVA和C#互通

  

然后流程图大概就变成了这个样子。

吐槽net下没有靠谱的FastDFS的sdk之使用thrift实现JAVA和C#互通

二:解决C# 和 JAVA的互通问题

  互通方式比较多,除了走rest这种面向http的方式,还可以使用thrift,grpc这种tcp的模式,最后我决定还是采用thrift走一遭,目前最新的版本是0.11了。

网址:http://thrift.apache.org/。 看了一下C#的thrift sdk,貌似最高支持0.9.1,网址为:http://archive.apache.org/dist/thrift/0.9.1/ ,

吐槽net下没有靠谱的FastDFS的sdk之使用thrift实现JAVA和C#互通

吐槽net下没有靠谱的FastDFS的sdk之使用thrift实现JAVA和C#互通

有了这个thrift-0.9.1.exe之后,接下来就可以定义Thrift的DSL,这个DSL可以让thrift-0.9.1.exe 生成各个语言版本的sdk。

1. 定义Thrift DSL

service ThriftService
{
string Upload(: binary data),
binary Download(: string path),
bool Remove(: string path)
}

有人可能会问,这个DSL怎么写,这个大家可以看看官方的DSL的各个关键词描述的网址:http://thrift.apache.org/docs/idl  还是比较简单的,如果不清楚的

话,这个是示例大全: https://git-wip-us.apache.org/repos/asf?p=thrift.git;a=blob_plain;f=test/ThriftTest.thrift;hb=HEAD ,然后保存为1.thrift。

2. 通过thrift生成 C# SDK

生成的方式可以参考一下官网的模板:

thrift --gen <language> <Thrift filename>
C:\Users\hxc>cd C:\java\lib\thrift

C:\java\lib\thrift>thrift-0.9..exe -gen csharp C:\java\lib\thrift\.thrift

吐槽net下没有靠谱的FastDFS的sdk之使用thrift实现JAVA和C#互通

可以看到,执行完之后,就多了一个gen-csharp文件夹,点进去看一下,会发现有一个文件名为DSL中定义的ThriftService.cs文件。

吐槽net下没有靠谱的FastDFS的sdk之使用thrift实现JAVA和C#互通

3. 通过thrift生成 JAVA SDK

执行完下面这条语句,你会发现你的文件夹又多了一份gen-java 。

C:\java\lib\thrift>thrift-0.9..exe -gen java C:\java\lib\thrift\.thrift

吐槽net下没有靠谱的FastDFS的sdk之使用thrift实现JAVA和C#互通

               

三:SDK集成

  改造之后,我们使用JAVA作为服务端,C#作客户端,服务端要做的事情就是通过JAVA来封装FastDFS,然后让C#来调用。

1. JAVA服务端

《1》使用fastDFS 和 Thrift的Maven地址:

        <!-- https://mvnrepository.com/artifact/org.apache.thrift/libthrift -->
<dependency>
<groupId>org.apache.thrift</groupId>
<artifactId>libthrift</artifactId>
<version>0.9.</version>
</dependency> <!-- https://mvnrepository.com/artifact/net.oschina.zcx7878/fastdfs-client-java -->
<dependency>
<groupId>net.oschina.zcx7878</groupId>
<artifactId>fastdfs-client-java</artifactId>
<version>1.27.0.0</version>
</dependency>

《2》 ThriftServiceImpl.java 实现类:

 package com.datamip.thrift;

 import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Date; import org.apache.log4j.Logger;
import org.apache.thrift.TException;
import org.csource.common.MyException;
import org.csource.fastdfs.StorageClient; import com.fasterxml.jackson.databind.ObjectMapper; /*
* thrift 服务端
*/
public class ThriftServiceImpl implements ThriftService.Iface { public static Logger logger1 = Logger.getLogger(App.class); StorageClient client = null; ObjectMapper objectMapper=new ObjectMapper(); public ThriftServiceImpl() throws IOException, MyException {
client = new FastService().Create();
} //上传文件
public String Upload(ByteBuffer data) { byte[] bytes = data.array(); logger1.info("已成功接受到upload请求: bytes.length="+bytes.length); if(bytes==null || bytes.length==) return ""; // 目前给的 “后缀名为 g1",以后可以动态变更,通过‘阿波罗’动态配置
String[] result = null; try {
result = client.upload_file(bytes, "g1", null); logger1.info("update 上传结果为: "+objectMapper.writeValueAsString(result)); if (result.length < ) return ""; }catch (Exception e) {
logger1.error("upload异常",e);
} return result[];
} // 文件下载
public ByteBuffer Download(String path) throws TException { logger1.info("已成功接受到download请求:"+path); if (path == null || path == "")
return ByteBuffer.allocate(); String[] arr = path.split("\\."); if (arr.length < )
return ByteBuffer.allocate(); String group_name = arr[]; try {
byte[] bytes = client.download_file(group_name, path); logger1.info(String.format("根据path=%s,获取的bytes长度为:%s",path,bytes.length)); return ByteBuffer.wrap(bytes); }catch (Exception e) {
logger1.error("download异常",e);
} // TODO Auto-generated method stub
return ByteBuffer.allocate();
} // 删除文件
public boolean Remove(String path) throws TException { logger1.info("已成功接受到remove请求:"+path); if (path == null || path == "") return false; String[] arr = path.split("\\."); if(arr==null || arr.length<) return false; String group_name = arr[]; try {
int code = client.delete_file(group_name, path); logger1.info(String.format("当前path=%s, groupname=%s,返回状态值=%s",
path,group_name,code)); if(code==) {
return true;
} }catch (Exception e) {
logger1.error("Remove异常",e);
} return false;
}
}

《3》 FastDFS的封装类

 package com.datamip.thrift;

 import java.io.IOException;

 import org.csource.common.MyException;
import org.csource.fastdfs.ClientGlobal;
import org.csource.fastdfs.StorageClient;
import org.csource.fastdfs.StorageServer;
import org.csource.fastdfs.TrackerClient;
import org.csource.fastdfs.TrackerServer; import com.datamip.utils.PropertiesUtils; public class FastService { public StorageClient Create() throws IOException, MyException { //读取配置文件
String path = PropertiesUtils.getProperties("setting.properties","fastdfs");
return this.Create(path);
} public StorageClient Create(String host) throws IOException, MyException { ClientGlobal.initByTrackers(host); // 3、创建一个TrackerClient对象。
TrackerClient trackerClient = new TrackerClient(); // 4、创建一个TrackerServer对象。
TrackerServer trackerServer = trackerClient.getConnection(); // 5、声明一个StorageServer对象,null。
StorageServer storageServer = null; // 6、获得StorageClient对象。
StorageClient storageClient = new StorageClient(trackerServer, storageServer); return storageClient;
}
}

《4》最后就是AppMain,Thrift开启19999端口。

 package com.datamip.thrift;

 import java.io.IOException;

 import org.apache.log4j.Logger;
import org.apache.thrift.TProcessor;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TSimpleServer;
import org.apache.thrift.transport.TServerSocket;
import org.apache.thrift.transport.TTransportException;
import org.csource.common.MyException; public class App { public static Logger logger1 = Logger.getLogger(App.class); public static void main(String[] args) throws IOException, MyException { try {
TProcessor tprocessor = new ThriftService.Processor<ThriftService.Iface>(new ThriftServiceImpl()); TServerSocket serverTransport = new TServerSocket();
TServer.Args tArgs = new TServer.Args(serverTransport); tArgs.processor(tprocessor);
tArgs.protocolFactory(new TBinaryProtocol.Factory()); logger1.debug("thrift 服务端开启,开放端口 19999"); TServer server = new TSimpleServer(tArgs);
server.serve();
} catch (TTransportException e) {
e.printStackTrace();
}
}
}

2. C#客户端

《1》 从negut上把dll拉下来,然后把生成的ThriftService.cs引入到我们的解决方案中

  public partial class ThriftService
{
public interface Iface
{
string Upload(byte[] data);
#if SILVERLIGHT
IAsyncResult Begin_Upload(AsyncCallback callback, object state, byte[] data);
string End_Upload(IAsyncResult asyncResult);
#endif
byte[] Download(string path);
#if SILVERLIGHT
IAsyncResult Begin_Download(AsyncCallback callback, object state, string path);
byte[] End_Download(IAsyncResult asyncResult);
#endif
bool Remove(string path);
#if SILVERLIGHT
IAsyncResult Begin_Remove(AsyncCallback callback, object state, string path);
bool End_Remove(IAsyncResult asyncResult);
#endif
} public class Client : IDisposable, Iface
{
public Client(TProtocol prot) : this(prot, prot)
{
} public Client(TProtocol iprot, TProtocol oprot)
{
iprot_ = iprot;
oprot_ = oprot;
} protected TProtocol iprot_;
protected TProtocol oprot_;
protected int seqid_; public TProtocol InputProtocol
{
get { return iprot_; }
}
public TProtocol OutputProtocol
{
get { return oprot_; }
} #region " IDisposable Support "
private bool _IsDisposed; // IDisposable
public void Dispose()
{
Dispose(true);
} protected virtual void Dispose(bool disposing)
{
if (!_IsDisposed)
{
if (disposing)
{
if (iprot_ != null)
{
((IDisposable)iprot_).Dispose();
}
if (oprot_ != null)
{
((IDisposable)oprot_).Dispose();
}
}
}
_IsDisposed = true;
}
#endregion #if SILVERLIGHT
public IAsyncResult Begin_Upload(AsyncCallback callback, object state, byte[] data)
{
return send_Upload(callback, state, data);
} public string End_Upload(IAsyncResult asyncResult)
{
oprot_.Transport.EndFlush(asyncResult);
return recv_Upload();
} #endif public string Upload(byte[] data)
{
#if !SILVERLIGHT
send_Upload(data);
return recv_Upload(); #else
var asyncResult = Begin_Upload(null, null, data);
return End_Upload(asyncResult); #endif
}
#if SILVERLIGHT
public IAsyncResult send_Upload(AsyncCallback callback, object state, byte[] data)
#else
public void send_Upload(byte[] data)
#endif
{
oprot_.WriteMessageBegin(new TMessage("Upload", TMessageType.Call, seqid_));
Upload_args args = new Upload_args();
args.Data = data;
args.Write(oprot_);
oprot_.WriteMessageEnd();
#if SILVERLIGHT
return oprot_.Transport.BeginFlush(callback, state);
#else
oprot_.Transport.Flush();
#endif
} public string recv_Upload()
{
TMessage msg = iprot_.ReadMessageBegin();
if (msg.Type == TMessageType.Exception)
{
TApplicationException x = TApplicationException.Read(iprot_);
iprot_.ReadMessageEnd();
throw x;
}
Upload_result result = new Upload_result();
result.Read(iprot_);
iprot_.ReadMessageEnd();
if (result.__isset.success)
{
return result.Success;
}
throw new TApplicationException(TApplicationException.ExceptionType.MissingResult, "Upload failed: unknown result");
} #if SILVERLIGHT
public IAsyncResult Begin_Download(AsyncCallback callback, object state, string path)
{
return send_Download(callback, state, path);
} public byte[] End_Download(IAsyncResult asyncResult)
{
oprot_.Transport.EndFlush(asyncResult);
return recv_Download();
} #endif public byte[] Download(string path)
{
#if !SILVERLIGHT
send_Download(path);
return recv_Download(); #else
var asyncResult = Begin_Download(null, null, path);
return End_Download(asyncResult); #endif
}
#if SILVERLIGHT
public IAsyncResult send_Download(AsyncCallback callback, object state, string path)
#else
public void send_Download(string path)
#endif
{
oprot_.WriteMessageBegin(new TMessage("Download", TMessageType.Call, seqid_));
Download_args args = new Download_args();
args.Path = path;
args.Write(oprot_);
oprot_.WriteMessageEnd();
#if SILVERLIGHT
return oprot_.Transport.BeginFlush(callback, state);
#else
oprot_.Transport.Flush();
#endif
} public byte[] recv_Download()
{
TMessage msg = iprot_.ReadMessageBegin();
if (msg.Type == TMessageType.Exception)
{
TApplicationException x = TApplicationException.Read(iprot_);
iprot_.ReadMessageEnd();
throw x;
}
Download_result result = new Download_result();
result.Read(iprot_);
iprot_.ReadMessageEnd();
if (result.__isset.success)
{
return result.Success;
}
throw new TApplicationException(TApplicationException.ExceptionType.MissingResult, "Download failed: unknown result");
} #if SILVERLIGHT
public IAsyncResult Begin_Remove(AsyncCallback callback, object state, string path)
{
return send_Remove(callback, state, path);
} public bool End_Remove(IAsyncResult asyncResult)
{
oprot_.Transport.EndFlush(asyncResult);
return recv_Remove();
} #endif public bool Remove(string path)
{
#if !SILVERLIGHT
send_Remove(path);
return recv_Remove(); #else
var asyncResult = Begin_Remove(null, null, path);
return End_Remove(asyncResult); #endif
}
#if SILVERLIGHT
public IAsyncResult send_Remove(AsyncCallback callback, object state, string path)
#else
public void send_Remove(string path)
#endif
{
oprot_.WriteMessageBegin(new TMessage("Remove", TMessageType.Call, seqid_));
Remove_args args = new Remove_args();
args.Path = path;
args.Write(oprot_);
oprot_.WriteMessageEnd();
#if SILVERLIGHT
return oprot_.Transport.BeginFlush(callback, state);
#else
oprot_.Transport.Flush();
#endif
} public bool recv_Remove()
{
TMessage msg = iprot_.ReadMessageBegin();
if (msg.Type == TMessageType.Exception)
{
TApplicationException x = TApplicationException.Read(iprot_);
iprot_.ReadMessageEnd();
throw x;
}
Remove_result result = new Remove_result();
result.Read(iprot_);
iprot_.ReadMessageEnd();
if (result.__isset.success)
{
return result.Success;
}
throw new TApplicationException(TApplicationException.ExceptionType.MissingResult, "Remove failed: unknown result");
} }
public class Processor : TProcessor
{
public Processor(Iface iface)
{
iface_ = iface;
processMap_["Upload"] = Upload_Process;
processMap_["Download"] = Download_Process;
processMap_["Remove"] = Remove_Process;
} protected delegate void ProcessFunction(int seqid, TProtocol iprot, TProtocol oprot);
private Iface iface_;
protected Dictionary<string, ProcessFunction> processMap_ = new Dictionary<string, ProcessFunction>(); public bool Process(TProtocol iprot, TProtocol oprot)
{
try
{
TMessage msg = iprot.ReadMessageBegin();
ProcessFunction fn;
processMap_.TryGetValue(msg.Name, out fn);
if (fn == null)
{
TProtocolUtil.Skip(iprot, TType.Struct);
iprot.ReadMessageEnd();
TApplicationException x = new TApplicationException(TApplicationException.ExceptionType.UnknownMethod, "Invalid method name: '" + msg.Name + "'");
oprot.WriteMessageBegin(new TMessage(msg.Name, TMessageType.Exception, msg.SeqID));
x.Write(oprot);
oprot.WriteMessageEnd();
oprot.Transport.Flush();
return true;
}
fn(msg.SeqID, iprot, oprot);
}
catch (IOException)
{
return false;
}
return true;
} public void Upload_Process(int seqid, TProtocol iprot, TProtocol oprot)
{
Upload_args args = new Upload_args();
args.Read(iprot);
iprot.ReadMessageEnd();
Upload_result result = new Upload_result();
result.Success = iface_.Upload(args.Data);
oprot.WriteMessageBegin(new TMessage("Upload", TMessageType.Reply, seqid));
result.Write(oprot);
oprot.WriteMessageEnd();
oprot.Transport.Flush();
} public void Download_Process(int seqid, TProtocol iprot, TProtocol oprot)
{
Download_args args = new Download_args();
args.Read(iprot);
iprot.ReadMessageEnd();
Download_result result = new Download_result();
result.Success = iface_.Download(args.Path);
oprot.WriteMessageBegin(new TMessage("Download", TMessageType.Reply, seqid));
result.Write(oprot);
oprot.WriteMessageEnd();
oprot.Transport.Flush();
} public void Remove_Process(int seqid, TProtocol iprot, TProtocol oprot)
{
Remove_args args = new Remove_args();
args.Read(iprot);
iprot.ReadMessageEnd();
Remove_result result = new Remove_result();
result.Success = iface_.Remove(args.Path);
oprot.WriteMessageBegin(new TMessage("Remove", TMessageType.Reply, seqid));
result.Write(oprot);
oprot.WriteMessageEnd();
oprot.Transport.Flush();
} } #if !SILVERLIGHT
[Serializable]
#endif
public partial class Upload_args : TBase
{
private byte[] _data; public byte[] Data
{
get
{
return _data;
}
set
{
__isset.data = true;
this._data = value;
}
} public Isset __isset;
#if !SILVERLIGHT
[Serializable]
#endif
public struct Isset
{
public bool data;
} public Upload_args()
{
} public void Read(TProtocol iprot)
{
TField field;
iprot.ReadStructBegin();
while (true)
{
field = iprot.ReadFieldBegin();
if (field.Type == TType.Stop)
{
break;
}
switch (field.ID)
{
case :
if (field.Type == TType.String)
{
Data = iprot.ReadBinary();
}
else
{
TProtocolUtil.Skip(iprot, field.Type);
}
break;
default:
TProtocolUtil.Skip(iprot, field.Type);
break;
}
iprot.ReadFieldEnd();
}
iprot.ReadStructEnd();
} public void Write(TProtocol oprot)
{
TStruct struc = new TStruct("Upload_args");
oprot.WriteStructBegin(struc);
TField field = new TField();
if (Data != null && __isset.data)
{
field.Name = "data";
field.Type = TType.String;
field.ID = ;
oprot.WriteFieldBegin(field);
oprot.WriteBinary(Data);
oprot.WriteFieldEnd();
}
oprot.WriteFieldStop();
oprot.WriteStructEnd();
} public override string ToString()
{
StringBuilder sb = new StringBuilder("Upload_args(");
sb.Append("Data: ");
sb.Append(Data);
sb.Append(")");
return sb.ToString();
} } #if !SILVERLIGHT
[Serializable]
#endif
public partial class Upload_result : TBase
{
private string _success; public string Success
{
get
{
return _success;
}
set
{
__isset.success = true;
this._success = value;
}
} public Isset __isset;
#if !SILVERLIGHT
[Serializable]
#endif
public struct Isset
{
public bool success;
} public Upload_result()
{
} public void Read(TProtocol iprot)
{
TField field;
iprot.ReadStructBegin();
while (true)
{
field = iprot.ReadFieldBegin();
if (field.Type == TType.Stop)
{
break;
}
switch (field.ID)
{
case :
if (field.Type == TType.String)
{
Success = iprot.ReadString();
}
else
{
TProtocolUtil.Skip(iprot, field.Type);
}
break;
default:
TProtocolUtil.Skip(iprot, field.Type);
break;
}
iprot.ReadFieldEnd();
}
iprot.ReadStructEnd();
} public void Write(TProtocol oprot)
{
TStruct struc = new TStruct("Upload_result");
oprot.WriteStructBegin(struc);
TField field = new TField(); if (this.__isset.success)
{
if (Success != null)
{
field.Name = "Success";
field.Type = TType.String;
field.ID = ;
oprot.WriteFieldBegin(field);
oprot.WriteString(Success);
oprot.WriteFieldEnd();
}
}
oprot.WriteFieldStop();
oprot.WriteStructEnd();
} public override string ToString()
{
StringBuilder sb = new StringBuilder("Upload_result(");
sb.Append("Success: ");
sb.Append(Success);
sb.Append(")");
return sb.ToString();
} } #if !SILVERLIGHT
[Serializable]
#endif
public partial class Download_args : TBase
{
private string _path; public string Path
{
get
{
return _path;
}
set
{
__isset.path = true;
this._path = value;
}
} public Isset __isset;
#if !SILVERLIGHT
[Serializable]
#endif
public struct Isset
{
public bool path;
} public Download_args()
{
} public void Read(TProtocol iprot)
{
TField field;
iprot.ReadStructBegin();
while (true)
{
field = iprot.ReadFieldBegin();
if (field.Type == TType.Stop)
{
break;
}
switch (field.ID)
{
case :
if (field.Type == TType.String)
{
Path = iprot.ReadString();
}
else
{
TProtocolUtil.Skip(iprot, field.Type);
}
break;
default:
TProtocolUtil.Skip(iprot, field.Type);
break;
}
iprot.ReadFieldEnd();
}
iprot.ReadStructEnd();
} public void Write(TProtocol oprot)
{
TStruct struc = new TStruct("Download_args");
oprot.WriteStructBegin(struc);
TField field = new TField();
if (Path != null && __isset.path)
{
field.Name = "path";
field.Type = TType.String;
field.ID = ;
oprot.WriteFieldBegin(field);
oprot.WriteString(Path);
oprot.WriteFieldEnd();
}
oprot.WriteFieldStop();
oprot.WriteStructEnd();
} public override string ToString()
{
StringBuilder sb = new StringBuilder("Download_args(");
sb.Append("Path: ");
sb.Append(Path);
sb.Append(")");
return sb.ToString();
} } #if !SILVERLIGHT
[Serializable]
#endif
public partial class Download_result : TBase
{
private byte[] _success; public byte[] Success
{
get
{
return _success;
}
set
{
__isset.success = true;
this._success = value;
}
} public Isset __isset;
#if !SILVERLIGHT
[Serializable]
#endif
public struct Isset
{
public bool success;
} public Download_result()
{
} public void Read(TProtocol iprot)
{
TField field;
iprot.ReadStructBegin();
while (true)
{
field = iprot.ReadFieldBegin();
if (field.Type == TType.Stop)
{
break;
}
switch (field.ID)
{
case :
if (field.Type == TType.String)
{
Success = iprot.ReadBinary();
}
else
{
TProtocolUtil.Skip(iprot, field.Type);
}
break;
default:
TProtocolUtil.Skip(iprot, field.Type);
break;
}
iprot.ReadFieldEnd();
}
iprot.ReadStructEnd();
} public void Write(TProtocol oprot)
{
TStruct struc = new TStruct("Download_result");
oprot.WriteStructBegin(struc);
TField field = new TField(); if (this.__isset.success)
{
if (Success != null)
{
field.Name = "Success";
field.Type = TType.String;
field.ID = ;
oprot.WriteFieldBegin(field);
oprot.WriteBinary(Success);
oprot.WriteFieldEnd();
}
}
oprot.WriteFieldStop();
oprot.WriteStructEnd();
} public override string ToString()
{
StringBuilder sb = new StringBuilder("Download_result(");
sb.Append("Success: ");
sb.Append(Success);
sb.Append(")");
return sb.ToString();
} } #if !SILVERLIGHT
[Serializable]
#endif
public partial class Remove_args : TBase
{
private string _path; public string Path
{
get
{
return _path;
}
set
{
__isset.path = true;
this._path = value;
}
} public Isset __isset;
#if !SILVERLIGHT
[Serializable]
#endif
public struct Isset
{
public bool path;
} public Remove_args()
{
} public void Read(TProtocol iprot)
{
TField field;
iprot.ReadStructBegin();
while (true)
{
field = iprot.ReadFieldBegin();
if (field.Type == TType.Stop)
{
break;
}
switch (field.ID)
{
case :
if (field.Type == TType.String)
{
Path = iprot.ReadString();
}
else
{
TProtocolUtil.Skip(iprot, field.Type);
}
break;
default:
TProtocolUtil.Skip(iprot, field.Type);
break;
}
iprot.ReadFieldEnd();
}
iprot.ReadStructEnd();
} public void Write(TProtocol oprot)
{
TStruct struc = new TStruct("Remove_args");
oprot.WriteStructBegin(struc);
TField field = new TField();
if (Path != null && __isset.path)
{
field.Name = "path";
field.Type = TType.String;
field.ID = ;
oprot.WriteFieldBegin(field);
oprot.WriteString(Path);
oprot.WriteFieldEnd();
}
oprot.WriteFieldStop();
oprot.WriteStructEnd();
} public override string ToString()
{
StringBuilder sb = new StringBuilder("Remove_args(");
sb.Append("Path: ");
sb.Append(Path);
sb.Append(")");
return sb.ToString();
} } #if !SILVERLIGHT
[Serializable]
#endif
public partial class Remove_result : TBase
{
private bool _success; public bool Success
{
get
{
return _success;
}
set
{
__isset.success = true;
this._success = value;
}
} public Isset __isset;
#if !SILVERLIGHT
[Serializable]
#endif
public struct Isset
{
public bool success;
} public Remove_result()
{
} public void Read(TProtocol iprot)
{
TField field;
iprot.ReadStructBegin();
while (true)
{
field = iprot.ReadFieldBegin();
if (field.Type == TType.Stop)
{
break;
}
switch (field.ID)
{
case :
if (field.Type == TType.Bool)
{
Success = iprot.ReadBool();
}
else
{
TProtocolUtil.Skip(iprot, field.Type);
}
break;
default:
TProtocolUtil.Skip(iprot, field.Type);
break;
}
iprot.ReadFieldEnd();
}
iprot.ReadStructEnd();
} public void Write(TProtocol oprot)
{
TStruct struc = new TStruct("Remove_result");
oprot.WriteStructBegin(struc);
TField field = new TField(); if (this.__isset.success)
{
field.Name = "Success";
field.Type = TType.Bool;
field.ID = ;
oprot.WriteFieldBegin(field);
oprot.WriteBool(Success);
oprot.WriteFieldEnd();
}
oprot.WriteFieldStop();
oprot.WriteStructEnd();
} public override string ToString()
{
StringBuilder sb = new StringBuilder("Remove_result(");
sb.Append("Success: ");
sb.Append(Success);
sb.Append(")");
return sb.ToString();
} } }

《2》 封装一个简单的CURD操作

     public class ThriftSHelper
{
private static string fastdfs = ConfigurationManager.AppSettings["fastdfs"]; TTransport transport = null;
TProtocol protocol = null;
ThriftService.Client client = null; public ThriftSHelper()
{
var arr = fastdfs.Split(':');
var host = arr[];
var port = Convert.ToInt32(arr[]); transport = new TSocket(host, port);
protocol = new TBinaryProtocol(transport);
client = new ThriftService.Client(protocol);
} public static ThriftSHelper Create()
{
return new ThriftSHelper();
} public string UploadFile(BitArray bit)
{
string path = string.Empty; try
{
var bytes = new byte[Convert.ToInt32(Math.Ceiling((double)bit.Length / ))]; transport.Open(); bit.CopyTo(bytes, ); path = client.Upload(bytes);
}
catch (Exception ex)
{
LogHelper.Error(ex);
}
finally
{
transport.Close();
} return path;
} /// <summary>
/// 下载文件
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
public BitArray DownloadFile(string fileName)
{
BitArray bitArray = null; try
{
transport.Open(); var bytes = client.Download(fileName); return new BitArray(bytes);
}
catch (Exception ex)
{
LogHelper.WriteLog(fileName, ex);
}
finally
{
transport.Close();
} return bitArray;
} /// <summary>
/// 删除文件
/// </summary>
/// <param name="fileName"></param>
public void RemoveFile(string fileName)
{
try
{
transport.Open(); client.Remove(fileName);
}
catch (Exception ex)
{
LogHelper.WriteLog(ex);
}
finally
{
transport.Close();
}
}
}

  好了,这个问题我们就这样完美解决了,跑在生产上还是蛮好的。