在 C# 中列出位于 SFTP 服务器上的 ZIP 文件内的文件

2023-12-02

我需要通过 ASP.NET Core 以编程方式处理来自 SFTP 服务器 (WinSCP) 的 ZIP 文件内的文件夹。

有什么方法可以获取 ZIP 文件中的文件列表而无需下载到本地计算机吗?作为 文件大小会很大并且不会保持一致。任何帮助,将不胜感激。


With 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 to it:

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 存档的代码时,会生成以下内容。因此仅从流中读取了 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
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 C# 中列出位于 SFTP 服务器上的 ZIP 文件内的文件 的相关文章

  • 如何在 C# 中从 UNIX 纪元时间转换并考虑夏令时?

    我有一个从 unix 纪元时间转换为 NET DateTime 值的函数 public static DateTime FromUnixEpochTime double unixTime DateTime d new DateTime 19
  • 如何从 .resx 文件条目获取注释

    资源文件中的字符串有名称 值和注释 The ResXResourceReader类让我可以访问名称和值 有办法看评论吗 你应该能够得到Comment via ResXDataNode class http msdn microsoft co
  • 如何访问另一个窗体上的ListView控件

    当单击与 ListView 所在表单不同的表单中的按钮时 我试图填充 ListView 我在 Form1 中创建了一个方法以在 Form2 中使用 并将参数传递给 Form1 中的方法 然后填充 ListView 当我调试时 我得到了传递的
  • 无法在 Windows 运行时组件库的 UserControl 中创建依赖项属性

    我想在用户控件内创建数据可绑定属性 这个用户控件包含一个 Windows 运行时组件 项目 我使用下面的代码来创建属性 public MyItem CurrentItem get return MyItem GetValue Current
  • 获取 WPF 控件的所有附加事件处理程序

    我正在开发一个应用程序 在其中动态分配按钮的事件 现在的问题是 我希望获取按钮单击事件的所有事件 因为我希望删除以前的处理程序 我尝试将事件处理程序设置为 null 如下所示 Button Click null 但是我收到了一个无法分配 n
  • 未经许可更改内存值

    我有一个二维数组 当我第一次打印数组的数据时 日期打印正确 但其他时候 array last i 的数据从 i 0 到 last 1 显然是一个逻辑错误 但我不明白原因 因为我复制并粘贴了 for 语句 那么 C 更改数据吗 I use g
  • 在一个字节中存储 4 个不同的值

    我有一个任务要做 但我不知道从哪里开始 我不期待也绝对不想要代码中的答案 我想要一些关于该怎么做的指导 因为我感到有点失落 将变量打包和解包到一个字节中 您需要在一个字节中存储 4 个不同的值 这些值为 NAME RANGE BITS en
  • 使用 Moq 使用内部构造函数模拟类型

    我正在尝试模拟 Microsoft Sync Framework 中的一个类 它只有一个内部构造函数 当我尝试以下操作时 var fullEnumerationContextMock new Mock
  • 将 log4net 与 Autofac 结合使用

    我正在尝试将 log4net 与 Autofac 一起使用 我粘贴了这段代码http autofac readthedocs org en latest examples log4net html http autofac readthed
  • 等待线程完成

    private void button1 Click object sender EventArgs e for int i 0 i lt 15 i Thread nova new Thread Method nova Start list
  • std::async 与重载函数

    可能的重复 std bind 重载解析 https stackoverflow com questions 4159487 stdbind overload resolution 考虑以下 C 示例 class A public int f
  • Process.Start() 方法在什么情况下返回 false?

    From MSDN https msdn microsoft com en us library e8zac0ca v vs 110 aspx 返回值 true 表示有新的进程资源 开始了 如果由 FileName 成员指定的进程资源 St
  • 编译时“strlen()”有效吗?

    有时需要将字符串的长度与常量进行比较 例如 if line length gt 2 Do something 但我试图避免在代码中使用 魔法 常量 通常我使用这样的代码 if line length gt strlen Do somethi
  • 英特尔 Pin 与 C++14

    问题 我有一些关于在 C 14 或其他 C 版本中使用英特尔 Pin 的问题 使用较新版本从较旧的 C 编译代码很少会出现任何问题 但由于 Intel Pin 是操作指令级别的 如果我使用 C 11 或 C 14 编译它 是否会出现任何不良
  • memset 未填充数组

    u32 iterations 5 u32 ecx u32 malloc sizeof u32 iterations memset ecx 0xBAADF00D sizeof u32 iterations printf 8X n ecx 0
  • 使用 GROUP 和 SUM 的 LINQ 查询

    请帮助我了解如何使用带有 GROUP 和 SUM 的 LINQ 进行查询 Query the database IEnumerable
  • 如何将 Roslyn 语义模型返回的类型符号名称与 Mono.Cecil 返回的类型符号名称相匹配?

    我有以下代码 var paramDeclType m semanticModel GetTypeInfo paramDecl Type Type Where paramDeclType ToString returns System Col
  • 使用 GhostScript.NET 打印 PDF DPI 打印问题

    我在用GhostScript NET http ghostscriptnet codeplex com打印 PDF 当我以 96DPI 打印时 PDF 打印效果很好 但有点模糊 如果我尝试以 600DPI 打印文档 打印的页面会被极大地放大
  • 防止在工厂方法之外实例化对象

    假设我有一个带有工厂方法的类 class A public static A newA Some code logging return new A 是否可以使用 a 来阻止此类对象的实例化new 那么工厂方法是创建对象实例的唯一方法吗 当
  • 在客户端系统中安装后桌面应用程序无法打开

    我目前正在使用 Visual Studio 2017 和 4 6 1 net 框架 我为桌面应用程序创建了安装文件 安装程序在我的系统中完美安装并运行 问题是安装程序在其他计算机上成功安装 但应用程序无法打开 edit 在客户端系统中下载了

