views:

175

answers:

0

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();
 }
}