简体   繁体   English

将下载的torrent保存在内存中而不是文件libtorrent

[英]Keeping the downloaded torrent in memory rather than file libtorrent

Working with Rasterbar libtorrent I dont want the downloaded data to sit on my hard drive rather a pipe or variable or something Soft so I can redirect it to somewhere else, Mysql, or even trash if it is not what I want, is there anyway of doing this in preferably python binding if not in C++ using Libtorrent? 使用Rasterbar libtorrent我不希望下载的数据放在我的硬盘驱动器而不是管道或变量或软件上,所以我可以将它重定向到其他地方,Mysql,甚至垃圾,如果它不是我想要的,无论如何如果不是在C ++中使用Libtorrent,最好在python绑定中执行此操作?

EDIT:--> I like to point out this is a libtorrent question not a Linux file handling or Python file handling question. 编辑: - >我想指出这是一个libtorrent问题,而不是Linux文件处理或Python文件处理问题。 I need to tell libtorrent to instead of save the file traditionally in a normal file save it to my python pipe or variable or etc. 我需要告诉libtorrent而不是传统上将文件保存在普通文件中,将其保存到我的python管道或变量等。

You can do this by implementing your own storage class to use with libtorrent. 您可以通过实现自己的存储类来与libtorrent一起使用来实现此目的。 Unfortunately this is not possible to do in python, but you can do it in c++. 不幸的是,这在python中是不可能的,但你可以在c ++中完成。 The documentation for it is a bit scarce and can be found here . 它的文档有点稀缺,可以在这里找到。

Here's a simple example of how to do this by storing all the data in RAM: 这是一个简单的例子,说明如何通过将所有数据存储在RAM中来实现:

struct temp_storage : storage_interface
{
   temp_storage(file_storage const& fs) : m_files(fs) {}
   virtual bool initialize(bool allocate_files) { return false; }
   virtual bool has_any_file() { return false; }
   virtual int read(char* buf, int slot, int offset, int size)
   {
      std::map<int, std::vector<char> >::const_iterator i = m_file_data.find(slot);
      if (i == m_file_data.end()) return 0;
      int available = i->second.size() - offset;
      if (available <= 0) return 0;
      if (available > size) available = size;
      memcpy(buf, &i->second[offset], available);
      return available;
   }
   virtual int write(const char* buf, int slot, int offset, int size)
   {
      std::vector<char>& data = m_file_data[slot];
      if (data.size() < offset + size) data.resize(offset + size);
      std::memcpy(&data[offset], buf, size);
      return size;
   }
   virtual bool rename_file(int file, std::string const& new_name) { assert(false); return false; }
   virtual bool move_storage(std::string const& save_path) { return false; }
   virtual bool verify_resume_data(lazy_entry const& rd, error_code& error) { return false; }
   virtual bool write_resume_data(entry& rd) const { return false; }
   virtual bool move_slot(int src_slot, int dst_slot) { assert(false); return false; }
   virtual bool swap_slots(int slot1, int slot2) { assert(false); return false; }
   virtual bool swap_slots3(int slot1, int slot2, int slot3) { assert(false); return false; }
   virtual size_type physical_offset(int slot, int offset) { return slot * m_files.piece_length() + offset; };
   virtual sha1_hash hash_for_slot(int slot, partial_hash& ph, int piece_size)
   {
      int left = piece_size - ph.offset;
      TORRENT_ASSERT(left >= 0);
      if (left > 0)
      {
         std::vector<char>& data = m_file_data[slot];
         // if there are padding files, those blocks will be considered
         // completed even though they haven't been written to the storage.
         // in this case, just extend the piece buffer to its full size
         // and fill it with zeroes.
         if (data.size() < piece_size) data.resize(piece_size, 0);
         ph.h.update(&data[ph.offset], left);
      }
      return ph.h.final();
   }
   virtual bool release_files() { return false; }
   virtual bool delete_files() { return false; }

   std::map<int, std::vector<char> > m_file_data;
   file_storage m_files;
};

You'd also need a constructor function to pass in through the add_torrent_params struct when adding a torrent: 在添加torrent时,您还需要一个构造函数来通过add_torrent_params结构传入:

storage_interface* temp_storage_constructor(
   file_storage const& fs, file_storage const* mapped
   , std::string const& path, file_pool& fp
   , std::vector<boost::uint8_t> const& prio)
{
   return new temp_storage(fs);
}

From this point it should be fairly straight forward to store it in a MySQL database or any other back-end. 从这一点来看,将它存储在MySQL数据库或任何其他后端应该是相当直接的。

If you're on Linux, you could torrent into a tmpfs mount; 如果您使用的是Linux,则可以使用tmpfs mount; this will avoid writing to disk. 这样可以避免写入磁盘。 That said, this obviously means you're storing large files in RAM; 也就是说,这显然意味着你将大文件存储在RAM中; make sure you have enough memory to deal with this. 确保你有足够的内存来处理这个问题。

Note also that most Linux distributions have a tmpfs mount at /dev/shm , so you could simply point libtorrent to a file there. 另请注意,大多数Linux发行版在/dev/shm都有一个tmpfs挂载,所以你可以简单地将libtorrent指向那里的文件。

I've implemented a torrent client in Go just for this purpose. 为此,我在Go中实现了一个torrent客户端。 I wanted to able to handle and control the data directly, for use in writing torrentfs, and to have storage backends to S3 and various databases. 我希望能够直接处理和控制数据,用于编写torrentf,以及存储后端到S3和各种数据库。

It would be trivial to plug in an in-memory storage backend to this client. 将内存存储后端插入此客户端将是微不足道的。

Try giving the library a cStringIO "file handle" instead of a real file handle. 尝试为库提供cStringIO “文件句柄”而不是真正的文件句柄。 That works for most python libraries. 这适用于大多数python库。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM