-1

I have this code to access and download a file via python.

# Import Module
import ftplib
 
# Fill Required Information
HOSTNAME = "xxx"
USERNAME = "xxx"
PASSWORD = "xxx"
 
# Connect FTP Server
ftp_server = ftplib.FTP(HOSTNAME, USERNAME, PASSWORD)
 
# force UTF-8 encoding
ftp_server.encoding = "utf-8"
 
# Enter File Name with Extension
filename = "gfg.txt"
 
# Write file in binary mode
with open(filename, "wb") as file:
    # Command for Downloading the file "RETR filename"
    ftp_server.retrbinary(f"RETR {filename}", file.write)
 
# Get list of files
ftp_server.dir()
 
# Display the content of downloaded file
file= open(filename, "r")
print('File Content:', file.read())
 
# Close the Connection
ftp_server.quit()

Now I have these 2 questions.

1.How can I download a file inside the ftp that is inside a directory. It can download I suppose the script but just from root how can I modify the code to access a subdirectory inside the FTP

2.-I tried to download a file in .zip from root of a FTP and I received the next error message:

UnicodeDecodeError: 'charmap' codec can't decode byte 0x8f in position 12: character maps to <undefined>

What could be the problem in the code?

Thank you

I just tried the code like it is. I did not change anything yet.

alex1290
  • 17
  • 4
  • 1. Navigate inside the directory, see `CWD` FTR command; 2. You've opened `.zip` as a text file, not binary file (`r` vs `rb`), hence it assumes that it has some encoding (utf-8 in your case by default). It does not. Open it as a binary file and read bytes, not strings. – yeputons Dec 15 '22 at 19:12
  • You use `ftp_server.cwd` to change the current directory. And since you are reading binary files, you need to use `file = open(filename, 'rb')`, just like you used `wb` to write the file. – Tim Roberts Dec 15 '22 at 19:12
  • One question per post please! – Martin Prikryl Dec 16 '22 at 07:47

1 Answers1

0

(1.) inside a directory

Use / forward slashes, rather than \ backwhacks:

filename = "some/remote/directory/gfg.txt"

Or issue an FTP cd command to chdir to the remote directory.


(2.) UnicodeDecodeError

You mentioned "download", but that part looks suitably binary. I assume the error occurred when you read back the local copy. Use rb binary mode:

file= open(filename, "rb")
content = file.read()

That will retrieve binary content bytes, which won't necessarily print nicely. But you can uncompress / unzip them.


Consider using ftptool.

J_H
  • 17,926
  • 4
  • 24
  • 44
  • Oh I see the point 2 with rb worked perfect. But the route it doesn’t work I have a file in this route and it says this error: FileNotFoundError: [Errno 2] No such file or directory: 'Outbound/Inventory/Inventory_Full.20221215.111547.57093fa55baf44f0bb9b9ef6f2dcb4b6.csv' – alex1290 Dec 15 '22 at 19:35
  • It's worth noting that remote path and local path can be different, and might use different forward/backward `/` slashes. I recommend this: `from pathlib import Path`. Then you can say `path = Path(filename)`, and `path.name` will give just the _last_ component, with no directory prefix. You might find that simpler to work with. – J_H Dec 15 '22 at 19:43
  • If you're unclear on remote pathname spellings, use .dir(), perhaps after .cd("foo"), or use .dir("foo") – J_H Dec 15 '22 at 19:45
  • I solved adding this line before the filename: “ ftp_server.cwd('/Outbound/Inventory/')” And worked. THank you for the help. – alex1290 Dec 15 '22 at 20:04