85 lines
2.5 KiB
C#
85 lines
2.5 KiB
C#
using MAX.Plugins;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using MAX.Core.DependencyInjection;
|
|
using Microsoft.Extensions.Configuration;
|
|
using System.IO.Compression;
|
|
using System.Text;
|
|
|
|
namespace Store.Modules.CloudProduct.Services
|
|
{
|
|
/// <summary>
|
|
/// 商品原始数据文件存储:按 goodsId % 100 分目录,文件名即商品ID,GZip 压缩保存。
|
|
/// </summary>
|
|
public interface IRawDataStorage : IScopedDependency
|
|
{
|
|
/// <summary>
|
|
/// 保存原始数据,返回保存后的完整路径。
|
|
/// </summary>
|
|
Task<string> SaveAsync(long goodsId, string rawData);
|
|
|
|
/// <summary>
|
|
/// 读取并解压原始数据;文件不存在时返回 null。
|
|
/// </summary>
|
|
Task<string?> ReadAsync(long goodsId);
|
|
|
|
/// <summary>
|
|
/// 判断指定商品的原始数据文件是否存在。
|
|
/// </summary>
|
|
bool Exists(long goodsId);
|
|
}
|
|
|
|
internal class RawDataStorage : IRawDataStorage
|
|
{
|
|
private readonly string _rootPath;
|
|
|
|
public RawDataStorage([FromKeyedServices("CloudProduct")] PluginContext context)
|
|
{
|
|
var configured = context.Configuration.GetValue<string>("RawData:Path");
|
|
if (string.IsNullOrWhiteSpace(configured))
|
|
configured = "RawData";
|
|
|
|
_rootPath = Path.GetFullPath(configured, context.DirectoryPath);
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public async Task<string> SaveAsync(long goodsId, string rawData)
|
|
{
|
|
var filePath = GetFilePath(goodsId);
|
|
var dir = Path.GetDirectoryName(filePath)!;
|
|
Directory.CreateDirectory(dir);
|
|
|
|
await using var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None);
|
|
await using var gzip = new GZipStream(fileStream, CompressionLevel.Fastest);
|
|
await using var writer = new StreamWriter(gzip, new UTF8Encoding(false));
|
|
await writer.WriteAsync(rawData);
|
|
|
|
return filePath;
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public async Task<string?> ReadAsync(long goodsId)
|
|
{
|
|
var filePath = GetFilePath(goodsId);
|
|
if (!File.Exists(filePath))
|
|
return null;
|
|
|
|
await using var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
|
|
await using var gzip = new GZipStream(fileStream, CompressionMode.Decompress);
|
|
using var reader = new StreamReader(gzip, new UTF8Encoding(false));
|
|
return await reader.ReadToEndAsync();
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public bool Exists(long goodsId)
|
|
{
|
|
return File.Exists(GetFilePath(goodsId));
|
|
}
|
|
|
|
private string GetFilePath(long goodsId)
|
|
{
|
|
var subDir = (goodsId % 100).ToString();
|
|
return Path.Combine(_rootPath, subDir, goodsId.ToString());
|
|
}
|
|
}
|
|
}
|