python ftplib storbinary in loop writes empty file

141 Views Asked by At

For a planned stress test, I am trying to write the same file to an FTP server using a loop which store files with different names obtained by a counter includes in filenames.

The program works fine only for the first file. All the others has been created, but are empty.

Below there is my code:

from ftplib import FTP
from cred import *

# Script for streestest

ftp_conn = FTP()

ftp_conn.connect(host=hostname, port=21)

ftp_conn.login(user=username, passwd=password)

counter = 0

# Testfile must exist!

try:
    file = open(file='./testfile', mode='rb')
    for i in range(10):
        filename = f'testfile{i+1}'
        ftp_conn.storbinary(cmd=f'STOR /stresstest/{filename}', fp=file)
        print(f'wrote file: {filename}')
        counter += 1

except FileNotFoundError:
    print('File does not exist!')

ftp_conn.quit()

print(f'Written {counter} files to {ftp_conn.host}')

Thank You!

1

There are 1 best solutions below

0
User051209 On

Open and close the file for every test upload

You have to do 2 corrections to your code:

  • open the file inside the for loop
  • after the upload to the server FTP (STOR command) close the file testfile

The correct code is (I have tested it on my system):

from ftplib import FTP

# Script for streestest
ftp_conn = FTP()
ftp_conn.connect(host=hostname, port=21)
ftp_conn.login(user=username, passwd=password)

counter = 0

# Testfile must exist!
try:
    # move the open() inside the for loop
    #file = open(file='./testfile', mode='rb')  # <---- comment this instruction
    for i in range(10):
        file = open(file='./testfile', mode='rb')
        filename = f'testfile{i+1}'
        ftp_conn.storbinary(cmd=f'STOR /stresstest/{filename}', fp=file)
        print(f'wrote file: {filename}')
        counter += 1
        # close the file
        file.close()        # <----------- Add this close()

except FileNotFoundError:
    print('File does not exist!')

ftp_conn.quit()

print(f'Written {counter} files to {ftp_conn.host}')

Use a context manager

An other way is to use a context manager as in the followed code:

from ftplib import FTP

# Script for streestest
ftp_conn = FTP()
ftp_conn.connect(host=hostname, port=21)
ftp_conn.login(user=username, passwd=password)

counter = 0

# Testfile must exist!
try:
    for i in range(10):
        with open('./testfile', 'rb') as file:   # <---- here there is the context manager that opens the file
            filename = f'testfile{i+1}'
            ftp_conn.storbinary(cmd=f'STOR /stresstest/{filename}', fp=file)
            print(f'wrote file: {filename}')
            counter += 1

except FileNotFoundError:
    print('File does not exist!')

ftp_conn.quit()

print(f'Written {counter} files to {ftp_conn.host}')

By a context manager the file is closed automatically.

This post recommends the use of context manager, and starts with the following sentence:

It is strongly advised to use a context manager. As an advantage, it is made sure the file is always closed, no matter what...