Spring Boot 对上传文件进行解压缩
起因
在上一篇文章中,简单上手了Spring Boot并进行数据返回,和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);
}
}
}
}
使用:
using (HttpClient client = new HttpClient())
{
string path = Path.Combine(Environment.CurrentDirectory, "vs2019-cpu.png");
var httpContent = new CompressedContent(new ByteArrayContent(File.ReadAllBytes(path)), CompressionMethod.GZip);
httpContent.Headers.Add("fileName", "vs2019-cpu.png");
var requestUri = "http://myabcde.com:8080/uploadFile";
var result = client.PostAsync(requestUri, httpContent).Result.Content.ReadAsStringAsync().Result;
Console.WriteLine(result);
}
服务端 Java代码实现
@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版本).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();
}
}
}
}
}
这里只是简单实现,并没考虑多文件上传,不过看了一下,对文件压缩上传,压缩比例不是很高.
秋风
2020-01-05