[英]List files inside ZIP file located on SFTP server in C#
我需要通過 ASP.NET Core 以編程方式處理來自 SFTP 服務器 (WinSCP) 的 ZIP 文件中的文件夾。
有什么方法可以在不下載到本地計算機的情況下獲取 ZIP 文件中的文件列表? 由於文件大小會很大並且不會以一致的方式。 任何幫助,將不勝感激。
使用SSH.NET 庫,它可以很簡單:
using (var client = new SftpClient(host, username, password)
{
client.Connect();
using (Stream stream = client.OpenRead("/remote/path/archive.zip"))
using (var archive = new ZipArchive(stream, ZipArchiveMode.Read))
{
foreach (var entry in archive.Entries)
{
Console.WriteLine(entry);
}
}
}
您需要引用System.IO.Compression
程序集來獲取ZipArchive
。
該代碼只會讀取(下載)ZIP 中央目錄記錄,而不是整個 ZIP 檔案。 有關證明,請參閱答案的末尾。
不幸的是,庫中有一個錯誤。 要解決它,您必須像這樣實現包裝器Stream
實現:
class FixStream : Stream
{
public override long Seek(long offset, SeekOrigin origin)
{
long result;
// workaround for SSH.NET bug in implementation of SeekOrigin.End
if (origin == SeekOrigin.End)
{
result = _stream.Seek(Length + offset, SeekOrigin.Begin);
}
else
{
result = _stream.Seek(offset, origin);
}
return result;
}
// passthrough implementation of the rest of Stream interface
public override bool CanRead => _stream.CanRead;
public override bool CanSeek => _stream.CanSeek;
public override bool CanWrite => _stream.CanWrite;
public override long Length => _stream.Length;
public override long Position {
get => _stream.Position; set => _stream.Position = value; }
public FixStream(Stream stream)
{
_stream = stream;
}
public override void Flush()
{
_stream.Flush();
}
public override int Read(byte[] buffer, int offset, int count)
{
return _stream.Read(buffer, offset, count);
}
public override void SetLength(long value)
{
_stream.SetLength(value);
}
public override void Write(byte[] buffer, int offset, int count)
{
_stream.Write(buffer, offset, count);
}
private Stream _stream;
}
並將SftpFileStream
包裝到它:
using (Stream stream = client.OpenRead("/remote/path/archive.zip"))
using (var stream2 = new FixStream(stream))
using (var archive = new ZipArchive(stream2, ZipArchiveMode.Read))
{
...
}
作為它確實有效的證明,我已將日志記錄添加到FixStream
的所有方法。 當使用帶有兩個條目的 18 MB(18265315 字節)ZIP 存檔的代碼時,生成了以下內容。 所以從 stream 中只讀取了 244 個字節。實際上更多的是從實際的遠程 SFTP 文件中讀取,因為 SSH.NET 緩沖讀取(否則代碼將非常無效,特別是在這種情況下,正如您所看到的ZipArchive
做很多小讀)。 默認的 SSH.NET 緩沖區是 32 KB ( SftpClient.BufferSize
)。
Tried to seek to -18 from End => converting to seek to 18265297 from Begin
Seeked to 18265297 from Begin => 18265297
Seeked to -32 from Current => 18265265
Tried to read 32, got 32
Seeked to -32 from Current => 18265265
Seeked to 28 from Current => 18265293
Tried to read 4, got 4
Tried to read 2, got 2
Tried to read 2, got 2
Tried to read 2, got 2
Tried to read 2, got 2
Tried to read 4, got 4
Tried to read 4, got 4
Tried to read 2, got 2
Seeked to 18265075 from Begin => 18265075
Tried to read 4, got 4
Tried to read 1, got 1
Tried to read 1, got 1
Tried to read 2, got 2
Tried to read 2, got 2
Tried to read 2, got 2
Tried to read 4, got 4
Tried to read 4, got 4
Tried to read 4, got 4
Tried to read 4, got 4
Tried to read 2, got 2
Tried to read 2, got 2
Tried to read 2, got 2
Tried to read 2, got 2
Tried to read 2, got 2
Tried to read 4, got 4
Tried to read 4, got 4
Tried to read 28, got 28
Tried to read 2, got 2
Tried to read 2, got 2
Tried to read 32, got 32
Set position to 18265185
Tried to read 4, got 4
Tried to read 1, got 1
Tried to read 1, got 1
Tried to read 2, got 2
Tried to read 2, got 2
Tried to read 2, got 2
Tried to read 4, got 4
Tried to read 4, got 4
Tried to read 4, got 4
Tried to read 4, got 4
Tried to read 2, got 2
Tried to read 2, got 2
Tried to read 2, got 2
Tried to read 2, got 2
Tried to read 2, got 2
Tried to read 4, got 4
Tried to read 4, got 4
Tried to read 26, got 26
Tried to read 2, got 2
Tried to read 2, got 2
Tried to read 32, got 32
Set position to 18265293
Tried to read 4, got 4
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.