using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Rhea.Common;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using System.IO;
using ICSharpCode.SharpZipLib.Zip;
using Tiger.IBusiness;
namespace Tiger.Api.Controllers.Base
{
///
/// Api自动更新服务
///
[Route("api/[controller]/[action]")]
[EnableCors("Any")]
[ApiController]
public partial class UpgradeController : ControllerBase
{
///
/// 获取文件列表
///
///
///
[HttpGet]
public async Task GetFileListAsync(string? path)
{
var filePath = UpgradeFileSystem.UpgradeRootPath + path;
var allFiles = new List();
await Task.Run(() =>
{
if (Directory.Exists(filePath))
{
allFiles = new UpgradeFileSystem(new DirectoryInfo(filePath)).ChildNodes;
}
else if (System.IO.File.Exists(filePath))
{
allFiles.Add(new UpgradeFileSystem(new FileInfo(filePath)));
}
});
return Ok(allFiles);
}
///
/// 获取文件
///
///
///
[HttpGet]
public async Task GetFileAsync(string? path)
{
var filePath = UpgradeFileSystem.UpgradeRootPath + path;
if (System.IO.File.Exists(filePath))
{
return await GetFileStreamResultAsync(new FileInfo(filePath));
//return await SegmentDownloadFileAsync(new FileInfo(filePath));
}
return Ok(null);
}
///
/// 获取..\AutoUpgrade.exe
///
///
///
[HttpGet]
public async Task GetAutoUpgradeProgramAsync()
{
var filePath = UpgradeFileSystem.UpgradeRootPath + "AutoUpgrade.exe";
if (System.IO.File.Exists(filePath))
{
return await GetFileStreamResultAsync(new FileInfo(filePath));
}
return Ok($"请先把AutoUpgrade.exe放到更新目录的[{UpgradeFileSystem.UpgradeRootPath}]根目录下");
}
///
/// 获取..\AutoUpgrade.exe.config
///
///
///
[HttpGet]
public async Task GetAutoUpgradeConfigAsync()
{
var filePath = UpgradeFileSystem.UpgradeRootPath + "AutoUpgrade.exe.config";
if (System.IO.File.Exists(filePath))
{
return await GetFileStreamResultAsync(new FileInfo(filePath));
}
return Ok($"请先把AutoUpgrade.exe.config放到更新目录的[{UpgradeFileSystem.UpgradeRootPath}]根目录下");
}
///
/// 上传文件
///
///
///
///
[HttpPost]
public JsonResult UploadFile([FromForm] string fileName, [FromForm] string filePath)
{
var files = Request.Form.Files;
var msgResult = new List();
if (files.Count > 0)
{
foreach (var formFile in files)
{
var fullPath = $"{filePath}\\{fileName}";
//save
using var stream = new FileStream(fullPath, FileMode.Create);
formFile.CopyTo(stream);
stream.Close();
stream.Dispose();
//unzip
var unZipDir = fullPath.Replace(Path.GetFileName(fullPath), "").Trim('\\');
//System.IO.Compression.ZipFile.ExtractToDirectory(fullPath, unZipDir);
var isOK = UnZip(fullPath, unZipDir);
//delete compress package
System.IO.File.Delete(fullPath);
msgResult.Add($"【{fileName}】上传成功,{(isOK ? "解压成功" : "解压失败")}");
}
}
return new JsonResult(msgResult);
}
#region Function
///
/// 获取到文件流结果
///
/// FileInfo文件
/// 返回FileStreamResult
private async Task GetFileStreamResultAsync(FileInfo fileInfo)
{
if (fileInfo == null) return NotFound();
var memoryStream = new MemoryStream();
using (var stream = new FileStream(fileInfo.FullName, FileMode.Open))
{
await stream.CopyToAsync(memoryStream);
}
memoryStream.Seek(0, SeekOrigin.Begin);
//文件名必须编码,否则会有特殊字符(如中文)无法在此下载。
string encodeFilename = System.Net.WebUtility.UrlEncode(fileInfo.Name);
Response.Headers.Add("Content-Disposition", "attachment; filename=" + encodeFilename);
return new FileStreamResult(memoryStream, "application/octet-stream");//文件流方式,指定文件流对应的ContenType。
}
///
/// 获取到文件流结果
///
/// FileInfo文件
/// 返回FileStreamResult
private IActionResult GetFileStreamResult(FileInfo fileInfo)
{
if (fileInfo == null) return NotFound();
var memoryStream = new MemoryStream();
using (var stream = new FileStream(fileInfo.FullName, FileMode.Open))
{
stream.CopyTo(memoryStream);
}
memoryStream.Seek(0, SeekOrigin.Begin);
//文件名必须编码,否则会有特殊字符(如中文)无法在此下载。
string encodeFilename = System.Net.WebUtility.UrlEncode(fileInfo.Name);
Response.Headers.Add("Content-Disposition", "attachment; filename=" + encodeFilename);
return new FileStreamResult(memoryStream, "application/octet-stream");//文件流方式,指定文件流对应的ContenType。
}
///
/// 异步分段下载数据
///
/// FileInfo文件
/// 返回响应结果
private async Task SegmentDownloadFileAsync(FileInfo fileInfo)
{
if (fileInfo == null) return NotFound();
int index = 0;
using (FileStream fs = new FileStream(fileInfo.FullName, FileMode.Open))
{
if (fs.Length <= 0)
{
return Ok(new { code = -1, msg = "文件尚未处理" });
}
int shardSize = 1 * 1024 * 1024;//一次1M
int count = (int)(fs.Length / shardSize);
if ((fs.Length % shardSize) > 0)
{
count += 1;
}
if (index > count - 1)
{
return Ok(new { code = -1, msg = "无效的下标" });
}
fs.Seek(index * shardSize, SeekOrigin.Begin);
if (index == count - 1)
{
//最后一片 = 总长 - (每次片段大小 * 已下载片段个数)
shardSize = (int)(fs.Length - (shardSize * index));
}
byte[] datas = new byte[shardSize];
await fs.ReadAsync(datas.AsMemory(0, datas.Length));
return File(datas, "application/octet-stream");
}
}
///
/// 分段下载数据
///
/// FileInfo文件
/// 返回响应结果
private IActionResult SegmentDownloadFile(FileInfo fileInfo)
{
if (fileInfo == null) return NotFound();
int index = 0;
using (FileStream fs = new FileStream(fileInfo.FullName, FileMode.Open))
{
if (fs.Length <= 0)
{
return Ok(new { code = -1, msg = "文件尚未处理" });
}
int shardSize = 1 * 1024 * 1024;//一次1M
int count = (int)(fs.Length / shardSize);
if ((fs.Length % shardSize) > 0)
{
count += 1;
}
if (index > count - 1)
{
return Ok(new { code = -1, msg = "无效的下标" });
}
fs.Seek(index * shardSize, SeekOrigin.Begin);
if (index == count - 1)
{
//最后一片 = 总长 - (每次片段大小 * 已下载片段个数)
shardSize = (int)(fs.Length - (shardSize * index));
}
byte[] datas = new byte[shardSize];
fs.Read(datas, 0, datas.Length);
return File(datas, "application/octet-stream");
}
}
///
/// 功能:解压zip格式的文件。
///
/// 压缩文件路径
/// 解压文件存放路径,为空时默认与压缩文件同一级目录下,跟压缩文件同名的文件夹
/// 解压是否成功
private bool UnZip(string zipFilePath, string unZipDir)
{
try
{
if (zipFilePath == string.Empty)
{
throw new Exception("压缩文件不能为空!");
}
if (!System.IO.File.Exists(zipFilePath))
{
throw new FileNotFoundException("压缩文件不存在!");
}
//解压文件夹为空时默认与压缩文件同一级目录下,跟压缩文件同名的文件夹
if (unZipDir == string.Empty)
unZipDir = zipFilePath.Replace(Path.GetFileName(zipFilePath), Path.GetFileNameWithoutExtension(zipFilePath));
if (!unZipDir.EndsWith("/"))
unZipDir += "/";
if (!Directory.Exists(unZipDir))
Directory.CreateDirectory(unZipDir);
using (var s = new ZipInputStream(System.IO.File.OpenRead(zipFilePath)))
{
ZipEntry theEntry;
while ((theEntry = s.GetNextEntry()) != null)
{
string directoryName = Path.GetDirectoryName(theEntry.Name);
string fileName = Path.GetFileName(theEntry.Name);
if (!string.IsNullOrEmpty(directoryName))
{
Directory.CreateDirectory(unZipDir + directoryName);
}
if (directoryName != null && !directoryName.EndsWith("/"))
{
}
if (fileName != string.Empty)
{
using FileStream streamWriter = System.IO.File.Create(unZipDir + theEntry.Name);
int size;
byte[] data = new byte[2048];
while (true)
{
size = s.Read(data, 0, data.Length);
if (size > 0)
{
streamWriter.Write(data, 0, size);
}
else
{
break;
}
}
}
}
}
return true;
}
catch (Exception ex)
{
//_logger.LogError(ex, $"解压zip格式的文件失败:{zipFilePath}");
return false;
}
}
#endregion
}//endClass
}