SSH.NET
SSH.NET copied to clipboard
Can't delete file right after creating them
I am wondering if this is an issue or my process flaw. I am not be able to delete a file that just created. But, on WinSCP, I am able to delete them manually.
There is a case where the file got locked and I can't delete them because it says that "Permission Denied" and I can't delete them as SFTP user or OS (windows) user. I did checked that the file is owned by Administrator.
Here is the code that I use to produce the problem.
private static void uploadZip(string fTPAddress, string ftpPath, string fTPUsername, string fTPPassword, string zipFilePath, string zipFileName) {
// Build username/password
var passwordAuth = new PasswordAuthenticationMethod(fTPUsername, fTPPassword);
// Build connection
var connectionInfo = new ConnectionInfo(fTPAddress, fTPUsername, passwordAuth);
using (var client = new SftpClient(connectionInfo)) {
Console.WriteLine("Connecting " + fTPAddress + "... ");
client.Connect();
Console.WriteLine(client.IsConnected ? "Connected!" : "Disconnected.");
// Upload file
try {
Console.WriteLine("Creating new path + file...");
client.Create(ftpPath + zipFileName);
Console.WriteLine("Created!");
if (client.Exists(ftpPath + zipFileName)) {
Console.WriteLine(ftpPath + zipFileName + " Exists!");
Console.WriteLine("Deleting " + ftpPath + zipFileName + "... ");
client.Delete(ftpPath + zipFileName);
Console.WriteLine("Deleted");
} else {
Console.WriteLine("Uploading file...");
using (FileStream stream = File.Open(zipFilePath, FileMode.Open)) {
client.UploadFile(stream, ftpPath + zipFileName);
}
Console.WriteLine("Uploaded!");
}
} catch (Exception e) {
Console.WriteLine("-- Something wrong on execution: " + e.Message);
Console.WriteLine(e.StackTrace);
} finally {
Console.WriteLine("Disconnecting... ");
client.Disconnect();
Console.WriteLine(client.IsConnected ? "Connected!" : "Disconnected.");
Console.WriteLine("Deleting " + zipFilePath + "...");
File.Delete(zipFilePath);
Console.WriteLine(zipFilePath + " Deleted...");
}
}
}
The output: C:\Users\btobias>C:\WorkingCopies\PCCDBAssembly\PCCDB.Docs.Run\bin\Dev\PCCDB.Docs.Run.exe ( 0 milliseconds) Type found: PCCDB.PCC.Library.LibraryPatronDump ( 0 milliseconds) Method found: LibraryPatronDumpExe ( 1 milliseconds) Parameter 0: ftpAddress (System.String): ftp.test.com ( 1 milliseconds) Parameter 1: ftpPath (System.String): /alma/test/ ( 1 milliseconds) Parameter 2: ftpUsername (System.String): XXXXX ( 2 milliseconds) Parameter 3: ftpPassword (System.String): XXXXXXXXXXXXXX ( 2 milliseconds) Parameter 4: syncPersonnelIncluded (System.String): Y ( 3 milliseconds) Executing... ( 9292 milliseconds) Connecting ftp.pcci.edu... ( 9528 milliseconds) Connected! ( 9528 milliseconds) Creating new path + file... ( 9539 milliseconds) Created! ( 9546 milliseconds) /alma/test/PatronDump2.zip Exists! ( 9546 milliseconds) Deleting /alma/test/PatronDump2.zip... ( 9553 milliseconds) -- Something wrong on execution: Permission denied ( 9555 milliseconds) at Renci.SshNet.Sftp.SftpSession.RequestRemove(String path) at PCCDB.PCC.Library.LibraryPatronDump.uploadZip(String fTPAddress, String ftpPath, String fTPUsername, String fTPPassword, String zipFilePath, String zipFileName) in C:\WorkingCopies\PCCDBAssembly\PCCDB.Docs\PCC\Library\LibraryPatronDump.cs:line 94 ( 9556 milliseconds) Disconnecting... ( 9607 milliseconds) Disconnected. ( 9607 milliseconds) Deleting C:\Temp\PatronDump2.zip... ( 9609 milliseconds) C:\Temp\PatronDump2.zip Deleted... ( 9609 milliseconds) Finished... ( 9610 milliseconds) Press any key...
@benedicttobias I suspect it's because SftpClient.Exists() is bugged and cannot reliably determine if a directory exists when the path begins with a forward-slash character (/). Your ftpPath value (/alma/test/PatronDump2.zip) does appear to fit that use-case. Could you do me a favor and try using the same value without the leading slash (i.e. alma/test/PatronDump2.zip) and see if that workaround fixes things for you?
The issue with this is the 'Create' code:
client.Create(ftpPath + zipFileName);
This opens an SftpFileStream, which holds a lock on the just created file until the stream is closed or the session has ended, thus preventing the delete.
Adding a using statement will correct this by disposing of the SftpFileStream and releasing the lock, allowing the deletion without terminating the current session.
using(var sftpFileStream = client.Create(ftpPath + zipFileName)){}