I have a ftp client developed with python. When I specify a file in the current directory, it is successfully uploading. I want to specify a different directory except the current directory. How could I modify this code?
from ftplib import FTP
ftp = FTP('')
ftp.connect("127.0.0.1", 1026)
ftp.login()
ftp.retrlines('LIST')
def uploadFile():
filename = "f.txt" #replace with your file in your home folder
ftp.storbinary('STOR '+filename, open(filename, 'rb'))
print(ftp.storbinary)
ftp.quit()
print("filename",filename,"uploaded to server")
uploadFile()
Here I want to specify this directory to select files C:\Users\User\Desktop\nnn.
Please any help would be highly appreciated.
Put the directory prefix in the path when calling open():
ftp.storbinary('STOR ' + filename, open(os.path.join(r'C:\Users\User\Desktop\nnn', filename), 'rb'))
You can set filename like this way
ftp.storbinary('STOR {0}.mrss'.format("Your file name"), file)
Related
Using "ftplib" Python package, I connect to a host, post which I send a binary file using "storbinary: function to this directory. However, the file transfer does not happen, the source file is over-written and made 0 bytes
Tried using "cwd" within ftplib to change to destination directory before uploading file.
Tried 'rsync' on the command line which works fine (thus establishing file integrity).
print ('Establishing FTP connection')
ftp = FTP(dest_dir, 'user', 'password')
print '+++++', ftp.pwd()
ftp.cwd(dest_dir)
print 'work dir now', ftp.pwd()
ftp.retrlines('LIST')
f_name = /home/test/file_to_upload
with open(f_name, 'rb') as cfile:
ftp.storbinary('STOR %s' % f_name, cfile)
ftp.quit()
The file: /home/test/file_to_upload should be uploaded to dest_dir, instead it is getting over-written and also becomes an empty file, i.e. file contents are erased
f_name contains directory of your local system. Try to extract the filename only. Also be careful adding a space between ‘STOR’ and ‘filename’
Example:
ftp.storbinary('STOR '+ os.path.basename(f_name), open(f_name, 'rb'))
I want to download files from an FTP server and archive them locally in a (zip) archive.
It is well known how to download files and save them individually:
import ftplib
remote = ftplib.FTP(ftp_server)
remote.login(username, password)
for filename in file_list:
remote.retrbinary("RETR " + filename, open(filename, 'wb').write)
remote.quit()
It is also well known how to add files to an archive:
import zipfile
archive = zipfile.ZipFile(archive_file)
archive.write(filename)
archive.close()
But it seems not possible to use both at the same time:
remote.retrbinary("RETR " + filename, archive.write(filename))
This leads to a FileNotFoundError, because filename has not been saved to a local (temporary) directory in between.
Is there a way to directly send the file stream from FTP into a zip archive? Or would it be more efficient to download all files straight, add them to the archive, and then delete the files? I would like to keep harddisk I/O as low as possible.
Download the file to memory and use ZipFile.writestr:
import ftplib
import zipfile
from io import BytesIO
# ...
archive = zipfile.ZipFile(archive_file, "w")
for filename in file_list:
flo = BytesIO()
ftp.retrbinary('RETR ' + filename, flo.write)
archive.writestr(filename, flo.getvalue())
archive.close()
I'm trying to upload all my files to a time_name directory (such as "170905_161330") in my ftp server.
# -*- coding:utf-8 -*-
import ftplib
import os
import datetime
CWD = os.getcwd()
NOW_STR = str(datetime.datetime.now())
LOCAL_STR = "HDD1/AutoBackUp/" + NOW_STR[2:4]+NOW_STR[5:7]+NOW_STR[8:10]+"_"+NOW_STR[11:13]+NOW_STR[14:16]+NOW_STR[17:19]+"/"
FTP_ADDRESS = 'FTP_ADDRESS'
FTP_ID = '1'
FTP_PW = '1'
ftp = ftplib.FTP(FTP_ADDRESS, FTP_ID, FTP_PW)
for i in os.listdir(CWD):
FILENAME = str(i)
print(FILENAME)
ftp.mkd(LOCAL_STR)
LOCAL_NAME = LOCAL_STR + FILENAME
print(str(LOCAL_NAME))
with open(FILENAME, 'rb') as fileOBJ:
ftp.storlines('STOR ' + str(LOCAL_NAME), fileOBJ)
ftp.quit()
But the error
ftplib.error_perm: 550 HDD1/AutoBackUp/170905_160635/: Directory not empty
continues to appear, while the first file is uploaded correctly. After that, it doesn't work.
I can check my first file in ftp server, but yeah. second file doesn't exist.
I guess... storlines function only works when upload folder is empty.
How can I solve this problem?
From a very rapid read of your code, I suspect that the problem is in ftp.mkd. You already created the directory at the first iteration of the for loop.
To test this error on your local system, open the terminal:
write a mkdir test command
write a mkdir test again
You'll see an error: File Exist. I think the directory not empty is gnerated from this error in the server.
Modify your code to put ftp.mkd before the for loop:
ftp.mkd(LOCAL_STR)
for i in os.listdir(CWD):
FILENAME = str(i)
print(FILENAME)
LOCAL_NAME = LOCAL_STR + FILENAME
print(str(LOCAL_NAME))
with open(FILENAME, 'rb') as fileOBJ:
ftp.storlines('STOR ' + str(LOCAL_NAME), fileOBJ)
ftp.quit()
and test it again. Please remember to remove the directory from the server before testing it.
The script below is able to read the files in the ftp directory file however it does not download them. I know they read them because the outputted list in the command window shows them.
from ftplib import FTP
import os, sys, os.path
def handleDownload(block):
file.write(block)
ddir='U:/Test Folder'
os.chdir(ddir)
ftp = FTP('sidads.colorado.edu')
ftp.login()
print ('Logging in.')
directory = '/pub/DATASETS/NOAA/G02158/unmasked/2012/04_Apr/'
print ('Changing to ' + directory)
ftp.cwd(directory)
ftp.retrlines('LIST')
print ('Accessing files')
for subdir, dirs, files in os.walk(directory):
for file in files:
full_fname = os.path.join(root, fname);
print ('Opening local file ')
ftp.retrbinary('RETR U:/Test Folder' + fname,
handleDownload,
open(full_fname, 'wb'));
print ('Closing file ' + filename)
file.close();
ftp.close()
Here is one way you can do this using the pysftp library:
import pysftp
with pysftp.Connection('hostname', username='username', password='password') as sftp:
ftp_files = sftp.listdir('/ftp/dir/')
for file in ftp_files:
sftp.get(os.path.join('/ftp/dir/', file), localpath=os.path.join('/path/to/save/file/locally/', file))
So far I have the gotten the names of the files I need from the FTP site. See code below.
from ftplib import FTP
import os, sys, os.path
def handleDownload(block):
file.write(block)
ddir='U:/Test Folder'
os.chdir(ddir)
ftp = FTP('sidads.colorado.edu')
ftp.login()
print ('Logging in.')
directory = '/pub/DATASETS/NOAA/G02158/unmasked/2012/04_Apr/'
print ('Changing to ' + directory)
ftp.cwd(directory)
ftp.retrlines('LIST')
print ('Accessing files')
filenames = ftp.nlst() # get filenames within the directory
print (filenames)
Where I am running into trouble is the download of the files into a folder. The code below is something I have tried however I receive the permission error due to the file not being created before I write to it.
for filename in filenames:
local_filename = os.path.join('C:/ArcGis/New folder', filename)
file = open(local_filename, 'wb')
ftp.retrbinary('RETR '+ filename, file.write)
file.close()
ftp.quit()
Here is the error and callback.
The directory listing includes the . reference to the folder (and probably also .. reference to the parent folder).
You have to skip it, you cannot download it (them).
for filename in filenames:
if (filename != '.') and (filename != '..'):
local_filename = os.path.join('C:/ArcGis/New folder', filename)
file = open(local_filename, 'wb')
ftp.retrbinary('RETR '+ filename, file.write)
file.close()
Actually you have to skip all folders in the listing.