web-dev-qa-db-fra.com

Comment copier un fichier sur le serveur FTP dans un répertoire sur le même serveur en Java?

J'utilise Apache Commons FTP pour télécharger un fichier. Avant de télécharger, je veux vérifier si le fichier existe déjà sur le serveur et en faire une sauvegarde dans un répertoire de sauvegarde situé sur le même serveur.

Est-ce que quelqu'un sait comment copier un fichier d'un serveur FTP vers un répertoire de sauvegarde sur le même serveur?

public static void uploadWithCommonsFTP(File fileToBeUpload){
    FTPClient f = new FTPClient();
    FTPFile backupDirectory;
    try {
        f.connect(server.getServer());
        f.login(server.getUsername(), server.getPassword());
        FTPFile[] directories = f.listDirectories();
        FTPFile[] files = f.listFiles();
        for(FTPFile file:directories){
            if (!file.getName().equalsIgnoreCase("backup")) {
                backupDirectory=file;
            } else {
               f.makeDirectory("backup");
            }
        }
        for(FTPFile file: files){
            if(file.getName().equals(fileToBeUpload.getName())){
                //copy file to backupDirectory
            }
        }

    } catch (IOException e) {
        e.printStackTrace();
    }

}

Code édité: Il y a toujours un problème. Lorsque je sauvegarde un fichier Zip, le fichier sauvegardé est corrompu.

Est-ce que tout le monde en connaît la raison?

 public static void backupUploadWithCommonsFTP(File fileToBeUpload) {
    FTPClient f = new FTPClient();
    boolean backupDirectoryExist = false;
    boolean fileToBeUploadExist = false;
    FTPFile backupDirectory = null;
    try {
        f.connect(server.getServer());
        f.login(server.getUsername(), server.getPassword());
        FTPFile[] directories = f.listDirectories();
        // Check for existence of backup directory
        for (FTPFile file : directories) {
            String filename = file.getName();
            if (file.isDirectory() && filename.equalsIgnoreCase("backup")) {
                backupDirectory = file;
                backupDirectoryExist = true;
                break;
            }
        }
        if (!backupDirectoryExist) {
            f.makeDirectory("backup");
        }
        // Check if file already exist on the server
        f.changeWorkingDirectory("files");
        FTPFile[] files = f.listFiles();
        f.changeWorkingDirectory("backup");
        String filePathToBeBackup="/home/user/backup/";
        String prefix;
        String suffix;
        String fileNameToBeBackup;
        FTPFile fileReadyForBackup = null;
        f.setFileType(FTP.BINARY_FILE_TYPE);
        f.setFileTransferMode(FTP.BINARY_FILE_TYPE);
        for (FTPFile file : files) {
            if (file.isFile() && file.getName().equals(fileToBeUpload.getName())) {
                prefix = FilenameUtils.getBaseName(file.getName());
                suffix = ".".concat(FilenameUtils.getExtension(file.getName()));
                fileNameToBeBackup = prefix.concat(Calendar.getInstance().getTime().toString().concat(suffix));
                filePathToBeBackup = filePathToBeBackup.concat(fileNameToBeBackup);
                fileReadyForBackup = file;
                fileToBeUploadExist = true;
                break;
            }
        }
        // If file already exist on the server create a backup from it otherwise just upload the file.
        if(fileToBeUploadExist){
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            f.retrieveFile(fileReadyForBackup.getName(), outputStream);
            InputStream is = new ByteArrayInputStream(outputStream.toByteArray());
            if(f.storeUniqueFile(filePathToBeBackup, is)){
                JOptionPane.showMessageDialog(null, "Backup succeeded.");
                f.changeWorkingDirectory("files");
                boolean reply = f.storeFile(fileToBeUpload.getName(), new FileInputStream(fileToBeUpload));
                if(reply){
                    JOptionPane.showMessageDialog(null,"Upload succeeded.");
                }else{
                    JOptionPane.showMessageDialog(null,"Upload failed after backup.");
                }
            }else{
                JOptionPane.showMessageDialog(null,"Backup failed.");
            }
        }else{
            f.changeWorkingDirectory("files");
            f.setFileType(FTP.BINARY_FILE_TYPE);
            f.enterLocalPassiveMode();
            InputStream inputStream = new FileInputStream(fileToBeUpload);
            ByteArrayInputStream in = new ByteArrayInputStream(FileUtils.readFileToByteArray(fileToBeUpload));
            boolean reply = f.storeFile(fileToBeUpload.getName(), in);
            System.out.println("Reply code for storing file to server: " + reply);
            if(!f.completePendingCommand()) {
                f.logout();
                f.disconnect();
                System.err.println("File transfer failed.");
                System.exit(1);
            }
            if(reply){

                JOptionPane.showMessageDialog(null,"File uploaded successfully without making backup." +
                        "\nReason: There wasn't any previous version of this file.");
            }else{
                JOptionPane.showMessageDialog(null,"Upload failed.");
            }
        }
        //Logout and disconnect from server
        in.close();
        f.logout();
        f.disconnect();
    } catch (IOException e) {
        e.printStackTrace();
    }

}
13
itro

