- NNTP
- SMTP
- POP3
- Telnet
- TFTP
- Finger
- Whois
- rexec/rcmd/rlogin
- Time (rdate) and Daytime
- Echo
- Discard
- NTP/SNTP
Accesarea unui server FTP din limbajul Java
1. Introducere
Acest exemplu detaliaza cum ne putem conecta la un server FTP folosind limbajul Java.
Pentru a realiza acest lucru ne putem folosi de biblioteca Apache Commons Net, disponibila la adresa: http://commons.apache.org/net/
Tool-uri necesare:
- Java JDK (preferabil versiunea 1.6)
- Apache Ant (disponibil la adresa http://ant.apache.org/), pentru partea de build
- Apache Ivy pentru rezolvarea dependentelor proiectului (singura fiind Apache Common Net). Este disponibil la adresa: http://ant.apache.org/ivy/
Trebuie ca jar-ul pentru Ivy sa fie in CLASSPATH (de exemplu, in cazul meu, am in CLASSPATH d:\OPENSOURCE\apache-ivy-2.2.0\ivy-2.2.0.jar)
Trebuie ca directorul bin din distributia de Ant sa fie in PATH
2. Detalii privind utilizarea bibliotecii Apache Commons Net
Pasi ce trebuiesc urmati:
1. Instantierea unui obiect de tipul FTPClient. Acesta va fi utilizat pentru a interactiona cu serverul FTP.
- FTPClient client = new FTPClient();
2. Folosind obiectul de tip FTPClient, ne putem conecta la serverul FTP
- client.connect(server);
unde parametrul metodei este numele serverului FTP (de exemplu ftp.gnu.org)
Pentru a testa faptul ca ne-am conectat cu succes, trebuie sa testam codul de replay obtinut in urma operatiei de conectare.
Pentru a obtine codul de replay, folosim metoda getReplayCode() a clasei FTPClient.
Pentru a testa codul de replay obtinut, folsim metoda isPositiveCompletion(), statica in clasa FTPReply.
O bucata de cod ce exemplifica cele doua operatii este urmatoarea:
- int reply = client.getReplyCode();
- if(FTPReply.isPositiveCompletion(reply)) {
- // serverul FTP a acceptat conexiunea
- } else {
- // serverul FTP a refuzat conexiunea
- }
3. Dupa ce ne-am conectat la server, trebuie sa initiem operatiunea de log-in
Pentru aceasta avem nevoie de un nume de utilizator si de o parola.
Folosim metoda login(), a clasei FTPClient.
- client.login(user, password);
4. Presupunand ca operatia de log-in a decurs cu succes, de acum putem efectua diverse operatii, precum:
a) Setarea directorului remote (pe serverul FTP)
Pentru aceasta, folosim metoda changeWorkingDirectory() a clasei FTPClient, ce primeste ca parametru numele noii cai.
- client.changeWorkingDirectory(path)
b) Obtinerea de informatii despre fisierele ce se gasesc pe serverul FTP in directorul remote
Se foloseste metoda listFiles() a clasei FTPClient. Metoda intoarce un array de obiecte de tipul FTPFile.
Clasa FTPFile impacheteaza informatii despre un fisier aflat pe serverul FTP (precum numele sau, drepturi de acces, dimensiune in octeti, etc).
- client.listFiles();
c) Download-ul unui fisier de pe server
Se poate folosi metoda retrieveFile() a clasei FTPClient. Metoda primeste doi parametri: numele fisierului remote (ce se doreste a fi download-at) si un stream de iesire (FileOutputStream) deschis local, in care va fi scris continutul fisierului.
- FileOutputStream outStream = new FileOutputStream(localFile);
- client.retrieveFile(remoteFile, outStream)
Metoda retrieveFile() intoarce true daca operatia de download a reusit.
d) Upload-ul unui fisier pe server
Se poate folosi metoda storeFile() a clasei FTPClient. Metoda primeste doi parametri: numele fisierului remote (cum se va numi fisierul upload-at pe server) si un stream de intrare (FileInputStream) corespunzator fisierului local ce va fi upload-at.
- FileInputStream inputStream = new FileInputStream(localFile);
- client.storeFile(remoteFile, inputStream);
In cazul operatiilor de transfer (download, upload), se poate specifica tipul transferului (binar, ASCII, ...).
Pentru aceasta se poate folosi metoda setFileType() a clasei FTPClient.
De exemplu, pentru a seta tipul transferului ca fiind binar, procedam astfel:
- client.setFileType(FTP.BINARY_FILE_TYPE);
Pentru a seta tipul transferului ca fiind ASCII:
- client.setFileType(FTP.ASCII_FILE_TYPE);
5. In cele din urma, trebuie sa ne deconectam de la server.
Acest lucru presupune executarea unei operatii de log-out:
- client.logout();
si a operatiei de deconectare a clientului de la server:
- client.disconnect();
3. Exemplu complet
Sa punem totul cap la cap intr-un mic exemplu.
In acest exemplu, ne conectam la serverul FTP GNU, avand adresa ftp.gnu.org, in mod anonymous ( numele de utilizator fiind anonymous iar parola o adresa de email - nu conteaza care).
Dupa conectare, schimbam directorul remote curent catre gnu, luam lista de fisiere remote si o afisam.
Apoi, descarcam fisierul cu numele =README
Codul este urmatorul:
- package info.bitcell.javaexamples.ftp;
- import java.io.IOException;
- import org.apache.commons.net.ftp.FTPFile;
- public class FtpClientDemo {
- public static void main(String[] args) {
- FtpClientSession client = new FtpClientSession();
- try {
- // connect to server ftp.gnu.org as anonymous
- client.connect("ftp.gnu.org", "anonymous", "test@mail.org");
- try {
- // change the remote directory to gnu
- client.chdir("gnu");
- // print the files info from the remote directory
- for (FTPFile ftpFile : client.listFiles()) {
- System.out.println(ftpFile);
- }
- // download the "=README" file from the server
- client.downloadFile("=README", "=README", false);
- } finally {
- // disconnect from the server
- client.disconnect();
- }
- } catch (IOException ex) {
- ex.printStackTrace();
- }
- }
- }
Clasa FtpClientSession este folosita pentru a accesa serverul FTP.
Detaliile de implementare ar trebui sa fie clare deja.
- package info.bitcell.javaexamples.ftp;
- 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;
- import java.io.FileInputStream;
- import java.io.FileOutputStream;
- import java.io.IOException;
- public class FtpClientSession {
- /**
- * The client used to connect to the FTP server
- */
- private final FTPClient client = new FTPClient();
- /**
- * Connect to an FTP server
- * @param server the server address (e.g "ftp.gnu.org")
- * @param user the user
- * @param password the password
- * @throws IOException if the connection failed
- */
- public void connect(String server, String user, String password) throws IOException {
- // connect to the server
- client.connect(server);
- // enter local passive mode, in case we are behind a firewall
- client.enterLocalPassiveMode();
- // see if the replay code of the connect operation is positive
- int reply = client.getReplyCode();
- if(!FTPReply.isPositiveCompletion(reply)) {
- // the server refused the connection
- client.disconnect();
- throw new IOException("Server refused connection");
- }
- // we have successfully connected to the server, now proceed
- // with the login
- client.login(user, password);
- }
- /**
- * Disconnect from an FTP server
- * @throws IOException if the disconnect command failed
- */
- public void disconnect() throws IOException {
- assert(client.isConnected());
- // first logout, then disconnect from the server
- client.logout();
- client.disconnect();
- }
- /**
- * Change the remote directory path
- * @param path the new remote path
- * @throws IOException if the command failed
- */
- public void chdir(String path) throws IOException {
- if (!client.changeWorkingDirectory(path)) {
- throw new IOException("Could change remote directory to " + path);
- }
- }
- /**
- * Get the list of remote files
- * @return the list of remote files
- * @throws IOException if the command failed
- */
- public FTPFile[] listFiles() throws IOException {
- assert(client.isConnected());
- return client.listFiles();
- }
- /**
- * Download a remote file to the local host
- * @param remoteFile the name of the remote file
- * @param localFile the name of the local file
- * @param binaryTransfer set to true if the transfer is binary
- * and to false if is ASCII
- * @throws IOException if the command failed
- */
- public void downloadFile(String remoteFile, String localFile, boolean binaryTransfer) throws IOException {
- assert(client.isConnected());
- // set the transfer type to either binary or ASCII, depending
- // on the binaryTransfer parameter
- boolean fileTypeResult;
- if (binaryTransfer) {
- fileTypeResult = client.setFileType(FTP.BINARY_FILE_TYPE);
- } else {
- fileTypeResult = client.setFileType(FTP.ASCII_FILE_TYPE);
- }
- // check if the transfer type was set correctly
- if (!fileTypeResult) {
- throw new IOException("Could not set the file transfer type");
- }
- // now proceed with the download
- FileOutputStream outStream = new FileOutputStream(localFile);
- if (!client.retrieveFile(remoteFile, outStream)) {
- throw new IOException("Could not download file " + remoteFile);
- }
- }
- /**
- * Download a remote file to the local host
- * The transfer type is ASCII
- * @param remoteFile the name of the remote file
- * @param localFile the name of the local file
- * @throws IOException if the command failed
- */
- public void downloadFile(String remoteFile, String localFile) throws IOException {
- downloadFile(remoteFile, localFile, false);
- }
- /**
- * Upload a local file to the server
- * @param localFile the path of the local file
- * @param remoteFile the path of the remote file
- * @param binaryTransfer set to true if the transfer is binary and
- * to false if is ASCII
- * @throws IOException if the command failed
- */
- public void uploadFile(String localFile, String remoteFile, boolean binaryTransfer) throws IOException {
- assert(client.isConnected());
- boolean fileTypeResult;
- // set the transfer type to either binary or ASCII, depending
- // on the binaryTransfer parameter
- if (binaryTransfer) {
- fileTypeResult = client.setFileType(FTP.BINARY_FILE_TYPE);
- } else {
- fileTypeResult = client.setFileType(FTP.ASCII_FILE_TYPE);
- }
- // check if the transfer type was set correctly
- if (!fileTypeResult) {
- throw new IOException("Could not set the file transfer type");
- }
- // now proceed with the upload
- FileInputStream inputStream = new FileInputStream(localFile);
- if (!client.storeFile(remoteFile, inputStream)) {
- throw new IOException("Could not upload file " + localFile);
- }
- }
- /**
- * Upload a local file to the server
- * The transfer type is ASCII
- * @param localFile the path of the local file
- * @param remoteFile the path of the remote file
- * @throws IOException if the command failed
- */
- public void uploadFile(String localFile, String remoteFile) throws IOException {
- uploadFile(localFile, remoteFile, false);
- }
- }
Biblioteca Apache Commons Net permite interactiunea cu mai multe protocoale, nu numai FTP:
Pentru mai multe detalii se poate consulta documentatia javadoc, disponibila pe site.
4. Compilare si rulare
Layout-ul proiectului este urmatorul:
- │ build.xml
- │ ivy.xml
- │
- ├───lib
- └───src
- └───info
- └───bitcell
- └───javaexamples
- └───ftp
- FtpClientDemo.java
- FtpClientSession.java
Compilarea si executia se poate face folosind urmatorul script Ant (build.xml):
- <project xmlns:ivy="antlib:org.apache.ivy.ant" name="FtpClientDemo" basedir="." default="main">
- <taskdef resource="org/apache/ivy/ant/antlib.xml" />
- <property name="src.dir" value="src"/>
- <property name="build.dir" value="bin"/>
- <property name="classes.dir" value="${build.dir}/classes"/>
- <property name="jar.dir" value="${build.dir}/jar"/>
- <property name="main-class" value="info.bitcell.javaexamples.ftp.FtpClientDemo"/>
- <property name="lib.dir" value="lib"/>
- <property name="out.file" value="=README"/>
- <path id="classpath">
- <fileset dir="${lib.dir}" includes="**/*.jar"/>
- </path>
- <target name="clean">
- <delete dir="${build.dir}"/>
- <delete file="${out.file}"/>
- </target>
- <target name="resolve" description="--> retrieve dependencies with ivy">
- <ivy:retrieve />
- </target>
- <target name="compile" depends="resolve">
- <mkdir dir="${classes.dir}"/>
- <javac srcdir="${src.dir}" destdir="${classes.dir}" classpathref="classpath" />
- </target>
- <target name="jar" depends="compile">
- <mkdir dir="${jar.dir}"/>
- <jar destfile="${jar.dir}/${ant.project.name}.jar" basedir="${classes.dir}">
- <manifest>
- <attribute name="Main-Class" value="${main-class}"/>
- </manifest>
- </jar>
- </target>
- <target name="run" depends="jar">
- <java fork="true" classname="${main-class}">
- <classpath>
- <path refid="classpath"/>
- <path location="${jar.dir}/${ant.project.name}.jar"/>
- </classpath>
- </java>
- </target>
- <target name="clean-build" depends="clean,jar"/>
- <target name="main" depends="clean,run"/>
- </project>
Scriptul Ivy (ivy.xml) este urmatorul:
- <ivy-module version="2.2">
- <info organisation="info.bitcell" module="javaexamples"/>
- <dependencies>
- <dependency org="commons-net" name="commons-net" rev="2.2" />
- </dependencies>
- </ivy-module>
Se deschide un Command Prompt in directorul in care se afla fisierul build.xml si se ruleaza comanda:
In urma executiei, se vor compila fisierele sursa, se va genera arhiva FtpClientDemo.jar si se va executa.
Pentru a sterge binarele (*.class, *.jar) si fisierul descarcat de pe serverul FTP, se ruleaza comanda:
- ant clean
Welcome to BitCell. Click here to register !