写入时的 MonoTorrent 事件

Posted

技术标签:

【中文标题】写入时的 MonoTorrent 事件【英文标题】:MonoTorrent Event when piece written 【发布时间】:2019-11-16 11:50:26 【问题描述】:

我一直在尝试使用 C# MonoTorrent 库,但缺少文档并没有帮助。我正在尝试流式传输文件,但要做到这一点,每当将 Piece 写入文件或类似的东西时,我都需要一个事件。

我知道有一个事件会在对 Piece 进行哈希处理时触发,但是当我需要实际内容时它就不是那么有用了。

所以我想问一下我如何知道片段何时写入文件,以便我可以解析它然后流式传输该电影。

我已经查看了TorrentManagerClientEngineDiskManager,但在这些类或任何其他 Manager 类中都没有发现任何有用的东西。现在这个功能只是隐藏在某个地方还是我必须做一些不同的事情才能获得下载的片段?

【问题讨论】:

【参考方案1】:

PieceHashed 事件是您所需要的。引发该事件时,您可以保证与该片段相关的数据已被接收、验证并写入 DiskManager。

如果正在使用MemoryWriter,则在引发事件时数据可能不会写入底层硬盘驱动器/SSD。为了保证您需要调用FlushAsync 方法,传入 TorrentManager 和片段索引。如果一个片段大小为 256kB,并且片段 6 中包含三个长度分别为 200kb、50kb 和 6kb 的文件,那么如果您传入“6”作为片段索引,所有这三个文件都将被刷新。如果您调用不采用 PieceIndex 的重载,它将改为刷新每个文件。

如果您正在编写类似SlidingWindowPicker 的内容,那么您应该只在下载了高优先级集合中的片段后才调用 FlushAsync。任何对 flush 的调用都会刷新给定文件(或所有文件)的 all 待处理数据。如果您拥有的唯一数据来自洪流的最后,那么立即刷新它不会影响您的流式传输能力,但可能会增加开销。

【讨论】:

非常感谢您的回答,我不知道 FlushAsync 方法。在这种情况下,使用 PieceHashed 方法解决我的问题应该没有问题 我一直在尝试调用 ClientEngine 的 DiskManager 上的 FlushAsync 方法,但它似乎不存在。 Intellisense 没有显示该方法,编译器抱怨它也不存在。我有最新的 NuGet 版本,是否有可能缺少某些内容? 我还使用dotPeek反编译了NuGet的dll,也显示这些方法丢失了。 我刚刚看到,您最近才公开了这些方法。你认为你可以很快将它们上传到 nuget,否则我总是可以自己编译它。不过还是感谢您花时间进行更改。 它现在在最新的 nuget 版本中!我会用一个稍微复杂的替代方案来发表评论。【参考方案2】:

还有一种替代方法,即实现 IPieceWriter 并创建一个包装器,该包装器在写入适当的片段时刷新。

现有的 MemoryWriter 展示了如何创建包装器。它的Write方法实现如下:https://github.com/mono/monotorrent/blob/2209922c4159e394242c6c337401571312642b6e/src/MonoTorrent/MonoTorrent.Client.PieceWriters/MemoryWriter.cs#L118-L123.

如果你想写一些东西来自动刷新片段,你会做这样的事情:

public void Write(TorrentFile file, long offset, byte[] buffer, int bufferOffset, int count, bool forceWrite)

    Writer.Write(file, offset, buffer, bufferOffset, count);
    Writer.Flush(file);

【讨论】:

以上是关于写入时的 MonoTorrent 事件的主要内容,如果未能解决你的问题,请参考以下文章

Monotorrent 传输文件

MonoTorrent - 指向 Torrent 文件的磁力链​​接

使用 monotorrent 创建 torrent

使用 monotorrent c# 创建 torrent

BitSharp / MonoTorrent 扼杀所有同行

使用 Monotorrent 在 VB.NET 中加载 Torrent