Si vous utilisez net FTPClient de Apache commons, il existe une méthode directe pour déplacer un fichier d'un emplacement à un autre (si la user dispose des autorisations appropriées).

ftpClient.rename(from, to);

ou, Si vous connaissez ftp commands, vous pouvez utiliser quelque chose comme

ftpClient.sendCommand(FTPCommand.yourCommand, args);
if(FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
     //command successful;
} else {
     //check for reply code, and take appropriate action.
}

Si vous utilisez un autre client, consultez la documentation. Il n'y aura pas beaucoup de changements entre les implémentations des clients.

METTRE À JOUR:

L'approche ci-dessus déplace le fichier dans le répertoire to, c'est-à-dire qu'il ne sera plus dans le répertoire from. En gros, le protocole ftp était destiné à transférer les fichiers de local <-> remote ou remote <-> other remote mais pas à ceux du serveur.

Pour contourner le problème, il serait plus simple d’obtenir le fichier complet dans une InputStream locale et de le réécrire sur le serveur en tant que nouveau fichier dans le répertoire de sauvegarde.

pour obtenir le dossier complet, 

ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ftpClient.retrieveFile(fileName, outputStream);
InputStream is = new ByteArrayInputStream(outputStream.toByteArray());

maintenant, stockez ce flux dans le répertoire de sauvegarde. Nous devons d’abord changer le répertoire de travail en répertoire de sauvegarde.

// assuming backup directory is with in current working directory
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);//binary files
ftpClient.changeWorkingDirectory("backup");
//this overwrites the existing file
ftpClient.storeFile(fileName, is);
//if you don't want to overwrite it use storeUniqueFile

J'espère que cela vous aide ..

19
RP-

Essayez de cette façon,

J'utilise la bibliothèque d'Apache.

ftpClient.rename (de, à) facilitera les choses, j'ai mentionné dans le code ci-dessous où ajouter ftpClient.rename (de, à).

public void goforIt(){


        FTPClient con = null;

        try
        {
            con = new FTPClient();
            con.connect("www.ujudgeit.net");

            if (con.login("ujud3", "Stevejobs27!!!!"))
            {
                con.enterLocalPassiveMode(); // important!
                con.setFileType(FTP.BINARY_FILE_TYPE);
                String data = "/sdcard/prerakm4a.m4a";
                ByteArrayInputStream(data.getBytes());
                FileInputStream in = new FileInputStream(new File(data));
                boolean result = con.storeFile("/Ads/prerakm4a.m4a", in);
                in.close();
                if (result) 
                       {
                            Log.v("upload result", "succeeded");

// $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ Ajoutez la sauvegarde ici $$$$$$$$$$$$$$$$$$ $$$$$$$$$$$$$$$$$ //

                   // Now here you can store the file into a backup location

                  // Use ftpClient.rename(from, to) to place it in backup

// $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ Ajoutez la sauvegarde ici $$$$$$$$$$$$$$$$$$ $$$$$$$$$$$$$$$$$ //

                       }
                con.logout();
                con.disconnect();
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }   

    }
1
Kumar Vivek Mitra

Il n'existe aucun moyen standard de dupliquer un fichier distant via le protocole FTP. Certains serveurs FTP prennent toutefois en charge des extensions propriétaires ou non standard. 


Donc, si vous avez de la chance que votre serveur soit ProFTPD avec mod_copy module , vous pouvez utiliser FTP.sendCommand pour exécuter ces deux commandes:

f.sendCommand("CPFR sourcepath");
f.sendCommand("CPTO targetpath");

La deuxième possibilité est que votre serveur vous permet d'exécuter des commandes Shell arbitraires. C'est encore moins commun. Si votre serveur le supporte, vous pouvez utiliser la commande SITE EXEC:

SITE EXEC cp -p sourcepath targetpath

Une autre solution consiste à ouvrir une deuxième connexion au serveur FTP et à obliger le serveur à télécharger le fichier sur lui-même en canalisant une connexion de données en mode passif vers une connexion de données en mode actif. L'implémentation de cette solution (dans PHP cependant) est montrée dans FTP copier un fichier à un autre endroit dans le même FTP .


Si cela ne fonctionne pas, tout ce que vous pouvez faire est de télécharger le fichier dans un emplacement temporaire local et de le télécharger à nouveau vers l'emplacement cible. C’est que la réponse de @ RP- indique .


Voir aussi FTP copier un fichier à un autre endroit dans le même FTP .

0
Martin Prikryl