0

I have subclassed ftplib.FTP in order to download some xml files from a FTP server. I have used FTP.retrbinary with Path.write_bytes as callback. Script run successfully but xml files are smaller in size and not readeble by any browser or ET.parse. I have tried on a different server with mp4 file and they are not readable. When I use write method on the file object returned by open in binary mode, it works with xml and mp4.

I am using py3.5 on windows 2008/7 environment and then on linux with an Internet FTP server. I have first tried with FTP.retrlines but xml file have very long lines and I prefer not to change FTP.maxline. And I suspect I have same problem.

class MyFTP(ftplib.FTP): ... def saveFile1(self, filePath: Path): # It corrupts files!! command = "RETR " + str(filePath)

    callback = filePath.write_bytes

    try:
        self.retrbinary(command, callback)
    except ftplib.all_errors:
        raise MyException('File retrieval failed.')

def saveFile2(self, filePath: Path): # this works 
    command = "RETR " + str(filePath)

    fileName = str(filePath)
    fd = open(fileName, 'wb')
    callback = fd.write

    try:
        self.retrbinary(command, callback)
    except ftplib.all_errors:
        raise MyException('File retrieval failed.')

I prefer using Path for OS portability instead of file object ... in any case, is it a library bug or is there something I am missing? Thanks in advance

agossino
  • 21
  • 3
  • Each call to `Path.write_bytes()` reopens the file, and overwrites any previous contents - so you're only ending up with the final chunk of the data. This is simply not a workable method for receiving streaming data. – jasonharper Jun 15 '19 at 21:40

1 Answers1

0

Thanks to @jasonharper. Python doc in Lib/pathlib.py states: "Path.write_bytes(data) Open the file pointed to in bytes mode, write data to it, and close the file:"

So it is opened each time. open(... 'wb') uses io.BufferedIOBase.

agossino
  • 21
  • 3