随机推荐

  • 如何判断一个字符串是否包含整数?

    假设您有一个字符串 您想要测试它以确保它包含一个整数 然后再继续执行其余代码 在java中 你会用什么来判断它是否是一个整数 如果您想确保它是only一个整数并将其转换为一 我会使用parseInt in a try catch 但是 如果
  • iOS 从一年中的某一天获取日期

    stackoverflow 上的常见问题是如何从日期获取一年中的某一天 但是如何从一年中的某一天获取日期呢 我使用以下代码来生成一年中的某一天 但如何执行相反的操作 Calculate Day of the Year NSCalendar
  • 水平 ListView.builder 上的 RefreshIndicator

    我有一个水平 ListView builder 小部件 我想在将其向左拉时使用 RefreshIndicator 进行刷新 FutureBuilder future initGetTopX builder context wikiSnaps
  • removeAllObjects 和 NSMutableArray 的释放是否具有相同的功能?

    我写了以下代码行 NSMutableArray array NSMutableArray alloc init 这会分配一些内存 我的问题是 我们以后如何释放这块内存 是使用removeAllObjects方法还是 数组释放 这两种方法具有
  • 转换 T-s 时完美转发非 T 参数

    这个问题源自这个答案 我正在尝试调整一个蹦床函数 该函数当前仅传递可变数量的参数 我想让它转换任何参数PyObject pyob to Object pyob 但转发所有其他参数 So void self int PyObject floa
  • 将 WPF ContextMenu MenuItem 绑定到 UserControl 属性与 ViewModel 属性

    我正在努力了解 ContextMenu 发生了什么 我知道它被渲染为一个单独的窗口 具有一个单独的可视化树 因此我们不能使用相对绑定来绑定作为用户控件的属性公开的命令 例如下列does not work
  • Rails 4 按虚拟属性排序

    我有一个Product模型有name and description数据库中的列 我也有一个Product search results for query where query是一个像这样的字符串 Green Apple 我需要返回一个
  • Akka - 对象序列化期间的 StackOverflowError

    我遇到了一个持续超过 2 天的问题 当我在参与者之间交换消息时 正在指责 JVM 堆栈溢出 我的消息是一个具有许多链接的对象 10000 多个子对象在链接列表中链接在一起 即 具有 Neo4J 关系的对象 错误是这样的 java lang
  • JFreeChart - XYLineAndShapeRenderer getItemLineVisible() 不起作用

    我正在使用 DynamicTimeSeriesCollection 模拟虚拟实时数据 例如this 在随机间隔期间 传递到绘图的数据应该 丢失 以模拟网络连接丢失 此时 该图应该停止绘制 并且仅在丢失消退后才开始绘制数据 我子类化了XYLi
  • 数据框从数字变为字符

    我打开 csv 文件并控制每个数据的类别 mydataP lt read csv Energy protein2 csv stringsAsFactors F apply mydataP 2 function i class i 1 num
  • Struts2 - 如何获取 JSP 页面的结果作为操作类中的字符串(用于电子邮件)

    我想同时实现这两件事 我在Struts2中有一个常规的jsp页面 xx yy zz email jsp
  • 设置自定义编码器和处理参数化类型

    我有两个与数据流管道面临的编码器问题相关的问题 如何为我的自定义数据类型设置编码器 该类仅包含三个项目 两个双精度值和另一个参数化属性 我尝试使用 SerializedCoder 注释类型 但最终仍然出现错误 com google clou
  • IronPython DLR;将参数传递给编译的代码?

    我目前正在使用 DLR 执行以下操作来创建并执行简单的 python 计算 ScriptRuntime runtime Python CreateRuntime ScriptEngine engine runtime GetEngine p
  • MySQL-如何显示每个线程的最新主题

    我正在尝试创建 SQL 来检索论坛线程的最新帖子列表 我有以下代码 SELECT item discuss thread id item discuss post title COUNT item discuss thread id AS
  • 在未来的特定时间在iOS中运行后台任务

    有没有办法在 iOS 7 中连接后台任务 例如切换位置服务的使用 以在特定时间点 例如明天早上 运行 而无需用户打开应用程序 或者无需持续运行后台进程 我知道的唯一选择是在所需的时间向设备发送推送通知 但是有人知道有任何纯粹的设备上替代方案
  • 合并两个具有不同列的表mysql

    我想合并两个具有不同列的表mysql 例如 表格1 item id title slug type views updatedAt createdAt 1 sometitle someslg 1 43454 timestamp timest
  • TYPO3:未找到模板。无法解决视图的操作

    我正在尝试使用 TYPO3 后端模块 当我单击后端左侧菜单中的模块时 我试图获取视图 但是 当我单击此按钮时 我收到以下消息 抱歉 未找到请求的视图 技术原因是 没有找到模板 无法解析 MyVendor MyModule Controlle
  • 如何创建从反射获得的类型列表

    我有一个代码 如下所示 Assembly assembly Assembly LoadFrom ReflectionTest dll Type myType assembly GetType ReflectionTest TestObjec
  • 将序列中的值分配给一组连续的行,将某些行留空

    我试图对几个连续的行进行分组 并为它们分配相同的值 同时将某些行留空 当未满足某个条件时 我的数据是位置 xy 坐标 测量日期 时间以及测量之间的时间跨度 以某种方式简化 它们看起来像这样 ID X Y Time Span 1 3445 7
  • 在 C# 中列出位于 SFTP 服务器上的 ZIP 文件内的文件

    我需要通过 ASP NET Core 以编程方式处理来自 SFTP 服务器 WinSCP 的 ZIP 文件内的文件夹 有什么方法可以获取 ZIP 文件中的文件列表而无需下载到本地计算机吗 作为 文件大小会很大并且不会保持一致 任何帮助 将不