Link to home
Start Free TrialLog in
Avatar of tragedy-seeker-in-tragedy
tragedy-seeker-in-tragedy

asked on

ftp client in java?

i want to make FTP client using java...but not finding any way to start with. Tell me the correct path to go on. I am beginner in java.
ASKER CERTIFIED SOLUTION
Avatar of Ravindra76
Ravindra76

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Ravindra76
Ravindra76

The code will work if you replace

myftpsite ,
myname ,
mypassword,
/home/gadio/temp/tempfile,
/home/gadio/temp/tempfile.read

with

ftp://yoursite.com
OS user name on that machine
OS user password on that machine for that OS user
INput file directory
Outfile directory

I got this off of the internet somewhere.  I like it because it seems to work in all JDK's...

import java.io.*;
import java.net.*;
import java.util.*;

/**
 * <p>A wrapper for the network and command protocols needed for the most common
 * FTP commands.  Standard usage looks something like this:</p>
 * <pre> FTPConnection connection = new FTPConnection();
 * try {
 *     if (connection.connect(host)) {
 *         if (connection.login(username, password)) {
 *             connection.downloadFile(serverFileName);
 *             connection.uploadFile(localFileName);
 *         }
 *         connection.disconnect();
 *     }
 * } catch (UnknownHostException e) {
 *     // handle unknown host
 * } catch (IOException e) {
 *     // handle I/O exception
 * }</pre>
 * <p>Most FTP commands are wrapped by easy-to-use methods, but in case clients
 * need more flexibility, you can execute commands directly using the methods
 * <a href="#executeCommand(java.lang.String)">executeCommand</a> and
 * <a href="#executeDataCommand(java.lang.String, java.io.OutputStream)">executeDataCommand</a>,
 * the latter of which is used for commands that require an open data port.</p>
 *
 */
public class FTPConnection {

  /**
   * If this flag is on, we print out debugging information to stdout during
   * execution.  Useful for debugging the FTP class and seeing the server's
   * responses directly.
   */
  private static boolean PRINT_DEBUG_INFO = false;

  /**
   * Connects to the given FTP host on port 21, the default FTP port.
   */
  public boolean connect(String host)      throws UnknownHostException, IOException {
    return connect(host, 21);
  }

