I have code that connects to an FTP server and gets an input stream to a file which works wit smaller files, but doesn't work at all with larger ones. It simply returns null each time, yet when I paste the full url into a browser it works fine. Here is my FTP download code:
publishProgress("Downloading...");
try {
String userName="anonymous";
String passWord = "[email protected]";
Pattern p = Pattern.compile("ftp://(.+?)(/.+/(.+))");
Matcher m = p.matcher(completePathToFile);
m.find();
String hostPart = m.group(1);
String port = null;
if(hostPart.contains(":")){
port = hostPart.substring(hostPart.indexOf(":") + 1);
hostPart = hostPart.substring(0, hostPart.indexOf(":"));
}
String pathExcludingHostIncludingFirstSlash= m.group(2);
fileName = URLDecoder.decode(m.group(3));
FileOutputStream fos = null;
java.io.BufferedOutputStream bout = null;
InputStream myFileStream = null;
String tempFileForZip = Environment.getExternalStorageDirectory().getAbsolutePath() + GlobalVars.getSaveLocation(context, searchResult.getConsole()) + fileName;
int retries = 0;
while (myFileStream==null && retries < 100){
try{
boolean mkdirresult = (new File(tempFileForZip)).getParentFile().mkdirs();
fos = new FileOutputStream(new File(tempFileForZip));
bout = new BufferedOutputStream(fos,1024);
FTPclient = new FTPClient();
FTPclient.setListHiddenFiles(true);
FTPclient.connect(hostPart, port==null ? 21 : Integer.valueOf(port));
boolean loggedIn = FTPclient.login(userName, passWord);
FTPclient.setFileType(FTP.BINARY_FILE_TYPE);
myFileStream = FTPclient.retrieveFileStream(URLDecoder.decode(pathExcludingHostIncludingFirstSlash));
DataInputStream instream = new DataInputStream(myFileStream);
} catch (Exception e){
retries++;
if(fos!=null){fos.close();}
if(bout!=null){bout.close();}
if(myFileStream!=null){myFileStream.close();}
} finally {}
}
if(myFileStream==null){
throw new RuntimeException("Could not connect, try again");
}
int updateCounter = 0;
int bytesDownloaded = 0;
byte data[] = new byte[1024];
int x = 0;
while((x=myFileStream.read(data,0,1024))>=0){
bout.write(data,0,x);
bytesDownloaded+=1024;
updateCounter++;
if(updateCounter==3){
kilobytesDownloaded=(bytesDownloaded / 1024);
publishProgress("Downloading...");
updateCounter=0;
}
}
bout.close();
myFileStream.close();
if(!FTPclient.completePendingCommand()) {
FTPclient.logout();
FTPclient.disconnect();
Log.e("DownloadService","File transfer failed.");
}
I have no idea what's wrong with this. Here are two sample URLs:
ftp://173.192.209.76/120/NES%20Roms/A%20Ressha%20de%20Ikou%20(Japan).zip
ftp://94.75.253.68:9333/Gameboy%20Advance%20Roms/GBA%20Roms%201901%20-%202000/1909%20-%20Ace%20Combat%20Advance%20(U)(Venom).zip
ftp://ftp.emuparadise.org:8233/Playstation%20Demos/Metal%20Gear%20Solid%20Demo%20%5BU%5D%20%5BSLUS-90035%5D.rar
The first one works fine, the second one gets a null stream, and the third one causes the phone to freeze almost instantly, and then reboot!
The strangest thing is that I have a seperate Android app that runs this code perfectly in an Activity:
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import android.app.Activity;
import android.os.Bundle;
public class FtpClientService extends Activity {
public FtpClientService(){
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FtpConnect();
}
public static void FtpConnect(){
String userName="anonymous";
String passWord = "[email protected]";
String ftpAddress = "173.192.225.183";
String retrieveFromFTPFolder = "/2/PSX-PAL/";
String strLine;
DataInputStream inputStream = null;
BufferedReader bufferedReader = null;
FTPClient client = null;
FTPFile[] ftpFiles = null;
int reply;
try{
client = new FTPClient();
client.setListHiddenFiles(true);
//FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_UNIX);
//client.configure(conf);
client.connect(ftpAddress);
client.login(userName, passWord);
client.setFileType(FTP.BINARY_FILE_TYPE);
//ftpFiles = client.listFiles(retrieveFromFTPFolder); //retrieve list of files from ftp server
InputStream myFileStream = client.retrieveFileStream("/2/PSX-PAL/Metal Gear Solid (Demo) (E) [SLED-01400].7z");
inputStream = new DataInputStream(myFileStream);
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
//save file from ftp to local directory
File fileToWrite = new File("/sdcard/Metal Gear Solid (Demo) (E) [SLED-01400].7z");
java.io.FileOutputStream fos = new java.io.FileOutputStream(fileToWrite);
java.io.BufferedOutputStream bout = new BufferedOutputStream(fos,1024);
byte data[] = new byte[1024];
int x = 0;
while((x=myFileStream.read(data,0,1024))>=0){
bout.write(data,0,x);
}
bout.close();
myFileStream.close();
// Must call completePendingCommand() to finish command.
if(!client.completePendingCommand()) {
client.logout();
client.disconnect();
System.err.println("File transfer failed.");
}
} catch (Exception e) {
if (client.isConnected()) {
try {
client.logout();
client.disconnect();
} catch (IOException f) {
// do nothing
}
}
}
finally{
if (client.isConnected())
{
try
{
client.logout();
client.disconnect();
}
catch (IOException f)
{
}
}
}
}
public static void main(String[] args) {
FtpConnect();
}
}