杰瑞科技汇

Python中retrbinary函数如何使用?

Of course! Let's dive deep into retrbinary in Python, which is a function from the popular ftplib module.

Python中retrbinary函数如何使用?-图1
(图片来源网络,侵删)

What is retrbinary?

retrbinary is a method used to retrieve a file from an FTP server in binary mode. It's part of Python's built-in ftplib library, which provides an interface to interact with FTP (File Transfer Protocol) servers.

The "binary" part is crucial. It means the file is transferred exactly as it is on the server, without any modifications. This is essential for non-text files like images, videos, compressed archives (.zip, .tar.gz), and executables.

When to Use retrbinary vs. retrlines

It's important to distinguish retrbinary from its counterpart, retrlines.

Feature retrbinary(conn, callback, blocksize=8192) retrlines(cmd, callback)
Purpose Retrieve a binary file (image, video, etc.). Retrieve a text file (.txt, .csv, .py).
Transfer Mode TYPE I (Image/Binary) TYPE A (ASCII)
Data Handling Receives raw bytes (bytes object). Receives decoded lines (str object).
Callback A function that accepts one argument: the data chunk (as bytes). A function that accepts one argument: a line of text (as str).
Line Endings Preserves original line endings (CR/LF). Translates FTP line endings (\r\n) to Python's (\n).

Rule of Thumb:

Python中retrbinary函数如何使用?-图2
(图片来源网络,侵删)
  • Use retrbinary for anything that isn't plain text.
  • Use retrlines for plain text files.

How to Use retrbinary: A Step-by-Step Guide

Here’s a complete, practical example of downloading a file from a public FTP server.

Step 1: Import the ftplib Module

import ftplib
import os

Step 2: Define a Callback Function

The callback function is the heart of the retrbinary operation. It gets called repeatedly by the FTP library as chunks of the file are downloaded from the server. You use this function to write the data to a local file.

A simple callback looks like this:

def write_data(data):
    """Callback function to write the downloaded data to a file."""
    # The 'wb' mode in open() is important for binary data
    with open("downloaded_file.jpg", "ab") as f: # 'ab' for append in binary mode
        f.write(data)

Explanation:

Python中retrbinary函数如何使用?-图3
(图片来源网络,侵删)
  • The ftplib passes a chunk of data (as bytes) to this function each time it's received.
  • We open the file in "ab" (append binary) mode. We use "ab" instead of "wb" (write binary) because retrbinary will call this function multiple times for each chunk of the file. If we used "wb", it would overwrite the file on every call, resulting in only the last chunk being saved.

Step 3: Connect to the FTP Server and Perform the Download

Let's download a sample image file from the test.rebex.net public FTP server.

# --- Main Execution ---
if __name__ == "__main__":
    # FTP server details (a public one for testing)
    ftp_host = "ftp.test.rebex.net"
    ftp_user = "demo"
    ftp_pass = "password"
    # The file we want to download
    remote_filename = "screenshot.png"
    local_filename = "downloaded_screenshot.png"
    try:
        # 1. Connect to the FTP server
        print(f"Connecting to {ftp_host}...")
        with ftplib.FTP(ftp_host, ftp_user, ftp_pass) as ftp:
            print("Connection successful.")
            # 2. Check if the remote file exists (optional but good practice)
            if remote_filename in ftp.nlst():
                print(f"File '{remote_filename}' found on the server.")
            else:
                print(f"File '{remote_filename}' not found on the server.")
                exit()
            # 3. Open the local file in write-binary mode
            # We do this here to ensure it's created fresh for this download.
            with open(local_filename, "wb") as local_file:
                # 4. Define the callback to write to our local file
                def write_callback(data_chunk):
                    local_file.write(data_chunk)
                # 5. Execute the RETR command
                print(f"Starting download of '{remote_filename}'...")
                # The command is 'RETR <filename>'
                ftp.retrbinary(f"RETR {remote_filename}", write_callback)
                print(f"Download complete. File saved as '{local_filename}'.")
    except ftplib.all_errors as e:
        print(f"An FTP error occurred: {e}")
    except Exception as e:
        print(f"An unexpected error occurred: {e}")

Breakdown of the retrbinary Call

ftp.retrbinary(f"RETR {remote_filename}", write_callback, blocksize=8192)
  1. f"RETR {remote_filename}": This is the FTP command string. RETR stands for "retrieve." The FTP server understands this command as "please send me the file named {remote_filename}."
  2. write_callback: This is the function that will be executed for each chunk of data received. It's the "callback" part of the function name.
  3. blocksize=8192 (Optional): This parameter specifies the size of the data chunks (in bytes) that the server should send. The default is 8192 bytes (8 KB), which is generally a good value. You can adjust it for performance if needed, but it's rarely necessary.

Complete, Runnable Example

Here is the full code from above, which you can save as a Python file and run. It will download screenshot.png from a public server.

import ftplib
import os
def download_file_from_ftp(host, user, password, remote_filename, local_filename):
    """
    Downloads a file from an FTP server in binary mode.
    Args:
        host (str): The FTP server hostname or IP address.
        user (str): The FTP username.
        password (str): The FTP password.
        remote_filename (str): The name of the file on the FTP server.
        local_filename (str): The name to save the file locally.
    """
    try:
        print(f"Connecting to {host}...")
        with ftplib.FTP(host, user, password) as ftp:
            print("Connection successful.")
            # Check if the remote file exists
            files = ftp.nlst()
            if remote_filename not in files:
                print(f"Error: File '{remote_filename}' not found on the server.")
                return
            # Open the local file in write-binary mode
            # The 'with' statement ensures the file is properly closed
            with open(local_filename, "wb") as local_file:
                print(f"Starting download of '{remote_filename}'...")
                # Define the callback function to write data chunks to the local file
                def write_callback(data):
                    local_file.write(data)
                # Execute the RETR command
                ftp.retrbinary(f"RETR {remote_filename}", write_callback)
            print(f"Download complete. File saved as '{local_filename}'.")
    except ftplib.all_errors as e:
        print(f"An FTP error occurred: {e}")
    except FileNotFoundError:
        print(f"Error: Local path for saving '{local_filename}' is invalid.")
    except Exception as e:
        print(f"An unexpected error occurred: {e}")
# --- Main execution block ---
if __name__ == "__main__":
    # Using a public FTP server for demonstration
    FTP_HOST = "ftp.test.rebex.net"
    FTP_USER = "demo"
    FTP_PASS = "password"
    REMOTE_FILE = "screenshot.png"
    LOCAL_FILE = "my_downloaded_image.png"
    download_file_from_ftp(FTP_HOST, FTP_USER, FTP_PASS, REMOTE_FILE, LOCAL_FILE)

After running this script, you will find a file named my_downloaded_image.png in the same directory.

分享:
扫描分享到社交APP
上一篇
下一篇