Javxp.Storage
1.0.2
dotnet add package Javxp.Storage --version 1.0.2
NuGet\Install-Package Javxp.Storage -Version 1.0.2
<PackageReference Include="Javxp.Storage" Version="1.0.2" />
<PackageVersion Include="Javxp.Storage" Version="1.0.2" />
<PackageReference Include="Javxp.Storage" />
paket add Javxp.Storage --version 1.0.2
#r "nuget: Javxp.Storage, 1.0.2"
#:package Javxp.Storage@1.0.2
#addin nuget:?package=Javxp.Storage&version=1.0.2
#tool nuget:?package=Javxp.Storage&version=1.0.2
Javxp.Storage
面向 .NET 10 的本地磁盘和阿里云 OSS 存储库。普通保存和 OSS 保存统一返回 Task<SaveResponse>;OSS Multipart 对外保留初始化、上传和取消三个操作。
安装与注册
dotnet add package Javxp.Storage
using Javxp.Storage;
builder.Services.JavxpStorage();
也可以直接实例化:
IStorageService storage = new StorageService();
运行环境为 .NET 10,主要依赖 Aliyun.OSS.SDK.NetCore 2.14.1 和 Microsoft.Extensions.DependencyInjection.Abstractions 10.0.12。
SaveResponse
public sealed class SaveResponse
{
public bool Success { get; set; }
public string Message { get; set; }
public string FileName { get; set; }
}
Success 表示操作是否完成;Message 保存成功消息或错误信息;FileName 在本地操作中是完整文件路径,在 OSS 操作中是对象 URL。
本地保存
父目录会自动创建,目标文件默认覆盖。调用方传入的 Stream 不会由库关闭。
SaveResponse bytesResult = await storage.SaveAsync(bytes, @"D:\Storage\data.bin");
await using Stream input = File.OpenRead(@"D:\Input\archive.zip");
SaveResponse streamResult = await storage.SaveAsync(input, @"D:\Storage\archive.zip");
SaveResponse urlResult = await storage.SaveAsync(
"https://example.com/files/photo.jpg",
@"D:\Storage\photo.jpg");
Task<SaveResponse> SaveAsync(byte[] data, string filePath, CancellationToken cancellationToken = default);
Task<SaveResponse> SaveAsync(Stream stream, string filePath, CancellationToken cancellationToken = default);
Task<SaveResponse> SaveAsync(string url, string filePath, CancellationToken cancellationToken = default);
另外提供以下输入重载,它们会先转换为 byte[],再调用 byte[] 核心保存方法:
SaveAsync(FileInfo file, string filePath, ...);
SaveAsync(ReadOnlyMemory<byte> data, string filePath, ...);
SaveAsync(ReadOnlySequence<byte> data, string filePath, ...);
SaveAsync(HttpContent content, string filePath, ...);
SaveAsync(PipeReader reader, string filePath, ...);
SaveAsync(IAsyncEnumerable<ReadOnlyMemory<byte>> chunks, string filePath, ...);
SaveAsync(TextReader reader, string filePath, Encoding? encoding = null, ...);
OSS 同样提供这些输入类型的重载。文本输入默认使用 UTF-8,也可以显式传入其他 Encoding。
这些重载会把完整内容加载到内存。大文件不建议使用它们,应使用 Multipart 流式上传。
OSS 普通上传
AliyunOssOptions 只保存连接和 Bucket 信息;ObjectName 由每次上传调用单独传入,因此同一配置可以复用到多个对象。
var options = new AliyunOssOptions(
endpoint: "oss-cn-shenzhen.aliyuncs.com",
accessKeyId: accessKeyId,
accessKeySecret: accessKeySecret,
bucketName: "platform-yjlglobal-cn");
SaveResponse response = await storage.SaveAliyunOssAsync(
bytes,
options,
objectName: $"{Guid.NewGuid():N}.pdf");
也可以使用对象初始化器:
var options = new AliyunOssOptions
{
Endpoint = "oss-cn-shenzhen.aliyuncs.com",
AccessKeyId = accessKeyId,
AccessKeySecret = accessKeySecret,
BucketName = "platform-yjlglobal-cn"
};
签名:
Task<SaveResponse> SaveAliyunOssAsync(byte[] data, AliyunOssOptions options, string objectName, CancellationToken cancellationToken = default);
Task<SaveResponse> SaveAliyunOssAsync(Stream stream, AliyunOssOptions options, string objectName, CancellationToken cancellationToken = default);
Task<SaveResponse> SaveAliyunOssAsync(string url, AliyunOssOptions options, string objectName, CancellationToken cancellationToken = default);
EndPoint 是 Endpoint 的兼容别名,Bucket 是 BucketName 的兼容别名。普通 OSS 上传使用 SDK 默认签名方式,不需要 region 参数,同名对象默认覆盖。
Multipart 上传
初始化
Multipart 的对象名在初始化时单独传入,并由 MultipartUploadConfig 保存上传状态:
MultipartUploadConfig config = await storage.MultipartUpload_InitiateAsync(
options,
objectName: "videos/large.mp4",
region: "cn-shenzhen");
if (!config.Success)
{
Console.WriteLine(config.Message);
return;
}
一步完成上传
await using Stream file = File.OpenRead(@"D:\Input\large.mp4");
SaveResponse result = await storage.MultipartUploadAsync(file, config);
对于本地文件,也可以直接使用专用方法。它会以只读异步文件流打开文件,不会把整个文件一次性加载到内存:
SaveResponse result = await storage.MultipartUpload_LocalFileAsync(
@"D:\Input\large.mp4",
config,
cancellationToken: cancellationToken);
本地文件上传会按 config.MaxConcurrency 并发上传分片,默认值为处理器数量的两倍;可以根据网络和 OSS 限流情况调整:
config.MaxConcurrency = 8;
每个分片都会独立打开本地文件并定位读取,上传过程会使用 OSS SDK 的传输进度事件持续报告进度。
MultipartUploadAsync 也支持 byte[] 和 URL 重载。内部会自动查询已有分片、上传剩余分片并完成合并。
暂停和恢复
MultipartUploadConfig.Stop 对应旧版 oss_v2.cs 的暂停标志。上传过程中由其他线程设置:
config.Stop = true;
当前分片完成后上传会返回暂停结果,并保留 UploadId 和已上传分片。恢复时使用同一个配置对象,将标志改回 false,再次调用同一个 MultipartUploadAsync:
config.Stop = false;
await using Stream resumedFile = File.OpenRead(@"D:\Input\large.mp4");
SaveResponse resumeResult = await storage.MultipartUploadAsync(resumedFile, config);
取消
SaveResponse abortResult = await storage.MultipartUpload_AbortAsync(config);
公开 Multipart 方法:
Task<MultipartUploadConfig> MultipartUpload_InitiateAsync(
AliyunOssOptions options,
string objectName,
string region,
int partSize = 5 * 1024 * 1024,
CancellationToken cancellationToken = default);
Task<SaveResponse> MultipartUploadAsync(
Stream stream,
MultipartUploadConfig config,
IProgress<MultipartUploadProgress>? progress = null,
CancellationToken cancellationToken = default);
Task<SaveResponse> MultipartUpload_LocalFileAsync(
string localFile,
MultipartUploadConfig config,
IProgress<MultipartUploadProgress>? progress = null,
CancellationToken cancellationToken = default);
Task<SaveResponse> MultipartUpload_AbortAsync(
MultipartUploadConfig config,
CancellationToken cancellationToken = default);
默认分片大小为 5 MB,初始化时不能小于 100 KB,最后一个分片可以小于 100 KB。
安全说明
- 不要把
AccessKeySecret写入日志或提交到代码仓库。 AliyunOssOptions不保存对象名,连接配置可以复用,但凭证仍应妥善保护。AliyunOssOptions.ToString()已脱敏。- 私有 Bucket 返回的 OSS URL 只表示对象位置,不保证匿名访问。
构建
dotnet build Javxp.Storage.csproj -c Release
当前 OSS SDK 的核心操作主要是同步 API,库内部使用异步包装执行;本地文件和 HTTP 下载使用原生异步 API。
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Aliyun.OSS.SDK.NetCore (>= 2.14.1)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.12)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.