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

时间:2011-05-22 18:11:16

标签: c++ python bittorrent

使用Rasterbar libtorrent我不希望下载的数据放在我的硬盘驱动器而不是管道或变量或软件上,所以我可以将它重定向到其他地方,Mysql,甚至垃圾,如果它不是我想要的,是无论如何,如果不是在使用Libtorrent的C ++中,最好在python绑定中执行此操作?

编辑: - >我想指出这是一个libtorrent问题,而不是Linux文件处理或Python文件处理问题。我需要告诉libtorrent而不是传统上将文件保存在普通文件中,将其保存到我的python管道或变量等等。

4 个答案:

答案 0 :(得分:7)

您可以通过实施自己的存储类与libtorrent一起使用来实现此目的。不幸的是,这在python中是不可能的,但你可以在c ++中完成。它的文档有点稀缺,可以找到here

以下是一个简单的示例,说明如何通过将所有数据存储在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;
};

添加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);
}

从这一点来说,将它存储在MySQL数据库或任何其他后端应该是相当直接的。

答案 1 :(得分:4)

如果您使用的是Linux,则可以使用tmpfs mount;这样可以避免写入磁盘。也就是说,这显然意味着你将大文件存储在RAM中;确保你有足够的记忆来处理这个问题。

另请注意,大多数Linux发行版都在/dev/shm处安装了tmpfs,因此您只需将libtorrent指向该文件即可。

答案 2 :(得分:0)

尝试为库提供cStringIO“文件句柄”而不是真正的文件句柄。这适用于大多数python库。

答案 3 :(得分:0)

我只是为了这个目的而在Go中使用implemented一个torrent客户端。我希望能够直接处理和控制数据,用于编写torrentfs,以及存储后端到S3和各种数据库。

将内存存储后端插入此客户端将是微不足道的。

相关问题