# FTP Client Speed via Scripting

**URL:** <https://forum.inductiveautomation.com/t/ftp-client-speed-via-scripting/26620>\
**Category:** Ignition\
**Tags:** scripting\
**Created:** [July 17, 2019, 12:58pm UTC](https://forum.inductiveautomation.com/t/ftp-client-speed-via-scripting/26620 "2019-07-17T12:58:10Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![r.huisken](https://avatars.discourse-cdn.com/v4/letter/r/47e85d/32.png) [@r.huisken](https://forum.inductiveautomation.com/u/r.huisken)\
**Post date:** [July 17, 2019, 12:58pm UTC](https://forum.inductiveautomation.com/t/ftp-client-speed-via-scripting/26620/1 "2019-07-17T12:58:10Z")

</div>

I am connecting to HMI’s and robots using python ftplib. I am able to upload/download files. The files are typically less than 10KB, the biggest is about 150KB. The problem I have is it takes about 4.5 seconds per ftp request whether that is connecting, getting a list of files, or downloading a file. If I run it as a python script outside Ignition, one of these operations takes less than 300ms. Is there something I can do to improve the performance?

Here’s an example of my functions for connecting, getting the list of files, and downloading:

```auto
# Create the ftp connection to the robot
# return that ftp handle
def createConnection(robotIp, robotUsername, robotPassword):
	try:
		ftp = ftplib.FTP(robotIp, robotUsername, robotPassword)
		ftp.login()
		return ftp
	except Exception, ex:
		print("Error connecting to %s : %s" % (robotIp, str(ex)))
		return None
		
# Get the list of files of each file type then
# return the list of files
def getBackupFileList(ftp):
	files = []
	fileTypes = ["*.JBI", "*.DAT", "*.CND", "*.LST"]
	for fileType in fileTypes:
		print(fileType)
		command = 'LIST %s' % (fileType)
		ftp.retrlines(command, files.append)
	for i in range(len(files)):
		files[i] = files[i].replace(files[i][0:54], '')
	return files
	
# Save the file specified by fileName in the specified folder
def downloadFile(ftp, fileName, folder):
	saveFilePath = os.path.join(folder, fileName)
	try:
		file = open(saveFilePath, 'w')
		def writeLine(data):
			file.write(data + '\n')
		ftp.retrlines('RETR ' + fileName, writeLine)
		file.close()
	except Exception, ex:
		print("Error downloading %s : %s" % (fileName, str(ex)))

```

---

<div class="post-metadata">

**Author:** ![jlivingston](https://avatars.discourse-cdn.com/v4/letter/j/779978/32.png) [@jlivingston](https://forum.inductiveautomation.com/u/jlivingston)\
**Post date:** [July 17, 2019, 1:21pm UTC](https://forum.inductiveautomation.com/t/ftp-client-speed-via-scripting/26620/2 "2019-07-17T13:21:44Z")

</div>

There is a knowledgebase article which goes into PC performance parameters as a solution for problems in the timing. Much of it has to do with the type of storage that you are using ( physical storage, as in things that you point to- RAM and or Hard Disk and or Solid State Disk Drive ) and various cache settings. It is oriented toward that error message folks receive if they are not using the correct Time Server parameters. That said, a script file is using what experts call a ‘high-level’ or ‘more complex’ language to access the inner workings ( hardware ). FTP is also far away from Assembly Language or Machine Language. If you need a ‘faster answer’ to your quest for better response time, other users have suggested that you visit the support page ( which also includes the knowledgebase as a menu choice at entry ). I recommend you read the support policies first, because voice support is generally best if you have an account. Non-priority e-mail is free ( for now ). Try the following to get to support at IA : [https://support.inductiveautomation.com](https://support.inductiveautomation.com) Thanks in advance for telling the rest of us what the result was and therefore we may learn something also.

---

<div class="post-metadata">

**Author:** ![jlivingston](https://avatars.discourse-cdn.com/v4/letter/j/779978/32.png) [@jlivingston](https://forum.inductiveautomation.com/u/jlivingston)\
**Post date:** [July 17, 2019, 1:55pm UTC](https://forum.inductiveautomation.com/t/ftp-client-speed-via-scripting/26620/3 "2019-07-17T13:55:35Z")

</div>

Here is more on that KnowledgeBase:  
there is a Knowledgebase article by Anna Christian entitled “ClockDriftDetector warnings in the Gateway Console” posted 07/21/2016 08:11 A.M.  
There are also some diagnostic tools to be found regarding speed / performance in a recent post regarding Azure/VM migration. I am always a bit nervous when it comes to the 3-finger salute ( Control-Alt-Delete ) which is a shortcut to Task Manager ( or mangler, as you prefer ).

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [July 17, 2019, 3:20pm UTC](https://forum.inductiveautomation.com/t/ftp-client-speed-via-scripting/26620/4 "2019-07-17T15:20:12Z")

</div>

I think we’ve seen others report this as well. The Jython stdlib’s FTP and other networking-related functions are really slow for some reason. I don’t know if there was ever a solution though.

---

<div class="post-metadata">

**Author:** ![r.huisken](https://avatars.discourse-cdn.com/v4/letter/r/47e85d/32.png) [@r.huisken](https://forum.inductiveautomation.com/u/r.huisken)\
**Post date:** [July 17, 2019, 3:39pm UTC](https://forum.inductiveautomation.com/t/ftp-client-speed-via-scripting/26620/5 "2019-07-17T15:39:52Z")

</div>

> I think we’ve seen others report this as well. The Jython stdlib’s FTP and other networking-related functions are really slow for some reason. I don’t know if there was ever a solution though.

If that's the case, then any opinions on what would be the best way to trigger some external method of running the FTP functions? For this particular operation, I would like to be able to pass in the settings for an HMI/robot, let it download the files to the HDD, then notify if there were any problems.

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [July 17, 2019, 3:50pm UTC](https://forum.inductiveautomation.com/t/ftp-client-speed-via-scripting/26620/6 "2019-07-17T15:50:58Z")

</div>

One option (that a few people on the forum have reported as working much better) is switching to Java’s built in classes, rather than using FTPLib; there are lots of examples online of Java code to make an FTP connection, and it’s usually not too complicated to port Java code into Jython.

---

<div class="post-metadata">

**Author:** ![r.huisken](https://avatars.discourse-cdn.com/v4/letter/r/47e85d/32.png) [@r.huisken](https://forum.inductiveautomation.com/u/r.huisken)\
**Post date:** [July 18, 2019, 11:27pm UTC](https://forum.inductiveautomation.com/t/ftp-client-speed-via-scripting/26620/7 "2019-07-18T23:27:58Z")

</div>

Thank you for the suggestions. Using PGriffith’s suggestion I was able to use the java libraries and reduce the time to download a batch of files from 4.5 minutes to 11.5 seconds. For anyone use who is curious, here’s a chunk of what I came up with:

```auto
import os
from java.net import URL
from java.net import URLConnection
from java.io import BufferedReader
from java.io import InputStream
from java.io import InputStreamReader

def getInputStream(robotController, path):
	ftpUrl = "ftp://%s:%s@%s/%s" % (robotController[2], robotController[3], robotController[1], path)
	url = URL(ftpUrl)
	urlConnection = url.openConnection()
	inputStream = urlConnection.getInputStream()
	return inputStream

def downloadFile(robotController, fileName, folder):
	inputStream = getInputStream(robotController, fileName)
	
	streamReader = InputStreamReader(inputStream)
	reader = BufferedReader(streamReader)
	
	fileData = []
	line = reader.readLine()
	while line != None:
		fileData.append(line)
		line = reader.readLine()
	inputStream.close()
	
	saveFilePath = os.path.join(folder, fileName)
	try:
		file = open(saveFilePath, 'w')
		for line in fileData:
			file.write("%s\n" % (line))
		file.close()
	except Exception, ex:
		writeMessage("Error writing %s : %s" % (fileName, str(ex)))

```

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [July 18, 2019, 11:36pm UTC](https://forum.inductiveautomation.com/t/ftp-client-speed-via-scripting/26620/8 "2019-07-18T23:36:41Z")

</div>

> [@r.huisken](#):
>
> 4.5 minutes to 11.5 seconds

_Dang!_ We really should try and figure out why Jython's FTPLib is so miserably slow - but kudos for figuring it out, and posting it back here!

---

<div class="post-metadata">

**Author:** ![r.huisken](https://avatars.discourse-cdn.com/v4/letter/r/47e85d/32.png) [@r.huisken](https://forum.inductiveautomation.com/u/r.huisken)\
**Post date:** [July 19, 2019, 1:59pm UTC](https://forum.inductiveautomation.com/t/ftp-client-speed-via-scripting/26620/9 "2019-07-19T13:59:43Z")

</div>

I spoke too soon. I had problems with the java.net.URLConnection and connecting to older generations of robots. Now I’m attempting to use the apache commons ftp library. I put the commons-net-3.6.jar in lib/core/gateway and /lib/core/common and restarted the gateway. Then in the script console, I’m trying the following:

```auto
from org.apache.commons.net.ftp import FTPClient

robotIp = "192.168.10.20"

ftp = FTPClient()
ftp.connect(robotIp)
reply = ftp.getReplyCode()
print(reply)

```

I get the error : ImportError:  
Traceback (most recent call last):  
File “”, line 1, in  
ImportError: No module named net

I’m not a java developer so forgive my unfamiliarity with jar’s and jar.pack.gz. Any guesses at what I’m doing wrong?

---

<div class="post-metadata">

**Author:** ![John\_S1](https://avatars.discourse-cdn.com/v4/letter/j/c0e974/32.png) [@John\_S1](https://forum.inductiveautomation.com/u/John_S1)\
**Post date:** [December 5, 2024, 4:49am UTC](https://forum.inductiveautomation.com/t/ftp-client-speed-via-scripting/26620/10 "2024-12-05T04:49:37Z")

</div>

Hello people,  
I know this is an old thread, but has somebody found some resolution for the FTP-based issue?  
Are there any new built-in functions from Ignition to use the Apache library?  
what will be the alternative or somebody found some other methods?

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [December 5, 2024, 4:43pm UTC](https://forum.inductiveautomation.com/t/ftp-client-speed-via-scripting/26620/11 "2024-12-05T16:43:43Z")

</div>

No, there's nothing new built in to Ignition ~~because we don't have any first party functionality that needs FTP~~ and, generally, there hasn't been enough demand to warrant it.

The 'drop a jar into the lib/ directory' approach is still going to be the easiest/cheapest way to get this working. Building a module that presents a `system.ftp` namespace would also be very doable.

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [December 5, 2024, 4:44pm UTC](https://forum.inductiveautomation.com/t/ftp-client-speed-via-scripting/26620/12 "2024-12-05T16:44:32Z")

</div>

> [@paul-griffith](#):
>
> because we don't have any first party functionality that needs FTP

Reporting? It brings in ftp4j, though not accessible to scripting.

---

<div class="post-metadata">

**Author:** ![John\_S1](https://avatars.discourse-cdn.com/v4/letter/j/c0e974/32.png) [@John\_S1](https://forum.inductiveautomation.com/u/John_S1)\
**Post date:** [December 9, 2024, 4:34am UTC](https://forum.inductiveautomation.com/t/ftp-client-speed-via-scripting/26620/13 "2024-12-09T04:34:13Z")

</div>

Thanks. Let me try to have some modifications internally and will try to make it as a module.
