Уведомления

Группа в Telegram: @pythonsu

Уведомления

  • Found 3494 posts.

Python для новичков » Перехватить данные с xmlrpc сервера » Фев. 20, 2014 00:12:27

Имеется xmlrpc сервер. На него с программы ежесекундно приходят некие события. Как их можно перехватить и записать в какую-нибудь переменную??

Python для экспертов » Python-команды аналогичные Java » Фев. 19, 2014 23:02:10

Для Selenium имеются команды на Java:

String mainWindow = driver.getWindowHandle();
List<String> windows = new ArrayList<String>(driver.getWindowHandles());
driver.switchTo().window(windows.get(1));
driver.close();
driver.switchTo().window(mainWindow);

Подскажите, пожалуйста, аналог приведенных команд на Python ?

UPD:

Верно ли я перевел код?

listHandles = [];
mainWindow = driver.window_handles[0];

for handle in driver.window_handles:
listHandles.append(handle);

driver.switch_to_window(listHandles[1]);

driver.close();

Python для экспертов » PyOpenssl: генерация сертификатов » Фев. 19, 2014 07:31:40

Здраствуйте всем!

Стандарт сертификата SSL X.509 v3 позволяет добавлять свои поля в сертификат.
Мне нужно создать в OpenSSL SSL сертификат с дополнительным своим полем. Как это можно сделать используя библиотеку PyOpenSSL? Также рассматриваю варианты с другими библиотеками.

Data Mining » contents в beautyfulSoup » Фев. 18, 2014 19:42:52

помогите пожалуйста понять один очень важный момент, чтение документации не помогает(

не совсем понимаю как работает метод contents. следующим скриптом я делаю парсинг сайта
import urllib.request
import urllib.parse
import re
import os
import requests
import bs4
beginIndex = 1000
endIndex = 1010
prefix = "http://www.inpic.ru"
rep_chars = ['\\', '/', ':', '*', '?', '"', '<', '>', '|']
for i in range(beginIndex, endIndex):
    req = requests.get(prefix + '/image/' + str(i))
    if req.status_code == requests.codes.ok:
        print(i, '\t', req.status_code, '\t', req, end='\n')
        soup = bs4.BeautifulSoup(req.content)
        #print(soup.prettify())
        name = soup.find("td", {"class": "post_title"}).contents[1].contents
        author = soup.find("td", {"class": "post_title"}).contents[2].contents[1].contents
        print(name[0])
        mainImagePath = soup.find("img", {"class": "image last"})["src"]
        manyImages = soup.findAll("img", {"class": "image"})
        print(mainImagePath)
        print(manyImages)
        if manyImages != []:
            newName = re.escape(name[0])
            #newName = re.sub('[\\\\/:*?"<>|]', 'special char', name[0])
            #for char in rep_chars:
                #newName = name[0].replace(char, '')
            try: 
                os.mkdir(str(newName))
            except FileExistsError:
                print('FileExistsError')
            except PermissionError :
                print('PermissionError ')
            except :
                print('error')                
            else:
                print('ok')
        else:
            pass

часть html страницы http://www.inpic.ru/image/1001/
  
<table>
  <tbody><tr>
      <td>
        <table class="post_rating">
          <tbody><tr>
            <td id="post_rating_left1001" class="post_rating_left_positive">
                              <div class="post_rating_none"></div>
                              
            </td>
            <td id="post_rating_center1001" class="post_rating_value_positive">
              <span id="post_rating1001">19</span>
            </td>
            <td id="post_rating_right1001" class="post_rating_right_positive">
                              <div class="post_rating_none"></div>
                          </td>
          </tr>
        </tbody></table>
      </td>
      <td class="post_title">
       <h1>Эти хитрые японцы...</h1>
       <div class="date_author"><a href="/users/Stack/">Stack</a> / 28.06.2008 21:59</div>
      </td>
    </tr>
  </tbody></table>

теоретически name должен указывать на
<h1>Эти хитрые японцы...</h1>
так как find находит элемент с классом post_title , а contents1 это первый вложенный элемент, в котором contents - текст

далее теоретически author должен указывать на
<a href="/users/Stack/">Stack</a>
так как find находит элемент с классом post_title , а contents2 это второй вложенный элемент, в котором есть
<a href="/users/Stack/">Stack</a>

но тем не менее скрипт выводит ошибку:
Traceback (most recent call last):
File “C:\VINT\OPENSERVER\OpenServer\domains\localhost\python\parse_html\1\q.py”, line 21, in <module>
author = soup.find(“td”, {“class”: “post_title”}).contents.contents.contents
File “C:\Python33\lib\site-packages\bs4\element.py”, line 675, in __getattr__
self.__class__.__name__, attr))
AttributeError: ‘NavigableString’ object has no attribute ‘contents’

пожалуйста не советуйте мне использовать что-нибудь типа nextSibling или пересмотреть алгоритм поиска. здесь мне важнее всего именно разобраться с этим загадочным contents

Python для новичков » PyUSB & HID » Фев. 15, 2014 15:50:55

Привет. Есть устройство которое работает по протоколу HID. К нему я подключиться смог без ошибок. Это устройство как только его запитать начинает слать пакеты. Т.е. не надо на него слать никакие команды. Я начинаю считывание
import usb.core
import usb.util
dev = usb.core.find(idVendor=0x1234, idProduct=0x0001)
if dev is None:
    raise ValueError('Device not found')
#dev.set_configuration()
test = dev.read(0x81,8)
print "res: ",test
Появляется следующая ошибка
usb.core.USBError: Resource busy
Устройство рабочее точно. НА винде на java работало

Центр помощи » Как netCDF4.Variable разпарсить на массивы строк и в ASCII-файл записать? » Фев. 15, 2014 15:05:41

Как netCDF4.Variable разпарсить на массивы строк и в ASCII-файл записать?

Python для экспертов » Получить раскладку клавиатуры X11 » Фев. 13, 2014 13:59:05

Великие гуру питона помогите найти верное решение, знаю что таких тем на stackoverflow.com полно, но не одна тема не даёт правильного ответа. Задача в следующем.
Помогите правильно, наименее “костыльно” получить текущую раскладку X11.
Сейчас используется такой вариант:
Установлена утилита skb от малоизвестного автора, соответственно в состав никакого дистрибутива не входит.
В Python коде использую её так:
import subprocess
keyboard = subprocess.check_output(['skb', '-now']).strip()
Существует обвязка поверх Xlib
Но там я не нашел реализации функции, а-ля “получить текущую раскладку клавиатуры”. Интересует метод получения раскладки клавиатуры, более приемлемым способом. Вариант с skb на данный момент более подходящий потому что возвращает любую раскладку клавиатура, а не только тогда, когда есть только 2 раскладки.

setxkbmap -print и setxkbmap -query дают АБСОЛЮТНО одинаковые результаты для разных раскладок клавиатуры.

Python для экспертов » Bottle + beaker + хуки » Фев. 13, 2014 09:56:45

Привет всем.
Пишу простенькое приложение-блог на bottle и естественно настал момент когда нужны сессии. Интересно насколько безопасно использование bottle.BaseTemplate.defaults для передачи сессии в шаблон (используестя mako). Может другие решения есть?
Заранее благодарен.

Накидал такой код:
### session hook   
@root.hook('before_request')
def set_default():
    session = request.environ['beaker.session']
    if 'token' in session:
        pass
    else:
        import random
        import string
        session['token'] = ''.join(
            random.choice(string.ascii_uppercase +\
            string.digits) for x in range(7)
            )
        session.save()
    bottle.BaseTemplate.defaults['session'] = session
    bottle.BaseTemplate.defaults['token'] = session['token']
    user = False # просто так
    if 'user' in session:
        user = session['user']
    bottle.BaseTemplate.defaults['user'] = user
###  end hook

Network » socketserver » Фев. 11, 2014 17:40:07

Недавно начал изучать python и столкнулся с проблемой, написал сервер который принимает число, складывает его со своим и отправляет пользователю. Всё хорошо функционирует, но при подключение более 30 клиентов сервер не может принимать данные. Пакеты идут 20 раз в секунду, сервер кушает всего 8% от процессора и 12 метров оперативы. Сервер работает на socketserver, а клиент на socket.

server

import socketserver
import time
import pickle
import threading
a = 0
def main():
    global a
    while True:
        a1 = int(a)
        digits = str(a1)
        result = ''
        while digits:
            digits, last3 = digits[:-3], digits[-3:]
            if result:
                result = (last3 + ',' + result)
            else:
                result = last3
        file_1 = open("file.txt", "w")
        file_1.write(str(result))
        file_1.close()
        print(result)
        time.sleep(0.05)
t1 = threading.Thread(target=main)
t1.start()
class MyTCPServer(socketserver.ThreadingTCPServer):
    allow_reuse_address = True
class MyTCPServerHandler(socketserver.BaseRequestHandler):
    def handle(self):
        global a
        b = pickle.loads(self.request.recv(1024))
        a=a+b
        self.request.sendall(pickle.dumps(a))
server = MyTCPServer(('localhost', 13373), MyTCPServerHandler)
server.serve_forever()

client

import time
import socket
import threading
import pickle
x = 1
def internet():
    global x
    while True:
        conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        conn.connect(("localhost", 13373))
        conn.sendall(pickle.dumps(x))
        y = pickle.loads(conn.recv(1024))
        conn.close()
        print(y)
        time.sleep(0.05)
t1 = threading.Thread(target=internet)
t1.start()

Python для новичков » Gtk.TreeView + Gtk.Popup Menu » Фев. 10, 2014 15:26:21

Доброго времени суток! Помогите пожалуйста решить вот такую проблемку:
У меня есть Gtk.Tree View в котором есть какая то информация и есть Gtk.Popup Menu, которое выпадает при щелчке правой кнопки мышки на каком нибудь элементе TreeView. Я могу клацать по пунктам меню и запускать функции. Но у меня не получается передать информацию из строки TreeView на которой я вызвал меню в мои функции. Подскажите пожалуйста как это сделать. Вот так вот я вызываю меню:
 self.treeviewR_popup = builder.get_object('treeviewR_popup')
        if event.button == 3:
            x = int(event.x)
            y = int(event.y)
            timez = event.time
            pthinfo = treeView_right.get_path_at_pos(x, y)
            if pthinfo is not None:
                path, col, cellx, celly = pthinfo
                treeView_right.grab_focus()
                treeView_right.set_cursor(path, col, 0)
                self.treeviewR_popup.popup(None, None, None, None, event.button, event.time)

Мне надо получить примерно вот такой эффект только на python. В плане не редактировать, а передать информацию на некую другую формую, к примеру.

GUI » PyGTK, scrolled window, так и должно быть?  » Фев. 9, 2014 17:29:46

Приветствую, экспериментирую с PyGTK, но получается какая-то ерунда, так и должно быть? Откуда такие зазоры возле скрол-баров и почему статус-бар тоже закрашивается?
Вот код:
import gtk
import 
class PyApp(gtk.Window):
    def __init__(self):
        super(PyApp, self).__init__()
        self.set_title("example")
        self.set_size_request(800, 600)
        self.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(35000, 35000, 35000))
        self.set_position(gtk.WIN_POS_
        # --- Main menu ---
        mb = gtk.MenuBar()
        filemenu = gtk.Menu()
        filem = gtk.MenuItem("_File")
        filem.set_submenu(filemenu)
        agr = gtk.AccelGroup()
        self.add_accel_group(agr)
        newi = gtk.ImageMenuItem(gtk.STOCK_NEW, agr)
        key, mod = gtk.accelerator_parse("<Control>N")
        newi.add_accelerator("activate", agr, key, mod, gtk.ACCEL_VISIBLE)
        filemenu.append(newi)
        openm = gtk.ImageMenuItem(gtk.STOCK_OPEN, agr)
        key, mod = gtk.accelerator_parse("<Control>O")
        openm.add_accelerator("activate", agr, key, mod, gtk.ACCEL_VISIBLE)
        filemenu.append(openm)
        sep = gtk.SeparatorMenuItem()
        filemenu.append(sep)
        exit = gtk.ImageMenuItem(gtk.STOCK_QUIT, agr)
        key, mod = gtk.accelerator_parse("<Control>Q")
        exit.add_accelerator("activate", agr, key, mod, gtk.ACCEL_VISIBLE)
        exit.connect("activate", gtk.main_quit)
        filemenu.append(exit)
        mb.append(filem)
        # --- Scrolled window ---
        scrolled_window = gtk.ScrolledWindow()
        scrolled_window.set_policy(gtk.POLICY_ALWAYS, gtk.POLICY_ALWAYS)
        # --- Drawing area ---
        darea = gtk.DrawingArea()
        darea.connect("expose-event", self.expose)
        scrolled_window.add_with_viewport(darea)
        # --- Status bar
        status_bar = gtk.Statusbar()
        status_bar.push(0, "example")
        vbox = gtk.VBox(False, 0)
        vbox.pack_start(mb, False, False, 0)
        vbox.pack_start(scrolled_window, True, True, 0)
        vbox.pack_start(status_bar, False, False, 0)
        self.add(vbox)
        self.connect("destroy", gtk.main_quit)
        self.show_all()
    def expose(self, widget, event):
        cr = widget.window.cairo_create()
        cr.set_source_rgb(0.6, 0.6, 0.6)
        cr.rectangle(20, 20, 120, 80)
        cr.rectangle(180, 20, 80, 80)
        cr.fill()
        cr.arc(330, 60, 40, 0, 2*math.pi)
        cr.fill()
        cr.arc(90, 160, 40, math.pi/4, math.pi)
        cr.fill()
        cr.translate(220, 180)
        cr.scale(1, 0.7)
        cr.arc(0, 0, 50, 0, 2*math.pi)
        cr.fill()
def main():
    gtk.main()
    return 0
if __name__ == "__main__":
    PyApp()
    main()

Python для новичков » winpdb размер шрифта » Фев. 8, 2014 09:59:55

Господа, откройте мне страшную тайну: как в winpdb размер шрифта подкрутить. Думал научиться пользоваться, но на такой мелкий серый шрифт на белом как по умолчанию смотреть больно, а настроек интрфейса (и вообще настроек кроме кодироки) не вижу. По “winpdb font size” тина акакая-то нагугливается.
ОС - linux mint, winpdb из репов.

Python для новичков » Подстановка значений в переменные в SymPy » Фев. 7, 2014 18:19:22

from sympy import *
U3 = Symbol('U3')
U4 = Symbol('U4')
U5 = Symbol('U5')
δ3 = Symbol('δ3')
δ4 = Symbol('δ4')
δ5 = Symbol('δ5')
δ2 = Symbol('δ2')
urav = [44.0*U3*cos(δ2 - δ3 + 0.64) + 51.85*U5*cos(δ2 - δ5 + 0.78) + 34223.96*cos(δ2 + 0.78) - 40110.66,
        -0.16*U3**2 + 44.0*U3*cos(-δ2 + δ3 + 0.64) - 100,
        0.12*U3**2 - 44.0*U3*sin(-δ2 + δ3 + 0.64) - 200,
        -0.25*U4**2 + 77.78*U4*cos(δ4 + 0.78) - 100,
        0.25*U4**2 - 77.78*U4*sin(δ4 + 0.78) - 200,
        -0.16*U5**2 + 51.85*U5*cos(-δ2 + δ5 + 0.78) - 100,
        0.16*U5**2 - 51.85*U5*sin(-δ2 + δ5 + 0.78) - 200]
pribl = {'U4': 220, 'U5': 220, 'δ3': 0, 'δ2': 0, 'U3': 220, 'δ5': 0, 'δ4': 0}
for string in urav:
    for var, value in pribl.items():
        var = Symbol(str(var))
        string.subs(var, value)

Существует некий вектор(urav), зависимый от n-числа переменных(в данном случае их семь)
Также существует словарь, в котором заданы начальные значения этих переменных и сами переменные.
Необходимо сделать хотя бы 1 итерацию с этими значениями, которые представлены в словаре, однако
for string in urav:
    for var, value in pribl.items():
        var = Symbol(str(var))
        string.subs(var, value)
результата не имеет..просьба ткнуть носом, в чем ошибка.
Если есть вариант сделать всё то же, но без SymPy - буду только рад.

Базы данных » Валидация значения поля. » Фев. 4, 2014 12:28:59

Сейчас будет много несвязанного текста) Заранее прошу прощения.
Надо сделать программку-валидатор.
Т.е. вводится значение, которое проверяется на валидность.
Одно из условий - “ Для числового поля заданы мин числовое и макс числовое в БД.”
Меня интересует: как сделать проверку поля в таблице - оформлять в виде отдельной функции, которая будет вызываться после того как мы внесли значение в поле и проверять его на валидность или же есть возможность задать форматирование поля при создании бд?
Планирую использовать SQLite. Из бд знаком только с access.

Python для экспертов » Помогите сгенерить XML » Фев. 4, 2014 10:19:04

Нужно создать XML такого вида:
<feed xmlns="http://www.ixtens.com/xml/mp/override/R1.1“ xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance“ xsi:schemaLocation=”http://www.ixtens.com/xml/mp/override/R1.1 http://support.ixtens.com/mp/R1.1/product/override.xsd">

Данные

</feed>

Делаю

import lxml.etree
xmlns = "http://www.ixtens.com/xml/mp/override/R1.1"
xmlns_xsi = "http://www.w3.org/2001/XMLSchema-instance"
xsi_schemaLocation = "http://www.ixtens.com/xml/mp/override/R1.1 http://support.ixtens.com/mp/R1.1/product/override.xsd"
NSMAP = {None: xmlns}
new_feed = lxml.etree.Element('feed', nsmap=NSMAP)
new_feed = lxml.etree.Element('feed')
new_feed.set('xmlns', xmlns)
head = lxml.etree.SubElement(new_feed, 'data')
new_feed.set('{http://www.ixtens.com/xml/mp/override/R1.1}xsi', xmlns_xsi)
new_feed.set('{http://www.w3.org/2001/XMLSchema-instance}schemaLocation', xsi_schemaLocation)
print(lxml.etree.tostring(new_feed, pretty_print=True, encoding='utf-8', xml_declaration=True))

Получаю
<?xml version='1.0' encoding='utf-8'?>
<feed xmlns:ns0="http://www.ixtens.com/xml/mp/override/R1.1“ xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance“ xmlns=”http://www.ixtens.com/xml/mp/override/R1.1“ ns0:xsi=”http://www.w3.org/2001/XMLSchema-instance“ xsi:schemaLocation=”http://www.ixtens.com/xml/mp/override/R1.1 http://support.ixtens.com/mp/R1.1/product/override.xsd">
<data/>
</feed>

Как сгенерить правильное пространство имен?

UPD(05.02.2014): Ответили на Тостере

Python для экспертов » Разбор параметров командной строки в Python » Янв. 29, 2014 08:29:30

Написал статью про разбор параметров командной строки в Python, в которой рассматриваются основные возможности стандартной Python-библиотеки argparse, говорится о том, как создавать именованные и позиционные параметры, рассматриваются различные варианты их использования, в том числе в виде флагов, а также рассказывается, как оформлять справку с использованием этой библиотеки.

http://jenyay.net/Programming/Argparse

Django » DJANGO TAGGIN POST_SAVE SIGNAL » Янв. 28, 2014 07:49:29

Всем привет. есть модель в которой я использую теги. Но заметил такую фичу. При сохранении TestObject удаляются все теги. object.save() то есть я предварительно ничего не делаю с обьектом а просто вызываю метод save и все тэги удаляются.

from tagging.fields import TagField
class TestObject(models.Model):
    title  = models.CharField(_("page title"), max_length=255)
    tags = TagField(null=True, blank=True,)

С помощью debug toolbar заметил что вызывается post_save TagField._save.
Вот сама функция

def _save(self, **kwargs): #signal, sender, instance):
    tags = self._get_instance_tag_cache(kwargs['instance'])
    if tags is not None:
        Tag.objects.update_tags(kwargs['instance'], tags)
def _get_instance_tag_cache(self, instance):
    return getattr(instance, '_%s_cache' % self.attname, None)

закомментировал строку
 #  if tags is not None:
# Tag.objects.update_tags(kwargs['instance'], tags)
заработало. меня смущает что я комментирую строку автора, и это не правильно. не могу понять он ждет в аргументах теги?

Django » Queryset в Таблицу » Янв. 27, 2014 10:59:56

нужно сформировать данные для google visualization из django в шаблоне в виде:

[ 
['День', 'Объект1', 'Объект2', 'Объект3'],
['01.01.2014',5,0,3],
['02.01.2014',2,1,1],
['03.01.2014',0,5,0],
...
]

данные представлены как результат запроса, т.е.:

'01.01.2014', ‘Объект1’, 5
'01.01.2014', ‘Объект3’, 3
'02.01.2014', ‘Объект1’, 2
'02.01.2014', ‘Объект2’, 1
'02.01.2014', ‘Объект3’, 1
'03.01.2014', ‘Объект2’, 0

как правильнее сделать это?

Python для новичков » Помогите адаптировать приложение под актуальную версию django » Янв. 25, 2014 05:17:43

Вопрос такой, начал изучать python+django 1.6
Изучаю на примере создания личного блога портфолио.
Встал вопрос о самом компоненте портфолио, нашел в сети и форкнул к себе в гитхаб вот это приложение _https://github.com/powellc/django-portfolio
Но оно написано очень давно и конечно сыпет ошибки((
Начну по порядку сначала ругалось вот на это
from django.views.generic import date_based, list_detail
Нашел вроде решение что нужно импорт изменить на такой
from django.views.generic import date_based, list_detail
Потом начало ругаться на
from tagging.fields import TagField и на import tagging
в целях простого теста просто закоментил для начала

Но позже вылезла вот такая ошибка
__init__() takes exactly 1 argument (5 given) вот тут views.py in project_list, line 13

Сама 13 стока файла вот так выглядит
**kwargs

Сам файл views.py приведу
from django.shortcuts import render_to_response, get_object_or_404
from django.template import RequestContext
from django.http import Http404
from django.views.generic import date_based, list_detail
from portfolio.models import Project, Medium
def project_list(request, page=0, **kwargs):
    return list_detail.object_list(
        request,
        queryset=Project.objects.public(),
        paginate_by=5,
        page=page,
        **kwargs
    )
project_list.__doc__ = list_detail.object_list.__doc__
def medium_list(request, **kwargs):
    return list_detail.object_list(
        request,
        queryset = Medium.objects.all(),
        **kwargs
    )

Ну и файл models.py сразу
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.db.models import permalink
from tagging.fields import TagField
from portfolio.managers import PublicManager
import tagging
class Client(models.Model):
    name = models.CharField(max_length=250)
    url = models.URLField(blank=True)
    
    class Meta:
        db_table = "clients"
        ordering = ['name']
        
    def __unicode__(self):
        return self.name
    
class Medium(models.Model):
    name = models.CharField(max_length=250)
    slug = models.SlugField()
    
    class Meta:
        db_table = "media"
        verbose_name_plural = "media"
        ordering = ['name']
    
    def __unicode__(self):
        return self.name
        
    @permalink
    def get_absolute_url(self):
        return self.slug
    
class Project(models.Model):
    name = models.CharField(max_length=250)
    slug = models.SlugField()
    project_url = models.URLField('Project URL')
    description = models.TextField(blank=True)
    client = models.ForeignKey(Client)
    media = models.ManyToManyField(Medium)
    disciplines = TagField()
    completion_date = models.DateField()
    in_development = models.BooleanField()
    is_public = models.BooleanField(default=True)
    overview_image = models.ImageField(upload_to="projects/overview/")
    detail_image = models.ImageField(upload_to="projects/detail/")
    objects         = PublicManager()
    
    class Meta:
        db_table = "projects"
        ordering = ['-completion_date']
        
    def __unicode__(self):
        return self.name
    
    @permalink
    def get_absolute_url(self):
        return self.slug

Файлы привел оригинального состояния без моих правок, помогите запустить приложение
Сразу прощения если тему не правильно оформил

Pyramid / Pylons / TurboGears » Pyramid, Deform and FileUploadTempStore » Янв. 23, 2014 17:23:52

Пытаюсь разобраться с выгрузкой файлов в Пирамиде - сделал свой класс с интерфейсом FileUploadTempStore, сессии не используются. Обеспечил в методе __setitem__ чтение файла и его сохранение в временную директорию на диске, там же наверно можно добавить какие-либо проверки и т.п.
А потом и подумал - а зачем это все городить? И как потом почистить эту директорию для временных файлов из моего приложения? (извне - cron'ом)
Или лучше завязать реализацию FileUploadTempStore на механизм сессий?

Подскажите пожалуйста, как правильнее использовать FileUploadTempStore? Может есть еще какая-то неочевидная новичку польза от этого хранилища, особенно по сравнению с тупым чтением пересылаемого файла и записью его на диск?