.NET C#通过SFTP读取Zip文件报错:Central Directory损坏
使用SSH.NET读取SFTP中Zip文件时出现“Central Directory corrupt”异常的解决思路
问题描述
通过SSH.NET访问SFTP文件夹,读取其中Zip文件内容时抛出异常:
System.IO.InvalidDataException: 'Central Directory corrupt'
内部异常:EndOfStreamException: Unable to read beyond the end of the stream
相关代码
public string GetContents(string filename, ref string error) { string contents = ""; using (var sftp = new SftpClient(SFTP_URI, SFTP_USERNAME, SFTP_PASSWORD)) { try { sftp.Connect(); } catch (Exception exc) { error = "Unable to connect " + SFTP_USERNAME + "@" + SFTP_URI + " - " + exc.Message; return contents; } if (!sftp.Exists(filename)) { error = "Filename doesn't exist - " + filename; return contents; } using (Stream stream = sftp.OpenRead(filename)) { using (var archive = new ZipArchive(stream, ZipArchiveMode.Read, true)) // 异常抛出位置 { foreach (var files in archive.Entries) // 测试用代码,尝试访问Zip内容 { Console.WriteLine(files); } } } } return contents; }
原因分析及解决步骤
- Zip文件本身损坏:手动通过SFTP客户端下载该Zip文件,本地尝试解压验证。如果本地解压也报错,说明文件在服务器端已损坏,需重新上传。
- 远程流不支持随机访问:
SftpClient.OpenRead返回的远程流不支持查找操作(CanSeek为false),但ZipArchive需要随机读取Zip的目录结构。解决方式是先将远程流复制到内存流或本地临时文件,再读取:
修改后的核心代码:using (Stream stream = sftp.OpenRead(filename)) { using (var memoryStream = new MemoryStream()) { stream.CopyTo(memoryStream); memoryStream.Position = 0; // 重置流位置到起始处 using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Read, true)) { foreach (var entry in archive.Entries) { Console.WriteLine(entry.FullName); } } } } - SSH.NET版本过旧:检查当前使用的SSH.NET版本,更新到最新稳定版,旧版本可能存在流处理的bug。
- 文件权限不足:确认SFTP用户对目标Zip文件拥有完整的读取权限,权限不足可能导致读取到不完整的数据流。
内容的提问来源于stack exchange,提问作者Saif
相关产品推荐
相关产品推荐

