Upload des fichiers vers le serveur FTP avec Java
Pour écrire un code Java qui fait l'envoi des fichiers (upload) à partir du disque local vers le serveur FTP en ligne, l'API Apache Commons Net est un très bon choix pour les développeurs Java. Elle est simple et rend la programmation avec le FTP facile.
Ce code montre comment envoyer des fichier de la machine vers le serveur FTP en utilisant ces deux méthodes:
1- Télécharger l'API Apache Commons Net
Avant de commencer, il faut télécharger l'API Apache Commons Net qui contient un ensemble des outils réseaux et supporte plusieurs protocoles comme: FTP, Telnet, SMTP... Après le téléchargement, le fichier .jar doit être intégré dans la classpath de votre projet.
2- L'API Apache Commons Net pour le transfert des fichier via le protocole FTP
La classe FTPClient fournit des méthodes pour transférer un fichier local vers le serveur en ligne via le protocole FTP:- boolean storeFile(String remote, InputStream local)
- OutputStream storeFileStream(String remote)
- boolean storeUniqueFile(InputStream local)
- boolean storeUniqueFile(String remote, InputStream local)
- OutputStream storeUniqueFileStream()
- OutputStream storeUniqueFileStream(String remote)
- Stocker les fichier en donnant un InputStream du fichier local (ceux sont les méthodes qui ont un InputStream comme paramètre). Ce type de méthodes est adopté quand on a pas besoin de connaitre comment les octets sont transférés à partir du fichier local au serveur. On laisse le système de faire ce traitement.
- Stocker les fichier en écrivant vers le OutputStream de la connexion (ceux sont les méthodes qui ont un OutputStream comme sortie). Ce type de méthodes est nécessaire quand on veut contrôler la manière dont les octets sont transférés, en écrivant notre propre code pour lire les bytes via le fichier local qui seront sauvegarder dans le chemin du fichier distant à travers l'objet OutputStream. Cela peut être utile si on veut montrer la progression de l'upload, en calculant combien d'octets sont transférés sur la taille du fichier .
- Nommer le fichier distant clairement (Ces méthodes qui acceptent un paramètre String nommé remote).
- Laisser le les noms du serveur et le fichier distant avec un nom unique (Ces méthodes qui n'ont pas un paramètre String).
En dépit de la complexité de ces méthodes, seulement deux méthodes sont principalement utilisées dans la pratique:
- boolean storeFile(String remote,InputStream local)
- OutputStream storeFileStream(String remote)
En dehors de ces six méthodes, il y a aussi deux autres qui ont besoin d’être appeler avant et après le transfert du fichier:
- boolean setFileType(int fileType): détermine le type du fichier, soit FTP.ASCII_FILE_TYPE ou FTP.BINARY_FILE_TYPE, est utilisée pour transférer le fichier. Le type par défaut est ASCII ( plain text ), mais il doit être mis en binaire dans le but qu'il marche pour tous les fichiers. Cette méthode doit être appelée avant que le transfert du fichier commence.
- boolean completePendingCommand(): Cette méthode doit être appelée après la fin du transfert pour compléter la transaction. Elle retourne true si le transfert est terminé avec succès, sinon false. On doit vérifier la valeur de retour de cette méthode pour s'assurer que l'upload a bien eu lieu.
Par défaut, le protocole FTP établit la connexion en ouvrant un port pour le client et autorise le serveur à se connecter à ce port. C'est le mode active, mais il est parfois bloqué par le firewall et le transfert du fichier ne marche pas. Heureusement, le protocole FTP a un autre mode qui est le mode passive dont lequel la connexion est établie, en ouvrant un port dans le serveur pour que le client se connecte. Ce mode n'est pas bloqué par le firewall.
Donc il est recommandé de s'orienter vers le mode passive avant le début du transfert des données avec l'appel de la méthode de la classe FTPClient enterLocalPassiveMode().
3- Les étapes pour transférer un fichier en Java
Pour bien écrire le code pour transférer un fichier vers le serveur FTP en utilisant l'API Apache Commons Net, les étapes suivants doivent être respectées:
- Connecter et s'identifier au serveur.
- Utiliser le mode passive pour la connexion.
- Modifier le type du fichier à transférer en binaire.
- Créer un InputStream pour le fichier local.
- Appeler l'une des méthodes store...() pour commencer le transfert du fichier. Il y a deux scénarios:
- En utilisant un InputStream: C'est la façon la plus simple puisque on laisse le système s'occuper de l'envoi et la réception. Il n y'a aucun code additionnel, juste faire passer l'objet InputStream dans la méthode correspondante, comme la méthode storeFile(String remote, InputStream local).
- En utilisant OutputStream: cela est plus complexe, mais on gagne plus de contrôle sur les données transférées. En général, on doit écrire quelques lignes de code pour lire les octets à partir de InputStream du fichier local et écrire ces octets dans un OutputStream qui est retourné par la méthode store...(), tel que la méthode storeFileStream(String remote).
- Fermer les flux de données InputStream et OutputStream.
- Appeler la méthode completePendingCommand() pour accomplir la transaction.
- Déconnecter du serveur.
On doit vérifier la valeur du retour des méthode store...() et completePendingCommand() pour assurer que l'upload a été bien terminé.
4- Programme de l'upload FTP en Java
- boolean storeFile(String remote, InputStream local)
- OutputStream storeFileStream(String remote)
import java.io.File;L'exécution de ce code retourne que le transfert a été bien accompli:
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
public class FTPUploadFile {
public static void main(String[] args) {
String serveur = "adresseDuServeur";
int port = 21;
String user = "nomUtilisateur";
String password = "votreMotdePasse";
FTPClient ftpClient = new FTPClient();
try {
ftpClient.connect(serveur, port);
ftpClient.login(user, password );
ftpClient.enterLocalPassiveMode();
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
// Approche 1: upload d'un fichier en utilisant InputStream
File file = new File("C:/plugins et styles.txt");
String chemin = "plugins et styles.txt";
InputStream inputStream = new FileInputStream(file);
System.out.println("Début de l'upload");
//résultat de l'upload
boolean res = ftpClient.storeFile(chemin, inputStream);
//fermet le flut de lecture
inputStream.close();
if (res==true) {
System.out.println("Le fichier "+chemin+" a été transféré avec succès");
}
// Approche 2: upload d'un fichier en utilisant OutputStream
file = new File("C:/piste 1.wma");
chemin = "audio/piste 1.wma";
inputStream = new FileInputStream(file);
System.out.println("Début de l'upload");
OutputStream outputStream = ftpClient.storeFileStream(chemin);
byte[] bytesIn = new byte[4096];
int buffer = 0;
//tant qu'on a pas atteint la fin du fichier
System.out.println("Transfert en cours...");
int transferé = 0;
int pourcentage = 0;
//tant qu'on a pas atteint la fin du fichier
while ((buffer = inputStream.read(bytesIn)) != -1) {
//lire les données avec un buffer de 4096 octets
outputStream.write(bytesIn, 0, buffer);
transferé += buffer;
pourcentage = (int) (transferé*100/file.length());
System.out.println(pourcentage+"%");
}
//fermer les flux de lecture de d'écriture
inputStream.close();
outputStream.close();
//résultat de l'upload
res = ftpClient.completePendingCommand();
if (res) {
System.out.println("Le fichier "+chemin+" a été transféré avec succès");
}
} catch (IOException e) {
System.out.println(e.getMessage());
e.printStackTrace();
} finally {
try {
if (ftpClient.isConnected()) {
//fermer la connexion FTP
ftpClient.logout();
ftpClient.disconnect();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
Début de l'upload
Le fichier plugins et styles.txt a été transféré avec succès
Début de l'upload
1%
2%
3%
.
.
97%
98%
98%
99%
99%
100%
Le fichier piste 1.wma a été transféré avec succès