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

一眼就看到了这个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果然就没有问题了。。。开心~~~~

  

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

二:解决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/ ,

有了这个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

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

3. 通过thrift生成 JAVA SDK

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

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

               

三: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();
}
}
}

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

吐槽net下没有靠谱的FastDFS的sdk之使用thrift实现JAVA和C#互通的更多相关文章

  1. 短视频sdk:选择一个靠谱的短视频SDK 你需要了解这些

    2017 年,短视频成为了内容创业的新风口,各种短视频 App 如雨后春笋般先后上线.随着互联网内容消费升级,视频越来越像文字.图片一样,成为每一个 App 不可或缺的一部分. 为了能够更好地聚焦于业 ...

  2. ubuntu下使用golang、qml与ubuntu sdk开发桌面应用

    ubuntu下使用golang.qml与ubuntu sdk开发桌面应用 (简单示例) 找了很长时间go的gui库,试了gtk,准备试qt的时候发现了这个qml库,试了下很好用. 准备工作 1.Go ...

  3. myecplise上将工程部署到应用下时,经常出现 An internal error occurred during: "Add Deployment". java.lang.NullPointEx

    myecplise上将工程部署到应用下时,经常出现 An internal error occurred during: "Add Deployment". java.lang.N ...

  4. Linux下离线安装docker与fastDFS

    一.Linux下离线安装Docker 基础环境 1.操作系统:CentOS 7 2.Docker版本:docker-19.03.9.tgz 官方下载地址(打不开可能需要科学-上网) 3.官方参考文档: ...

  5. windows 下文件上传到fastdfs

    php.ini 配置 [fastdfs]; the base pathfastdfs_client.base_path = D:/tmp ; connect timeout in seconds; d ...

  6. Ubuntu16.04下ZeroC ICE的安装与使用示例(Qt C++ 和 Java)

    项目需求:在Ubuntu16.04系统下安装并使用ICEgrid 3.7进行c++和Java Springboot开发环境的通信,下面逐一介绍各个步骤的详解: 一:Ice Lib的安装 参考官网地址: ...

  7. ubuntu下使用golang、qml与ubuntu sdk开发桌面应用 (简单示例)

    找了很长时间go的gui库,试了gtk,准备试qt的时候发现了这个qml库,试了下很好用. ##准备工作 **1.Go 1.2RC1** go的版本应该不能低于这个,我是在1.2RC发布当天升级后发现 ...

  8. Windows环境下教你用Eclipse ADT 插件生成.h/.so文件,Java下调用JNI,轻松学习JNI

    准备工作:Eclipse ADT IDE 开发工具,NDK .Java 环境,博主的配置是:Windows x86 , ADT Build: v22.3.0-887826 , JAVA 1.7, ND ...

  9. windows8.1下android开发环境搭建(Eclipse+Android sdk+ADT+Genymotion)

    一.基本jdk.eclipse环境 二.android sdk 1.下载安装:https://developer.android.com/sdk/installing/index.html?pkg=t ...

随机推荐

  1. Davinci DM6446开发攻略——u-boot-1.3.4移植(1)

    UBOOT的版本更新速度比较快,截止今天,稳定正式的版本是u-boot-2009.11-rc2,而TI最新的EVM开发包里的UBOOT是1.2.0版本,国内很多公司还一直使用u-boot-1.1.4和 ...

  2. Srtuts2实现登录界面(不连接数据库)

    1.设计思路 (1)利用Struts2框架设计出一个登录页面的跳转,当用户名和密码都正确时, 跳到登录成功页面:否则,跳到登录失败页面,并在10秒钟内跳到登录界面: (2)在Action中判断用户名和 ...

  3. Android之PendingIntent的深入理解

    PendingIntent字面意义:等待的,未决定的Intent.要得到一个pendingIntent对象,使用方法类的静态方法 getActivity(Context, int, Intent, i ...

  4. STM32F4 输入输出(GPIO)模式理解

    stm32的GPIO的配置模式有好几种,包括: 1. 模拟输入: 2. 浮空输入: 3. 上拉输入: 4. 下拉输入: 5. 开漏输出: 6. 推挽输出: 7. 复用开漏输出: 8. 复用推挽输出   ...

  5. freemarker自定义标签报错(二)

    freemarker自定义标签 1.错误描述 freemarker.core.ParseException: Unexpected end of file reached. at freemarker ...

  6. RTSP协议分析

    RTSP 协议分析 1.概述:  RTSP(Real Time Streaming Protocol),实时流传输协议,是TCP/IP协议体系中的一个应用层协议,由哥伦比亚大学.网景和RealNetw ...

  7. 芝麻HTTP:Scrapy-Splash的安装

    Scrapy-Splash是一个Scrapy中支持JavaScript渲染的工具,本节来介绍它的安装方式. Scrapy-Splash的安装分为两部分.一个是Splash服务的安装,具体是通过Dock ...

  8. ThreadLocal原理

    ThreadLocal类可以看作是当前线程的一个局部变量,只有当前线程可以访问,因此是线程安全的. ThreadLocal内部维护了一个ThreadLocalMap类,ThreadLocalMap是一 ...

  9. Css Secret 案例全套

    Css Secret 案例全套 github地址 案例地址 该书揭示了 47 个鲜为人知的 CSS 技巧,主要内容包括背景与边框.形状. 视觉效果.字体排印.用户体验.结构与布局.过渡与动画等.去年买 ...

  10. NOIp2017 滚粗记

    NOIp2017 滚粗记 Day0 早上 早自习的时候,班主任忽然告诉我们, 我们要参加期中考试... 这对于我们真是一个沉重的打击... 但是,管不着了 明天就死去考试了 上午 \(8:10\)到了 ...