起因
因为公司项目重做,接口服务改为Java(Web API),所以WCF服务中实现的功能,要在Java中实现,C#客户端进行数据交互.今天主要是在C#客户端上传文件的时候进行压缩,在服务端解压缩之后,将文件进行保存.
C# 进行Gzip压缩上传
这里主要使用博客园基于HttpContent实现CompressedContent.
public enum CompressionMethod
{
GZip = 1,
Deflate = 2
}
public class CompressedContent : HttpContent
{
private readonly HttpContent _originalContent;
private readonly CompressionMethod _compressionMethod;
public CompressedContent(HttpContent content, CompressionMethod compressionMethod)
{
if (content == null)
{
throw new ArgumentNullException("content");
}
_originalContent = content;
_compressionMethod = compressionMethod;
foreach (KeyValuePair<string, IEnumerable<string>> header in _originalContent.Headers)
{
Headers.TryAddWithoutValidation(header.Key, header.Value);
}
Headers.ContentEncoding.Add(_compressionMethod.ToString().ToLowerInvariant());
}
protected override bool TryComputeLength(out long length)
{
length = -1;
return false;
}
protected async override Task SerializeToStreamAsync(Stream stream, TransportContext context)
{
if (_compressionMethod == CompressionMethod.GZip)
{
using (var gzipStream = new GZipStream(stream, CompressionMode.Compress, true))
{
await _originalContent.CopyToAsync(gzipStream);
}
}
else if (_compressionMethod == CompressionMethod.Deflate)
{
using (var deflateStream = new DeflateStream(stream, CompressionMode.Compress, true))
{
await _originalContent.CopyToAsync(deflateStream);
}
}
}
}
服务端 Java代码解压Gzip文件
@RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
public String gzipFile(HttpServletRequest request) throws IOException {
String contentEncoding = request.getHeader("Content-Encoding");
if (contentEncoding != null && contentEncoding.indexOf("gzip") > -1) {
String fileName = request.getHeader("fileName");
if (fileName != null && fileName != "") {
fileName = "e:/blog/" + fileName; //保存文件路径,这样写很不正规,这里只是方便
ServletInputStream inputStream = request.getInputStream();
final GZIPInputStream gzipInputStream = new GZIPInputStream(inputStream);
final int blockSize = 8192;
byte[] buffer = new byte[blockSize];
FileOutputStream outputStream = new FileOutputStream(fileName);
int len;
while ((len = gzipInputStream.read(buffer, 0, blockSize)) != -1) {
outputStream.write(buffer, 0, len);
}
gzipInputStream.close();
outputStream.close();
return "upload ok";
} else {
return "fileName is null";
}
}
return "ok";
}
服务端 Owin(C#)实现代码
这里宿主是使用TinyFox(dll版本).这里要说一下Owin,老项目不想迁移到.Net Core和.Net 5/6中,又需要性能好且轻量.将一部分模块基于Owin的实现.
private void DecompressStream(IDictionary<string, object> env)
{
//获取所有请求头
var reqHeaders = env["owin.RequestHeaders"] as IDictionary<string, string[]>;
//获取请求正文
var reqStream = env["owin.RequestBody"] as Stream;
if (reqStream != null)
{
//获取文件名
string fileName = reqHeaders["fileName"] != null ? reqHeaders["fileName"][0] : "123.png";
using (var stream = new MemoryStream())
{
//进行解压缩
using (var gzipStream = new GZipStream(reqStream, CompressionMode.Decompress))
{
gzipStream.CopyTo(stream);
stream.Seek(0, SeekOrigin.Begin);
byte[] buffer = new byte[stream.Length];
stream.Read(buffer, 0, (int)stream.Length);
using (FileStream fileStream = new FileStream(fileName, FileMode.OpenOrCreate))
{
fileStream.Write(buffer, 0, buffer.Length);
fileStream.Flush();
}
}
}
}
}
如果您觉得对您有用的话,可以点个赞或者加个关注,欢迎大家一起进行技术交流