Сохранение загруженного торрента в памяти, а не файла libtorrent

Работая с Rasterbar libtorrent, я не хочу, чтобы загруженные данные находились на моем жестком диске, а были в канале, переменной или чем-то программном, чтобы я мог перенаправить их куда-то еще, Mysql или даже в мусор, если это не то, что я хочу, есть ли в любом случае делать это предпочтительно с привязкой к Python, если не на C ++, используя Libtorrent?

РЕДАКТИРОВАТЬ: --> Мне нравится указывать, что это вопрос libtorrent, а не вопрос обработки файлов Linux или Python. Мне нужно сказать libtorrent вместо того, чтобы сохранять файл традиционно в обычном файле, сохранить его в моем канале python или переменной или т. д.


person Max    schedule 22.05.2011    source источник


Ответы (4)


Вы можете сделать это, реализовав свой собственный класс storage для использования с libtorrent. К сожалению, это невозможно сделать на питоне, но вы можете сделать это на с++. Документация для него немного скудна, и ее можно найти здесь .

Вот простой пример того, как это сделать, сохранив все данные в оперативной памяти:

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;
};

Вам также понадобится функция-конструктор для прохождения через структуру 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 или любой другой серверной части.

person Arvid    schedule 23.05.2011
comment
Есть ли шанс обновить это для libtorrent-1.2.0? Кроме того, кажется, что происходит многое, чтобы сопоставить данные с их конечным пунктом назначения в файле. На самом деле так много (readwritev), что на данный момент кажется проще просто переопределить default_storage и изменить только некоторые части readv и writev - person user1593842; 03.02.2019

Если вы используете Linux, вы можете использовать торрент в монтирование tmpfs; это позволит избежать записи на диск. Тем не менее, это, очевидно, означает, что вы храните большие файлы в оперативной памяти; убедитесь, что у вас достаточно памяти, чтобы справиться с этим.

Также обратите внимание, что большинство дистрибутивов Linux имеют монтирование tmpfs в /dev/shm, поэтому вы можете просто указать libtorrent на файл там.

person bdonlan    schedule 22.05.2011
comment
это звучит хорошо, но я почти уверен, что должен быть способ сделать это через сам libtorrent. - person Max; 23.05.2011

Специально для этой цели я реализовал торрент-клиент на Go. Я хотел иметь возможность обрабатывать и контролировать данные напрямую, чтобы использовать их при написании torrentfs, а также иметь бэкенды для хранения S3 и различных баз данных.

Было бы тривиально подключить к этому клиенту серверную часть хранилища в памяти.

person Matt Joiner    schedule 13.03.2015
comment
Не могли бы вы предоставить или указать мне, где я могу найти MWE для реализации этого, а именно для загрузки торрента (желательно определенных файлов) в память? Меня интересует эта функция, поскольку я хочу загружать торрент-файл за файлом в удаленное хранилище (Google Диск). - person YenForYang; 25.07.2019
comment
@YenForYang, вы должны направлять эти вопросы на github.com/anacrolix/torrent/issues - person Matt Joiner; 26.07.2019

Попробуйте дать библиотеке cStringIO "дескриптор файла" вместо настоящего дескриптора файла. Это работает для большинства библиотек Python.

person chmullig    schedule 22.05.2011
comment
Проблема в том, что привязка python плохо документирована, и она не принимает дескриптор, она принимает только адрес пути или, по крайней мере, я так думаю :( - person Max; 22.05.2011