14

ApacheCommonsFTPを使用してファイルをアップロードしています。アップロードする前に、ファイルがサーバー上にすでに存在するかどうかを確認し、ファイルから同じサーバー上のバックアップディレクトリにバックアップを作成したいと思います。

FTPサーバーから同じサーバー上のバックアップディレクトリにファイルをコピーする方法を知っている人はいますか?

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();
    }

}

編集されたコード:まだ問題があります。zipファイルをバックアップすると、バックアップされたファイルが破損します。

誰かがその理由を知っていますか?

 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();
    }

}
4

4 に答える 4

22

apache commons netを使用している場合FTPClient、ファイルをある場所から別の場所に移動する直接的な方法があります(user適切な権限がある場合)。

ftpClient.rename(from, to);

または、に精通している場合はftp commands、次のようなものを使用できます

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

他のクライアントを使用している場合は、ドキュメントを確認してください。クライアントの実装間で大きな変更はありません。

アップデート:

上記のアプローチでは、ファイルがtoディレクトリに移動します。つまり、ファイルはfromディレクトリに存在しなくなります。基本的に、ftpプロトコルは、サーバーからファイルを転送することを目的としていますが、サーバー内でファイルを転送することはできませんlocal <-> remoteremote <-> other remote

この回避策はより簡単で、完全なファイルをローカルに取得しInputStream、バックアップディレクトリの新しいファイルとしてサーバーに書き戻します。

完全なファイルを取得するには、

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

ここで、このストリームをバックアップディレクトリに保存します。まず、作業ディレクトリをバックアップディレクトリに変更する必要があります。

// 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

これがお役に立てば幸いです。

于 2012-06-26T07:29:14.710 に答える
1

この方法を試してください、

私はapacheのライブラリを使用しています。

ftpClient.rename(from、to) を使用すると簡単になります。以下のコードで、ftpClient.rename(from、to)を追加する場所について説明しました。

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");

//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ここにバックアップを追加$$$$$$$$$$$$$$$ $$$$$$$$$$$$$$$$$ //

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

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

//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ここにバックアップを追加$$$$$$$$$$$$$$$ $$$$$$$$$$$$$$$$$ //

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

    }
于 2012-06-26T09:06:30.037 に答える
0

FTPプロトコルを介してリモートファイルを複製する標準的な方法はありません。ただし、一部のFTPサーバーは、このための独自の拡張機能または非標準の拡張機能をサポートしています。


したがって、サーバーがmod_copyモジュールFTP.sendCommandを備えたProFTPDであることが運が良ければ、次の2つのコマンドを発行するために使用できます。

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

2番目の可能性は、サーバーで任意のシェルコマンドを実行できることです。これはさらに一般的ではありません。サーバーがこれをサポートしている場合は、次のSITE EXECコマンドを使用できます。

SITE EXEC cp -p sourcepath targetpath

別の回避策は、FTPサーバーへの2番目の接続を開き、パッシブモードのデータ接続をアクティブモードのデータ接続にパイプすることにより、サーバーがファイルをサーバー自体にアップロードするようにすることです。このソリューションの実装(ただしPHPで)はFTPで示され、同じFTP内の別の場所にファイルをコピーします


これがどちらも機能しない場合は、ファイルをローカルの一時的な場所にダウンロードして、ターゲットの場所に再アップロードするだけです。これは、@RP-による回答がを示しているということです。


FTPでファイルを同じFTP内の別の場所にコピーするも参照してください。

于 2018-09-24T06:44:42.723 に答える
-1

同じサーバーでバックアップ(移動)するには、次を使用できますか?

String source="/home/user/some";
String goal  ="/home/user/someOther";
FTPFile[] filesFTP = cliente.listFiles(source);

clientFTP.changeWorkingDirectory(goal);  // IMPORTANT change to final directory

for (FTPFile f : archivosFTP) 
   {
    if(f.isFile())
       {
        cliente.rename(source+"/"+f.getName(), f.getName());
       }
   }
于 2017-06-08T17:56:06.290 に答える