简体   繁体   中英

JCIFS SmbFile RenameTo fails to a move file

I have the strangest behavior using the JCIFS SmbFile.renameTo() method. When I execute the code below it should move the network file from test1 to test2, but instead it creates a folder in test2 called test.xml and throws the following error "Cannot create a file when that file already exists..." I can't figure it out. Why is this method doing this?

 NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication (sDomain, 
                                       sUsername, sPassword);
 SmbFile smbFromFile = new SmbFile("smb://test1/test.xml", auth);
 SmbFile smbToFile = new SmbFile("smb://test2/test.xml", auth);
 smbFromFile.renameTo(smbToFile);

There's an interesting difference between copyTo(SmbFile) and renameTo(SmbFile) - only one of them says This file and the destination file do not need to be on the same host. As renameTo(SmbFile) does not say that, I can only assume you should use copyTo and then delete() the original.

SmbFile smbFromFile = new SmbFile("smb://test1/test.xml", auth);
SmbFile smbToFile = new SmbFile("smb://test2/test.xml", auth);
// smbFromFile.renameTo(smbToFile);
smbFromFile.copyTo(smbToFile);
smbFromFile.delete();

There are two possible Scenarios:

1.) The file needs to be moved on the same server ( That is, the authentication details for Input folder and Output folder are same).

Use renameTo() method.

 public boolean moveFile(SmbFile file) {
    log.info("{"Started Archiving or Moving the file");
    String targetFilePath = this.archiveDir + file.getName(); //Path where we need to move that file.
    try {
        NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication("", userId, userPassword);
        log.info("targetFilePath: {} , currentFile : {}",targetFilePath, file);
        SmbFile targetFile = new SmbFile(targetFilePath, auth); 
          //authenticate the SmbFile
        try {
            file.renameTo(targetFile); //User renameTo method for same server
            log.info("Archived File : {} to: {}", file.getName(), 
            targetFile.getName());
            return true;
        } catch (SmbException e) {
            log.error("Unable to Archive File: {}", file.getName());
            return false;
        }
    } catch (MalformedURLException e) {
        log.error("Connection failed to Server Drive: {}", targetFilePath);
    }
    return false;
}

2.) The file needs to be moved on Different server ( That is, the authentication details for Input folder and Output folder are NOT same).

Use copyTo() method.

Here I will suggest, You can firstly authenticate the first server on which file is present, And check if the File exists, If it is existing then add that in a list :

public List<SmbFile> xmlFiles = new ArrayList<>(); //Here we will add all the files which are existing.

public boolean isFileExists() throws MalformedURLException, SmbException {
  NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication("", 
  userID, userPassword); //authenticating input folder.
    SmbFile smbFile = new SmbFile(inputFolder, auth);
    SmbFile[] smbFiles = smbFile.listFiles();
    boolean isFilePresent = false;
    if (smbFiles.length > 0) {
        for (SmbFile file : smbFiles) {
            if (file.getName().toLowerCase(Locale.ENGLISH)              
       .contains(AppConstant.FILE_NAME.toLowerCase(Locale.ENGLISH))) {
                xmlFiles.add(file);
                isFilePresent = true;
            }
        }
    }
    if (isPlanFilePresent) {
        log.info("Number of files present on Server: {}",smbFiles.length);
        return true;
    }
    return false;
}

This will give you the files in the list. Go ahead to copy it to another server. Note that you need to authenticate here for the output Folder only.

 public boolean moveFile(SmbFile file) {
    log.info("Started Moving or Archiving the file");
    String toFilePath = this.outputFolder + file.getName(); //path where you need to copy the file from input folder.
    try {
        NtlmPasswordAuthentication auth1 = new NtlmPasswordAuthentication("", outputFolderUserId, outputFolderPassword); //authenticating output folder
        log.info("targetFilePath: {} and currentFile : {}", toFilePath, file);
        SmbFile targetFile = new SmbFile(toFilePath, auth1);
      
        try {
            file.copyTo(targetFile);
            file.delete(); //delete the file which we copied at our desired server
            log.info("Archived File : {} to: {}", file.getName(), targetFile.getName());
            return true;
        } catch (SmbException e) {
            log.error("Unable to Archive File: {}", file.getName());
            return false;
        }

    } catch (MalformedURLException e) {
        log.error("Connection failed to Server Drive: {}", toFilePath);
    }
    return false;
}

Happy to Help :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM