Banana limits string objects to 640k so sending a large file requires to break it into many small chunks. Twisted provide a helper class to do this: twisted.spread.pb.FilePager. I modified on recipe 457670: "How to use twisted pb pager" to demonstrate the usage of FilePager. getFile1() is similar to getIt() in recipe 457670. getFile2() uses the utility function in twisted.spread.pb.util.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | from twisted.spread.util import FilePager
from twisted.spread.flavors import Referenceable
from twisted.internet.defer import Deferred
import os
PATH = r"C:\temp\very_large_file.exe"
### Server Side
class ResultsPager(FilePager):
def __init__(self, collector, path):
self._deferred = Deferred()
print "%s, %d bytes" % (path, os.path.getsize(path))
fd = file(path, 'rb')
FilePager.__init__(self, collector, fd, callback=self.done)
def done(self):
print "The entire file has been transferred."
self._deferred.callback(self.collector)
def wait(self):
return self._deferred
class FilePagerizer(Referenceable):
def remote_getFile(self, collector, path):
pager = ResultsPager(collector, path)
return pager.wait()
### Client Side
class SimplePageCollector(Referenceable):
def __init__(self):
self.pages = []
def remote_gotPage(self, page):
self.pages.append(page)
print "gotPage (%d bytes)" % len(page)
def remote_endedPaging(self):
print 'endedPaging'
class FilerGetter:
def __init__(self, p):
self._file_pagerizer = p
def getRemoteFile(self, path):
root, ext = os.path.splitext(os.path.basename(path))
local_path = root + '-new' + ext
return self._file_pagerizer.callRemote(
"getFile",
SimplePageCollector(), path).addCallback(self._finished, local_path)
def _finished(self, collector, path):
data = ''.join(collector.pages)
with file(path, 'wb') as f:
f.write(data)
print "write to %s, %d bytes" % (path, len(data))
if __name__ == '__main__':
import sys
from twisted.internet import reactor
from twisted.python import log
log.startLogging(sys.stdout)
PORTNO = 8123
if sys.argv[1] == 'server':
from twisted.spread.flavors import Root
from twisted.spread.pb import PBServerFactory
class SimpleRoot(Root):
def rootObject(self, broker):
return FilePagerizer()
reactor.listenTCP(PORTNO, PBServerFactory(SimpleRoot()))
elif sys.argv[1] == 'client':
from twisted.spread import pb
def getFile1(x, path):
r = FilerGetter(x)
return r.getRemoteFile(path)
from twisted.spread import util
def getFile2(x, path):
def finished(pages):
data = ''.join(pages)
root, ext = os.path.splitext(os.path.basename(path))
local_path = root + '-new' + ext
f = file(local_path, 'wb')
f.write(data)
print "%d bytes written to %s" % (len(data), local_path)
util.getAllPages(x, "getFile", path).addCallback(finished)
cf = pb.PBClientFactory()
reactor.connectTCP("localhost", PORTNO, cf)
cf.getRootObject().addCallback(getFile2, PATH)
else:
raise sys.exit("usage: %s (server|client)" % sys.argv[0])
reactor.run()
|