使用WinSCP流保存到Azure Blob Storage报错:不支持非零偏移量
解决WinSCP流上传Azure Blob报错“Offsets with value of non-zero are not supported”
问题原因
WinSCP的Session.GetFile()返回的是**非可寻位(CanSeek = false)**的网络流,而Azure Blob的UploadAsync方法默认会尝试检查流的Position属性,当流不支持寻位或Position不为0时,就会触发该错误。而CopyTo写入磁盘的操作不需要依赖流的寻位能力,因此可以正常执行。
解决方案
提供两种实用解决方式,可根据文件大小选择:
方式1:转存到内存流后上传(适合小文件)
将远程文件流复制到支持寻位的内存流中,重置流位置后再上传:
using WinSCP; using Azure.Storage.Blobs; // 推荐使用新版Azure SDK,替代已过时的Microsoft.Azure.Storage.Blob BlobServiceClient blobServiceClient = new BlobServiceClient(_connectionString); BlobContainerClient blobContainerClient = blobServiceClient.GetBlobContainerClient(containername); BlobClient blobClient = blobContainerClient.GetBlobClient(filename); using (Session session = new Session()) { session.Open(sessionOptions); string remotePath = "/myfile.zip"; using (Stream remoteStream = session.GetFile(remotePath, transferOptions)) using (MemoryStream memoryStream = new MemoryStream()) { await remoteStream.CopyToAsync(memoryStream); memoryStream.Position = 0; // 重置流到起始位置 await blobClient.UploadAsync(memoryStream, new BlobHttpHeaders { ContentType = "application/zip" }); } }
注意:大文件使用此方式会占用较多内存,不推荐。
方式2:使用新版SDK的重载直接上传(适合大文件)
升级到Azure.Storage.Blobs新版SDK后,使用BlobUploadOptions配置上传参数,SDK会自动处理非可寻位流的上传逻辑:
using WinSCP; using Azure.Storage.Blobs; using Azure.Storage.Blobs.Models; BlobServiceClient blobServiceClient = new BlobServiceClient(_connectionString); BlobContainerClient blobContainerClient = blobServiceClient.GetBlobContainerClient(containername); BlobClient blobClient = blobContainerClient.GetBlobClient(filename); using (Session session = new Session()) { session.Open(sessionOptions); string remotePath = "/myfile.zip"; using (Stream remoteStream = session.GetFile(remotePath, transferOptions)) { var uploadOptions = new BlobUploadOptions { HttpHeaders = new BlobHttpHeaders { ContentType = "application/zip" } }; await blobClient.UploadAsync(remoteStream, uploadOptions); } }
额外提示
- 若仍需使用旧版
Microsoft.Azure.Storage.Blob,可参考方式1的逻辑,将流转存到可寻位流后再上传。 - 超大文件场景下,可考虑先将文件下载到本地临时路径,再读取本地文件流上传到Blob,避免内存溢出。
内容的提问来源于stack exchange,提问作者laney
相关产品推荐
相关产品推荐

