# FTP Text File from server

**URL:** <https://forum.inductiveautomation.com/t/ftp-text-file-from-server/84891>\
**Category:** Ignition\
**Tags:** perspective\
**Created:** [January 29, 2024, 2:18pm UTC](https://forum.inductiveautomation.com/t/ftp-text-file-from-server/84891 "2024-01-29T14:18:21Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![dis](https://avatars.discourse-cdn.com/v4/letter/d/e99b99/32.png) [@dis](https://forum.inductiveautomation.com/u/dis)\
**Post date:** [January 29, 2024, 2:18pm UTC](https://forum.inductiveautomation.com/t/ftp-text-file-from-server/84891/1 "2024-01-29T14:18:21Z")

</div>

I am creating a gateway script that will download a text file from a corporate server. The text file is small only a few KBs. I'm not a Python/Java programmer so this is a bit foreign to me.

I started with the built-in FTPlib which would allow me to transfer the file but while the script would complete almost immediately, it would be several minutes before data was in the text file.

Searching the forums [ftp-client-speed-via-scripting](https://forum.inductiveautomation.com/t/ftp-client-speed-via-scripting/26620/7) and online pointed me in the direction of using the java.net.urlconnection method. I found several examples of this and have it downloading the file in a few seconds.

Except, the file is "binary gibberish" not human readable text. I believe this has to do with InputStream but not sure where/how I need to convert it to human readable text.

```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

downloadFile("dwb.dat", "C:\\FILES\\")

def downloadFile(fileName, folder):
	inputStream = getInputStream("user", "password", "127.0.0.1", "usr/dwb.dwn")

	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')
		print saveFilePath
		for line in fileData:
			file.write("%s\n" % (line))
			print "%s\n" % (line)
		file.close()
		print "File Written"
	except Exception, ex:
		writeMessage("Error writing %s : %s" % (fileName, str(ex)))
	

def getInputStream(user, pwd, IP, filename):
	ftpUrl = "ftp://%s:%s@%s/%s" % (user, pwd, IP, filename)
	url = URL(ftpUrl)
	try:
		url.close()
	except:
		pass
		FTPConnection = url.openConnection()
		inputStream = FTPConnection.getInputStream()
		url.close()
		return inputStream

```

---

<div class="post-metadata">

**Author:** ![victordcq](https://avatars.discourse-cdn.com/v4/letter/v/f6c823/32.png) [@victordcq](https://forum.inductiveautomation.com/u/victordcq)\
**Post date:** [January 29, 2024, 3:45pm UTC](https://forum.inductiveautomation.com/t/ftp-text-file-from-server/84891/2 "2024-01-29T15:45:51Z")

</div>

> [@dis](#):
>
> ```auto
> url = URL(ftpUrl)
> try:
> url.close()
> except:
> pass
> FTPConnection = url.openConnection()
> inputStream = FTPConnection.getInputStream()
> url.close()
> return inputStream
> 
> ```

i guess this is just a copy paste isusue that the index is wrong?  
houls be this right?

```auto
    except:
		pass
FTPConnection = url.openConnection()
inputStream = FTPConnection.getInputStream()
url.close()
return inputStream

```

anyways i dont think you are supposed to close it before using the stream (?)

---

<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:** [January 29, 2024, 4:32pm UTC](https://forum.inductiveautomation.com/t/ftp-text-file-from-server/84891/3 "2024-01-29T16:32:40Z")

</div>

Adapted (moderately) from ChatGPT output, this function should work, if your original snippet worked at all:

```python
from java.io import ByteArrayOutputStream
from java.net import URL, URLConnection

def download_file(ftp_url, username, password, filename):
    url = URL("ftp://{}:{}@{}/{}".format(username, password, ftp_url, filename))
    conn = url.openConnection()
    conn.setDoInput(True)

	inputStream = conn.inputStream
	byteOutputStream = ByteArrayOutputStream()
    try:	
	    inputStream.transferTo(byteOutputStream)
    	return byteOutputStream.toByteArray()
    finally:
    	inputStream.close()
    	byteOutputStream.close()

# Usage
byte_array = download_file("ftp.example.com", "username", "password", "file.txt")
system.file.writeFile("path", byte_array)

```

The trick is to go "all in" on Java standard library stuff and avoid Jython's entirely, basically. That is, return a Java byte array instead of a Jython list, etc. The `transferTo` function is an interface default method that's "new" (as of Java 9) so lots of online resources aren't aware of it yet, but it automatically does a buffered transfer from an input stream to an output stream. I wrote the method to return a plain byte array because that gives you maximum flexibility; the builtin `system.file.writeFile` method can handle that byte array directly and write it out to an actual file.

---

<div class="post-metadata">

**Author:** ![dis](https://avatars.discourse-cdn.com/v4/letter/d/e99b99/32.png) [@dis](https://forum.inductiveautomation.com/u/dis)\
**Post date:** [January 29, 2024, 5:02pm UTC](https://forum.inductiveautomation.com/t/ftp-text-file-from-server/84891/4 "2024-01-29T17:02:21Z")

</div>

Yes. I picked up where I left of on Friday without cleaning up the code before posting.. That url.close() isn't supposed to be there.

---

<div class="post-metadata">

**Author:** ![dis](https://avatars.discourse-cdn.com/v4/letter/d/e99b99/32.png) [@dis](https://forum.inductiveautomation.com/u/dis)\
**Post date:** [January 29, 2024, 5:03pm UTC](https://forum.inductiveautomation.com/t/ftp-text-file-from-server/84891/5 "2024-01-29T17:03:46Z")

</div>

> [@paul-griffith](#):
>
> ```auto
> from java.io import ByteArrayOutputStream
> from java.net import URL, URLConnection
> 
> def download_file(ftp_url, username, password, filename):
> url = URL("ftp://{}:{}@{}/{}".format(username, password, ftp_url, filename))
> conn = url.openConnection()
> conn.setDoInput(True)
> 
> inputStream = conn.inputStream
> byteOutputStream = ByteArrayOutputStream()
> try:	
> inputStream.transferTo(byteOutputStream)
> return byteOutputStream.toByteArray()
> finally:
> inputStream.close()
> byteOutputStream.close()
> 
> # Usage
> byte_array = download_file("ftp.example.com", "username", "password", "file.txt")
> system.file.writeFile("path", byte_array)
> 
> ```

I will work with this. I did not think to try ChatGPT for this task. Thank you.

---

<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:** [January 29, 2024, 5:07pm UTC](https://forum.inductiveautomation.com/t/ftp-text-file-from-server/84891/6 "2024-01-29T17:07:47Z")

</div>

Be **very** careful with ChatGPT w.r.t. Ignition. It's not even close to good enough to be blindly trusted. In the very first answer I got, it gave me Java code and imported a third party library when I explicitly asked for Jython and the Java standard library. In the second answer, when coached, it still gave me an unnecessarily complicated answer that wasn't aware of the `transferTo` function. If I didn't already know what I was doing, I wouldn't have been able to 'coach' it through these things or fix the final snippet.

> **[ChatGPT](https://chat.openai.com/share/3ba93106-19cf-4ef3-9c0c-15c197281dd5)**
>
> A conversational AI system that listens, learns, and challenges

---

<div class="post-metadata">

**Author:** ![dis](https://avatars.discourse-cdn.com/v4/letter/d/e99b99/32.png) [@dis](https://forum.inductiveautomation.com/u/dis)\
**Post date:** [January 29, 2024, 5:17pm UTC](https://forum.inductiveautomation.com/t/ftp-text-file-from-server/84891/7 "2024-01-29T17:17:29Z")

</div>

I tried this out. Interestingly enough the file output is the same  
"óðôù÷ökðñõðð÷kòðòôññðòkðððñ÷ùö÷KðððkÄÙ@@@@@@@"

This leads me to believe this is an 'issue' with the FTP server, not returning the data in the proper format.

I ended up using the [apache.commons.net](http://apache.commons.net) instead. This allows you to specify the file type. It worked on the first try.