  /**
   * Connects to the given FTP host on the given port.
   */
  public boolean connect(String host, int port) throws UnknownHostException, IOException {
    connectionSocket = new Socket(host, port);
    outputStream = new PrintStream(connectionSocket.getOutputStream());
    inputStream = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));

    if (!isPositiveCompleteResponse(getServerReply())) {
      disconnect();
      return false;
    }

    return true;
  }

  /**
   * Disconnects from the host to which we are currently connected.
   */
  public void disconnect() {
    if (outputStream != null) {
      try {
        outputStream.close();
        inputStream.close();
        connectionSocket.close();
      } catch (IOException e) {
      }

      outputStream = null;
      inputStream = null;
      connectionSocket = null;
    }
  }

  /**
   * Wrapper for the commands <code>user [username]</code> and <code>pass
   * [password]</code>.
   */
  public boolean login(String username, String password) throws IOException {
    int response = executeCommand("user " + username);
    if (!isPositiveIntermediateResponse(response)) return false;
    response = executeCommand("pass " + password);
    return isPositiveCompleteResponse(response);
  }

  /**
   * Wrapper for the command <code>cwd [directory]</code>.
   */
  public boolean changeDirectory(String directory) throws IOException {
    int response = executeCommand("cwd " + directory);
    return isPositiveCompleteResponse(response);
  }

  /**
   * Wrapper for the commands <code>rnfr [oldName]</code> and <code>rnto
   * [newName]</code>.
   */
  public boolean renameFile(String oldName, String newName) throws IOException {
    int response = executeCommand("rnfr " + oldName);
    if (!isPositiveIntermediateResponse(response)) return false;
    response = executeCommand("rnto " + newName);
    return isPositiveCompleteResponse(response);
  }

  /**
   * Wrapper for the command <code>mkd [directory]</code>.
   */
  public boolean makeDirectory(String directory) throws IOException {
    int response = executeCommand("mkd " + directory);
    return isPositiveCompleteResponse(response);
  }

  /**
   * Wrapper for the command <code>rmd [directory]</code>.
   */
  public boolean removeDirectory(String directory) throws IOException {
    int response = executeCommand("rmd " + directory);
    return isPositiveCompleteResponse(response);
  }

  /**
   * Wrapper for the command <code>cdup</code>.
   */
  public boolean parentDirectory() throws IOException {
    int response = executeCommand("cdup");
    return isPositiveCompleteResponse(response);
  }

  /**
   * Wrapper for the command <code>dele [fileName]</code>.
   */
  public boolean deleteFile(String fileName) throws IOException {
    int response = executeCommand("dele " + fileName);
    return isPositiveCompleteResponse(response);
  }

  /**
   * Wrapper for the command <code>pwd</code>.
   */
  public String getCurrentDirectory() throws IOException {
    String response = getExecutionResponse("pwd");
    StringTokenizer strtok = new StringTokenizer(response);

    // Get rid of the first token, which is the return code
    if (strtok.countTokens() < 2) return null;
    strtok.nextToken();
    String directoryName = strtok.nextToken();

    // Most servers surround the directory name with quotation marks
    int strlen = directoryName.length();
    if (strlen == 0) return null;
    if (directoryName.charAt(0) == '\"') {
      directoryName = directoryName.substring(1);
      strlen--;
    }
    if (directoryName.charAt(strlen - 1) == '\"')
      return directoryName.substring(0, strlen - 1);
    return directoryName;
  }

  /**
   * Wrapper for the command <code>syst</code>.
   */
  public String getSystemType() throws IOException {
    return excludeCode(getExecutionResponse("syst"));
  }

  /**
   * Wrapper for the command <code>mdtm [fileName]</code>.  If the file does
   * not exist, we return -1;
   */
  public long getModificationTime(String fileName) throws IOException {
    String response = excludeCode(getExecutionResponse("mdtm " + fileName));
    try {
      return Long.parseLong(response);
    } catch (Exception e) {
      return -1L;
    }
  }

  /**
   * Wrapper for the command <code>size [fileName]</code>.  If the file does
   * not exist, we return -1;
   */
  public long getFileSize(String fileName) throws IOException {
    String response = excludeCode(getExecutionResponse("size " + fileName));
    try {
      return Long.parseLong(response);
    } catch (Exception e) {
      return -1L;
    }
  }

  /**
   * Wrapper for the command <code>retr [fileName]</code>.
   */
  public boolean downloadFile(String fileName) throws IOException {
    return readDataToFile("retr " + fileName, fileName);
  }

  /**
   * Wrapper for the command <code>retr [serverPath]</code>. The local file
   * path to which we will write is given by <code>localPath</code>.
   */
  public boolean downloadFile(String serverPath, String localPath) throws IOException {
    return readDataToFile("retr " + serverPath, localPath);
  }

  /**
   * Wrapper for the command <code>stor [fileName]</code>.
   */
  public boolean uploadFile(String fileName) throws IOException {
    return writeDataFromFile("stor " + fileName, fileName);
  }

  /**
   * Wrapper for the command <code>stor [localPath]</code>. The server file
   * path to which we will write is given by <code>serverPath</code>.
   */
  public boolean uploadFile(String serverPath, String localPath) throws IOException {
    return writeDataFromFile("stor " + serverPath, localPath);
  }

  /**
   * Set the restart point for the next download or upload operation.  This
   * lets clients resume interrupted uploads or downloads.
   */
  public void setRestartPoint(int point) {
    restartPoint = point;
    debugPrint("Restart noted");
  }

  /**
   * Gets server reply code from the control port after an ftp command has
   * been executed.  It knows the last line of the response because it begins
   * with a 3 digit number and a space, (a dash instead of a space would be a
   * continuation).
   */
  private int getServerReply() throws IOException {
    return Integer.parseInt(getFullServerReply().substring(0, 3));
  }

  /**
   * Gets server reply string from the control port after an ftp command has
   * been executed.  This consists only of the last line of the response,
   * and only the part after the response code.
   */
  private String getFullServerReply() throws IOException {
    String reply;

    do {
      reply = inputStream.readLine();
      debugPrint(reply);
    } while (!(Character.isDigit(reply.charAt(0)) && 
      Character.isDigit(reply.charAt(1)) &&
      Character.isDigit(reply.charAt(2)) &&
      reply.charAt(3) == ' '));

    return reply;
  }

  /**
   * Executes the given FTP command on our current connection, returning the
   * three digit response code from the server.  This method only works for
   * commands that do not require an additional data port.
   */
  public int executeCommand(String command) throws IOException {
    outputStream.println(command);
    return getServerReply();
  }

  /**
   * Executes the given FTP command on our current connection, returning the
   * last line of the server's response.  Useful for commands that return
   * one line of information.
   */
  public String getExecutionResponse(String command) throws IOException {
    outputStream.println(command);
    return getFullServerReply();
  }

  /**
   * Executes the given ftpd command on the server and writes the results
   * returned on the data port to the file with the given name, returning true
   * if the server indicates that the operation was successful.
   */
  public boolean readDataToFile(String command, String fileName) throws IOException {
    // Open the local file
    RandomAccessFile outfile = new RandomAccessFile(fileName, "rw");

    // Do restart if desired
    if (restartPoint != 0) {
      debugPrint("Seeking to " + restartPoint);
      outfile.seek(restartPoint);
    }

    // Convert the RandomAccessFile to an OutputStream
    FileOutputStream fileStream = new FileOutputStream(outfile.getFD());
    boolean success = executeDataCommand(command, fileStream);

    outfile.close();

    return success;
  }

  /**
   * Executes the given ftpd command on the server and writes the contents
   * of the given file to the server on an opened data port, returning true
   * if the server indicates that the operation was successful.
   */
  public boolean writeDataFromFile(String command, String fileName) throws IOException {
    // Open the local file
    RandomAccessFile infile = new RandomAccessFile(fileName, "r");

    // Do restart if desired
    if (restartPoint != 0) {
      debugPrint("Seeking to " + restartPoint);
      infile.seek(restartPoint);
    }

    // Convert the RandomAccessFile to an InputStream
    FileInputStream fileStream = new FileInputStream(infile.getFD());
    boolean success = executeDataCommand(command, fileStream);

    infile.close();

    return success;
  }

  /**
   * Executes the given ftpd command on the server and writes the results
   * returned on the data port to the given OutputStream, returning true
   * if the server indicates that the operation was successful.
   */
  public boolean executeDataCommand(String command, OutputStream out) throws IOException {
    // Open a data socket on this computer
    ServerSocket serverSocket = new ServerSocket(0);
    if (!setupDataPort(command, serverSocket)) return false;
    Socket clientSocket = serverSocket.accept();

    // Transfer the data
    InputStream in = clientSocket.getInputStream();
    transferData(in, out);

    // Clean up the data structures
    in.close();
    clientSocket.close();
    serverSocket.close();

    return isPositiveCompleteResponse(getServerReply());  
  }

  /**
   * Executes the given ftpd command on the server and writes the contents
   * of the given InputStream to the server on an opened data port, returning
   * true if the server indicates that the operation was successful.
   */
  public boolean executeDataCommand(String command, InputStream in) throws IOException {
    // Open a data socket on this computer
    ServerSocket serverSocket = new ServerSocket(0);
    if (!setupDataPort(command, serverSocket)) return false;
    Socket clientSocket = serverSocket.accept();

    // Transfer the data
    OutputStream out = clientSocket.getOutputStream();
    transferData(in, out);

    // Clean up the data structures
    out.close();
    clientSocket.close();
    serverSocket.close();

    return isPositiveCompleteResponse(getServerReply());  
  }

  /**
   * Transfers the data from the given input stream to the given output
   * stream until we reach the end of the stream.
   */
  private void transferData(InputStream in, OutputStream out) throws IOException {
    byte b[] = new byte[1024];  // 1K blocks I guess
    int amount;

    // Read the data into the file
    while ((amount = in.read(b)) > 0) {
      out.write(b, 0, amount);
    }
  }

  /**
   * Executes the given ftpd command on the server and writes the results
   * returned on the data port to the given FilterOutputStream, returning true
   * if the server indicates that the operation was successful.
   */
  private boolean setupDataPort(String command, ServerSocket serverSocket) throws IOException {
    // Send our local data port to the server
    if (!openPort(serverSocket))
      return false;

    // Set binary type transfer
    outputStream.println("type i");
    if (!isPositiveCompleteResponse(getServerReply())) {
      debugPrint("Could not set transfer type");
      return false;
    }

    // If we have a restart point, send that information
    if (restartPoint != 0) {
      outputStream.println("rest " + restartPoint);
      restartPoint = 0;
      // TODO: Interpret server response here
      getServerReply();
    }

    // Send the command
    outputStream.println(command);

    return isPositivePreliminaryResponse(getServerReply());
  }

  /**
   * Get IP address and port number from serverSocket and send them via the
   * <code>port</code> command to the ftp server, returning true if we get a
   * valid response from the server, returning true if the server indicates
   * that the operation was successful.
   */
  private boolean openPort(ServerSocket serverSocket) throws IOException {              
    int localport = serverSocket.getLocalPort();

    // get local ip address
    InetAddress inetaddress = serverSocket.getInetAddress();
    InetAddress localip;
    try {
      localip = inetaddress.getLocalHost();
    } catch(UnknownHostException e) {
      debugPrint("Can't get local host");
      return false;
    }

    // get ip address in high byte order
    byte[] addrbytes = localip.getAddress();

    // tell server what port we are listening on
    short addrshorts[] = new short[4];

    // problem:  bytes greater than 127 are printed as negative numbers
    for (int i = 0; i <= 3; i++) {
      addrshorts[i] = addrbytes[i];
      if (addrshorts[i] < 0)
        addrshorts[i] += 256;
    }

    outputStream.println("port " + addrshorts[0] + "," + addrshorts[1] +
      "," + addrshorts[2] + "," + addrshorts[3] + "," +
      ((localport & 0xff00) >> 8) + "," +
      (localport & 0x00ff));

    return isPositiveCompleteResponse(getServerReply());
  }      
  /**
   * True if the given response code is in the 100-199 range.
   */
  private boolean isPositivePreliminaryResponse(int response) {
    return (response >= 100 && response < 200);
  }      
  /**
   * True if the given response code is in the 300-399 range.
   */
  private boolean isPositiveIntermediateResponse(int response) {
    return (response >= 300 && response < 400);
  }      
  /**
   * True if the given response code is in the 200-299 range.
   */
  private boolean isPositiveCompleteResponse(int response) {
    return (response >= 200 && response < 300);
  }      
  /**
   * True if the given response code is in the 400-499 range.
   */
  private boolean isTransientNegativeResponse(int response) {
    return (response >= 400 && response < 500);
  }      
  /**
   * True if the given response code is in the 500-599 range.
   */
  private boolean isPermanentNegativeResponse(int response) {
    return (response >= 500 && response < 600);
  }      
  /**
   * Eliminates the response code at the beginning of the response string.
   */
  private String excludeCode(String response) {    
    if (response.length() < 5)
      return response;                                                                              
    return response.substring(4);
  }            
  /**
   * Prints debugging information to stdout if the private flag
   * <code>PRINT_DEBUG_INFO</code> is turned on.
   */
  private void debugPrint(String message) {
    if (PRINT_DEBUG_INFO)
      System.err.println(message);
  }
  /**
   * The socket through which we are connected to the FTP server.
   */
  private Socket connectionSocket = null;
  /**
   * The socket output stream.
   */
  private PrintStream outputStream = null;
  /**
   * The socket input stream.
   */
  private BufferedReader inputStream = null;      
  /**
   * The offset at which we resume a file transfer.
   */
  private long restartPoint = 0L;
}
Avatar of Jim Cakalic
You might also look at the NetComponents package available here:
    http://www.savarese.org/oro/downloads/#NetComponents

Jim Cakalic
Avatar of tragedy-seeker-in-tragedy

ASKER

being new to java, i would like a coding which tell about important steps of coding so that i can understand the nuts and bolts of java. This coding is also good n i will work on it ...but i want descriptions of steps also. Would u plz mail me that coding on "tayyabofmoon@yahoo.com" ... i will b thankful to u.
being new to java, i would like a coding which tell about important steps of coding so that i can understand the nuts and bolts of java. This coding is also good n i will work on it ...but i want descriptions of steps also. Would u plz mail me that coding on "tayyabofmoon@yahoo.com" ... i will b thankful to u.