The method file() of FTPHost lacks extra numeric argument "rest" (or "offset") which is given to _FTPFile method _open() in line 228:
The method _open() uses this argument for transfercmd() method in lines 85-86:
self._conn = ftp_error._try_with_ioerror( self._session.transfercmd, command)
This will give functionality of byte offset supported by transfercmd (http://docs.python.org/library/ftplib.html#ftplib.FTP.transfercmd). It does not fully cover ticket #14, however it will save lots of time of developers who simply need byte offset when reading files.
This is critical for me too.
Regards, Łukasz (lm at zork.pl)
RESTcommand was originally described in RFC 959, section 3.5. The RFC describes
RESTonly in the context of the "block" and "compressed" modes, which aren't used by Python's
ftplib. RFC 959 describes
RESTmarkers which don't have to consist of digits.
On the other hand, RFC 3659, chapter 5 describes an extension for the use of
RESTin "stream" mode. For binary transfer, the
RESTparameter is the 0-based byte count from where reading from or writing to a remote file should start.
For example, if a remote file contains the bytes
(represented as ASCII letters here), a
REST 3, followed by a
RETRcommand, will read the string "defghijkl". A
REST 3, followed by a
STORcommand, will overwrite the bytes starting at "d".
If the data written to the server has fewer bytes than the remaining bytes on the remote side, the "extra" remote bytes (here "jkl") will get lost. For example, writing "123" to the above remote file "abcdefghijkl" will result in the new remote content "abc123". I don't know if the shortening of the remote file is officially specified anywhere, but it's the behavior I see with my FTP server (Pure FTPd).
As suggested in the ticket description, I'm going to add a
file). For now, this argument will only be supported for binary transfer modes since applying the concept to text files may give confusing results.
Since ftputil is about simulating Python's API for local file systems, I had considered implementing the "offset" functionality with a
FTPFileobjects (the type of object returned by
FTPHost.open). However, this is far more complicated to implement:
seekwould have to reopen the file with a
RESTargument and an identical path.
- Having a
tell(local files have a
tellmethod) would be awkward.
tellwould require keeping track of a counter when reading from or writing to a remote file.
All in all, implementing the "rest" functionality via a file
seekmethod may be an interesting experiment, but offers little gain compared to the implementation effort.
I implemented passing
FTP.transfercmdin aa30554c49ad6719fed1b6f5bcd690690f8fd37c and 86d652d1aa23642e188f25c4e7224c134b92aa18, d21af13815e4eb7f61c10c7e883e221c0eedc801. The documentation update is in 15a349e3f75a055e1fcd48f2570169c185ce12af.
The documentation contains the following caveat:
If you pass
restvalues which point after the file, the behavior is undefined and may even differ from one FTP server to another. Therefore, use the
restargument only for error recovery in case of interrupted transfers. You need to keep track of the transferred data so that you can provide a valid
restargument for a resumed transfer.