3

i looked around for this error, but all I could really find is similar mismatch errors for python 3.3 support. I originally was getting errors when trying to use a *.txt wildcard to put all files in the localpath to the remotepath, kept getting file does not exist errors... so i finally just tried this with a single file, and got this:

size mismatch in put! 0 != 14911

Here is the code, along with python info, running linux mint 13 maya. Im really new to python and this module, and new to programming period. So dont assume i know what you are talking about....=P

Python 2.7.3 (default, Apr 20 2012, 22:39:59) [GCC 4.6.3] on linux2

import pysftp as sftp


def putjob():
    try:
        s = sftp.Connection(host='secure.sftp.site', username='username', password='password')

        remotepath='/Home/xxx24659/Upload/'
        localpath='/home/xxx24659/Local/Upload/Q0001.txt'
        s.put(localpath,remotepath)

        s.close()

    except Exception, e:
        print str(e)

putjob()
Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
Dogbyte
  • 99
  • 2
  • 10
  • 1
    maybe the `remotepath` should be filename such as `/Home/xxx24659/Upload/Q0001.txt` not directory. additionally, make sure that remote directory actually exists. – ymonad May 15 '14 at 00:49
  • 1
    @ymonad yes that was it... never used this module, i was assuming that it needed a path to the directory, not like a cp command. ive got to find a way to copy *.txt from the local path to the remotepath, but thank you, that was it! – Dogbyte May 15 '14 at 01:06
  • ive read through their documentation, and although i dont know what a flo is, im not sure if i can copy the entire contents of a folder containing txt files, up to the Upload folder and retain their unique names. is this possible with pysftp? – Dogbyte May 15 '14 at 01:11
  • according to the `pysftp`'s source code, it's just a small wrapper of `paramiko`, and unfortunately there does not seem to have functionality to send entire content in directory. so you must implement by your own. However it won't be difficult task, there are some sample codes here http://stackoverflow.com/questions/4409502/directory-transfers-on-paramiko – ymonad May 15 '14 at 01:25
  • ok thanks for the link... too bad this pysftp wont meet my needs, i had finally got a finger on it... py is really the first lang ive gone very far with. i dont know enough with bash to be able to script what i want to do... i really just need to put all local files to a sftp folder, then get all files from a remote folder to a local folder. then i'll automate it with cron, and be done. – Dogbyte May 15 '14 at 02:39
  • Yes, maybe using `bash` and `sftp` might fit your need, However, this conversation in comment is getting a little bit off topic, so you should post another question if you want to use `bash` instead of python. – ymonad May 15 '14 at 02:51
  • Related question: [“IOError: size mismatch in get!” when retrieving files via SFTP](https://stackoverflow.com/q/53945594/850848). – Martin Prikryl Nov 27 '20 at 07:56

2 Answers2

1

ymonad had it correct, pysftp was returning the size of the directory entry as requested.

You are correct, that pysftp does not do recursive directory copying currently. However, there is an issue for it in the tracker, so you can vote for it.

https://bitbucket.org/dundeemt/pysftp/issue/10/remote-walkdirs

or roll your own and send a pull request!

Dundee MT
  • 1,229
  • 1
  • 10
  • 5
0

The problem may be caused due to synchronicity issues between your file-system and the remote file-system as described for a similar issue regarding the Paramiko get-function here.

As pysftp is a Paramiko-wrapper the error message you receive is being thrown by the Paramiko-engine, I guess specifically on line 722 of the Paramiko sftp_client.py raise IOError(:

    with self.file(remotepath, "wb") as fr:
        fr.set_pipelined(True)
        size = self._transfer_with_callback(
            reader=fl, writer=fr, file_size=file_size, callback=callback
        )
    if confirm:
        s = self.stat(remotepath)
        if s.st_size != size:
            raise IOError(
                "size mismatch in put!  {} != {}".format(s.st_size, size)
            )
    else:
        s = SFTPAttributes()
    return s

To solve this problem I guess you have to get the file-size using the file-object during file-handling implementing the tell-function in the Paramiko putfo-function (to be found here on line 687) in order to change the underlying Paramiko-code that pysftp is using accordingly:

with self.file(remotepath, "wb") as fr:
    fr.set_pipelined(True)
    remotesize = fr.tell()
    size = self._transfer_with_callback(
        reader=fl, writer=fr, file_size=file_size, callback=callback
    )
if confirm:
    if remotesize != size:
        raise IOError(
            "size mismatch in put!  {} != {}".format(remotesize, size)
        )
else:
    s = SFTPAttributes()
return s

I would be very interested to hear from you if my suggestion can solve your problem as it did for me regarding the Paramiko get-function.

Furthermore, next time you have an issue it would be beneficial to also post the whole error-message in order to check where it originated specifically.