FTP: Difference between revisions

From Rosetta Code
Content added Content deleted
m (→‎{{header|Java}}: small change)
Line 4: Line 4:


=={{header|Java}}==
=={{header|Java}}==
requires apache.commons.net
<lang java>import java.io.FileOutputStream;
<lang java>import java.io.FileOutputStream;
import java.io.IOException;
import java.io.IOException;

Revision as of 07:42, 30 June 2014

FTP is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

Connect to a server, change directory, list its contents and download a file as binary using the FTP protocol. Use passive mode if available.

Java

requires apache.commons.net <lang java>import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import org.apache.commons.net.ftp.FTP; import org.apache.commons.net.ftp.FTPClient; import org.apache.commons.net.ftp.FTPFile; import org.apache.commons.net.ftp.FTPReply;

public class FTPconn {

   public static void main(String[] args) throws IOException {
       String server = "ftp.hq.nasa.gov";
       int port = 21;
       String user = "anonymous";
       String pass = "ftptest@example.com";
       OutputStream output = null;
       FTPClient ftpClient = new FTPClient();
       try {
           ftpClient.connect(server, port);
           serverReply(ftpClient);
           int replyCode = ftpClient.getReplyCode();
           if (!FTPReply.isPositiveCompletion(replyCode)) {
               System.out.println("Failure. Server reply code: " + replyCode);
               return;
           }
           serverReply(ftpClient);
           if (!ftpClient.login(user, pass)) {
               System.out.println("Could not login to the server.");
               return;
           }
           String dir = "pub/issoutreach/Living in Space Stories (MP3 Files)/";
           if (!ftpClient.changeWorkingDirectory(dir)) {
               System.out.println("Change directory failed.");
               return;
           }
           ftpClient.enterLocalPassiveMode();
           for (FTPFile file : ftpClient.listFiles())
               System.out.println(file);
           String filename = "Can People go to Mars.mp3";
           output = new FileOutputStream(filename);
           ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
           if (!ftpClient.retrieveFile(filename, output)) {
               System.out.println("Retrieving file failed");
               return;
           }
           serverReply(ftpClient);
           ftpClient.logout();
       } finally {
           if (output != null)
               output.close();
       }
   }
   private static void serverReply(FTPClient ftpClient) {
       for (String reply : ftpClient.getReplyStrings()) {
           System.out.println(reply);
       }
   }

}</lang>

Output:

220-Warning: This system is owned and operated by the US Federal Government.
          Unauthorized access to this system is a violation of US Federal
          law and could lead to prosecution.
 
 This is NASA HQ ANONYMOUS FTP SERVER.
 
 Please read the README file located in the initial server root directory.
 
 IF you place files into the /incoming directory, it is IMPERATIVE that you
 notify ftp-admin@hq.nasa.gov that you have done so and of your intended
 disposition of those files.  Absent such notification, all files placed
 in /incoming that cannot be identified will be immediately deleted.
 
220 FTP Server Ready
220-Warning: This system is owned and operated by the US Federal Government.
          Unauthorized access to this system is a violation of US Federal
          law and could lead to prosecution.
 
 This is NASA HQ ANONYMOUS FTP SERVER.
 
 Please read the README file located in the initial server root directory.
 
 IF you place files into the /incoming directory, it is IMPERATIVE that you
 notify ftp-admin@hq.nasa.gov that you have done so and of your intended
 disposition of those files.  Absent such notification, all files placed
 in /incoming that cannot be identified will be immediately deleted.
 
220 FTP Server Ready
-rw-rw-r--   1 109      space-station  2327118 May  9  2005 09sept_spacepropulsion.mp3
-rw-rw-r--   1 109      space-station  1260304 May  9  2005 Can People go to Mars.mp3
-rw-rw-r--   1 109      space-station  1350270 May  9  2005 Distill some water.mp3
-rw-rw-r--   1 109      space-station  1290888 May  9  2005 Good Vibrations.mp3
-rw-rw-r--   1 109      space-station  1431834 May  9  2005 Gravity Hurts_So good.mp3
-rw-rw-r--   1 109      space-station  1072644 May  9  2005 Gravity in the Brain.mp3
-rw-rw-r--   1 109      space-station  1230594 May  9  2005 Power to the ISS.mp3
-rw-rw-r--   1 109      space-station  1309062 May  9  2005 Space Bones.mp3
-rw-rw-r--   1 109      space-station  2292715 May  9  2005 Space Power.mp3
-rw-rw-r--   1 109      space-station   772075 May  9  2005 We have a solution.mp3
-rw-rw-r--   1 109      space-station  1134654 May  9  2005 When Space Makes you Dizzy.mp3
226 Transfer complete

Python 2

<lang Python> from ftplib import FTP ftp = FTP('kernel.org') ftp.login() ftp.cwd('/pub/linux/kernel') ftp.set_pasv(True) # Default since Python 2.1 print ftp.retrlines('LIST') print ftp.retrbinary('RETR README', open('README', 'wb').write) ftp.quit() </lang>

Racket

Note: net/ftp in Racket uses passive mode exclusively. <lang racket>

  1. lang racket

(require net/ftp) (let* ([server "kernel.org"]

      [remote-dir "/pub/linux/kernel/"]
      [conn (ftp-establish-connection
              server
              21
              "anonymous"
              "")])
 (ftp-cd conn remote-dir)
 (map
  (lambda (elem) (displayln (string-join elem "\t")))
  (ftp-directory-list conn "."))
 (ftp-download-file conn "." "README")
 (ftp-close-connection conn))

</lang>

REBOL

<lang REBOL> system/schemes/ftp/passive: on print read ftp://kernel.org/pub/linux/kernel/ write/binary %README read/binary ftp://kernel.org/pub/linux/kernel/README </lang>

Tcl

Using package ftp

<lang Tcl> package require ftp

set conn [::ftp::Open kernel.org anonymous "" -mode passive]

ftp::Cd $conn /pub/linux/kernel

foreach line [ftp::NList $conn] {

   puts $line

}

ftp::Type $conn binary
ftp::Get $conn README README

</lang>

Using a virtual file system

An alternative approach that uses the package TclVFS to access ftp:// paths as a virtual file system.

<lang tcl> package require vfs::urltype vfs::urltype::Mount ftp

  1. Patch to enable FTP passive mode.

source vfsftpfix.tcl

set dir [pwd] cd ftp://kernel.org/pub/linux/kernel foreach line [glob -dir ftp://kernel.org/pub/linux/kernel *] {

   puts $line

} file copy README [file join $dir README] </lang>

The file vfsftpfix.tcl with the passive mode patch (see http://wiki.tcl.tk/12837): <lang tcl>

  1. Replace vfs::ftp::Mount to enable vfs::ftp to work in passive
  2. mode and make that the default.

package require vfs::ftp proc vfs::ftp::Mount {dirurl local {mode passive}} {

   set dirurl [string trim $dirurl]
   ::vfs::log "ftp-vfs: attempt to mount $dirurl at $local"
   if {[string index $dirurl end] != "/"} {
       ::vfs::log "ftp-vfs: adding missing directory delimiter to mount point"
       append dirurl "/"
   }
   set urlRE {(?:ftp://)?(?:([^@:]*)(?::([^@]*))?@)?([^/:]+)(?::([0-9]*))?/(.*/)?$}
   if {![regexp $urlRE $dirurl - user pass host port path]} {
       return -code error "Sorry I didn't understand\
         the url address \"$dirurl\""
   }
   if {![string length $user]} {
       set user anonymous
   }
   if {![string length $port]} {
       set port 21
   }
   set fd [::ftp::Open $host $user $pass -port $port -output ::vfs::ftp::log -mode $mode]
   if {$fd == -1} {
       error "Mount failed"
   }
   if {$path != ""} {
       if {[catch {
           ::ftp::Cd $fd $path
       } err]} {
           ftp::Close $fd
           error "Opened ftp connection, but then received error: $err"
       }
   }
   if {![catch {vfs::filesystem info $dirurl}]} {
       # unmount old mount
       ::vfs::log "ftp-vfs: unmounted old mount point at $dirurl"
       vfs::unmount $dirurl
   }
   ::vfs::log "ftp $host, $path mounted at $fd"
   vfs::filesystem mount $local [list vfs::ftp::handler $fd $path]
   # Register command to unmount
   vfs::RegisterMount $local [list ::vfs::ftp::Unmount $fd]
   return $fd

} </lang>