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
|
{
|
/// <summary>
|
/// Api自动更新服务
|
/// </summary>
|
[Route("api/[controller]/[action]")]
|
[EnableCors("Any")]
|
[ApiController]
|
public partial class UpgradeController : ControllerBase
|
{
|
/// <summary>
|
/// 获取文件列表
|
/// </summary>
|
/// <param name="path"></param>
|
/// <returns></returns>
|
[HttpGet]
|
public async Task<IActionResult> GetFileListAsync(string? path)
|
{
|
var filePath = UpgradeFileSystem.UpgradeRootPath + path;
|
var allFiles = new List<UpgradeFileSystem>();
|
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);
|
}
|
|
/// <summary>
|
/// 获取文件
|
/// </summary>
|
/// <param name="path"></param>
|
/// <returns></returns>
|
[HttpGet]
|
public async Task<IActionResult> 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);
|
}
|
|
/// <summary>
|
/// 获取..\AutoUpgrade.exe
|
/// </summary>
|
/// <param name="path"></param>
|
/// <returns></returns>
|
[HttpGet]
|
public async Task<IActionResult> 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}]根目录下");
|
}
|
|
/// <summary>
|
/// 获取..\AutoUpgrade.exe.config
|
/// </summary>
|
/// <param name="path"></param>
|
/// <returns></returns>
|
[HttpGet]
|
public async Task<IActionResult> 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}]根目录下");
|
}
|
|
/// <summary>
|
/// 上传文件
|
/// </summary>
|
/// <param name="fileName"></param>
|
/// <param name="filePath"></param>
|
/// <returns></returns>
|
[HttpPost]
|
public JsonResult UploadFile([FromForm] string fileName, [FromForm] string filePath)
|
{
|
var files = Request.Form.Files;
|
var msgResult = new List<string>();
|
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
|
/// <summary>
|
/// 获取到文件流结果
|
/// </summary>
|
/// <param name="fileInfo">FileInfo文件</param>
|
/// <returns>返回FileStreamResult</returns>
|
private async Task<IActionResult> 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。
|
}
|
|
/// <summary>
|
/// 获取到文件流结果
|
/// </summary>
|
/// <param name="fileInfo">FileInfo文件</param>
|
/// <returns>返回FileStreamResult</returns>
|
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。
|
}
|
|
/// <summary>
|
/// 异步分段下载数据
|
/// </summary>
|
/// <param name="fileInfo">FileInfo文件</param>
|
/// <returns>返回响应结果</returns>
|
private async Task<IActionResult> 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");
|
}
|
}
|
|
/// <summary>
|
/// 分段下载数据
|
/// </summary>
|
/// <param name="fileInfo">FileInfo文件</param>
|
/// <returns>返回响应结果</returns>
|
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");
|
}
|
}
|
/// <summary>
|
/// 功能:解压zip格式的文件。
|
/// </summary>
|
/// <param name="zipFilePath">压缩文件路径</param>
|
/// <param name="unZipDir">解压文件存放路径,为空时默认与压缩文件同一级目录下,跟压缩文件同名的文件夹</param>
|
/// <returns>解压是否成功</returns>
|
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
|
|
}
|