there is a project assigned to me that create some files and send those files using SFTP to some server. there is another programme to read and send that files to another place(the files first programme sent to the server). it checks continuously new files from the server and read it and send. but the problem is sometimes the second program read files not completely imported to that server. that cause system to crash. they told me to do change in the first program before sending files, rename the files first and send and after finished upload rename again the sent files, files that in the server. is this possible to or is a there better way to do this. is there anyone have some ideas I'm kindly asking to share with me
That it's a good synchronization method, I mean using a temporary name during the transfer and the rename at once at the end.
The implementation depends on which approach you've used in the program.
It should be something like this:
// Rename the file or directory:
success = sftp.RenameFileOrDir("oldFilename.txt","newFilename.txt");
if (success != true) {
Console.WriteLine(sftp.LastErrorText);
return;
}
Basically:
Catch the event of transfer completed
Request the RENAME command
Related
I'm experiencing an issue with an FTP watcher service and the File.Move method.
The FTP server is a simple IIS 8.5 FTP site and the FTP client is FileZilla FTP Client
The windows service will poll a directory where the files are to be dropped.
The first task is to rename the file, using the static File.Move method.
The second, is to copy the file to another directory using the static File.Copy method.
The issue is that while the file is being transferred, the File.Copy will [correctly] throw an IO Exception if it is used, with the message "The file is being used by another process".
However the File.Move will perform it's task without throwing any exception while the file is still being transferred. Is this the correct behavior for this method? I've not been able to find any information on why this occurs. My impression was that the File.Move would throw an exception if it's used on a file that's being used by another process [The FTP Transfer] but it doesn't seem to.
Has anyone experienced this and / or have an explanation for the behavior of the File.Move method
Copying a file requires opening it for read access. The FTP server currently has the file open such that you cannot open it for reading.
Moving a file does not require opening it for read access unless the file is on a different volume than the destination.
Since moving a file to the same volume requires only delete access and not read access, the FTP server must lock the files for read and write, but not delete.
This code shows that File.Move will indeed throw an exception if the file is in use when you try to move it, so I think your premise is incorrect.
var filePath = #"d:\public\temp\temp.txt";
var moveToPath = #"d:\public\temp\temp2.txt";
// Create a stream reader so the file is 'in use'
using (var fileStream = new StreamReader(filePath))
{
// This will fail with an IO exception
File.Move(filePath, moveToPath);
}
Exception:
The process cannot access the file because it is being used by another process.
Moving a file is effectively implemented as a mere rename and only requires write permission on the target and source directory. For a real copy you need read permissions on the file itself. As there is an exclusive lock on the source file, the copy will fail, however, the move will succeed.
I have a ftp application. This application uses ftp rename command. If a file already exists in a directory which the file is renamed to, the error message 'the file not avaliable' caught. What can I do in c# to overwrite a file? In IIS there is a setting for this. When I do this, there is no problem.But,can I do this from c#?
What happens when there is a name collision depends on the server, if you cannot configure a known behaviour on each server you connect to you need to deal with it manually.
Either attempt a rename, catch the exception, delete the file then rename again or check for the files existence first (by requesting it size for example) and deleting it if found.
I have a job that needs to connect to two fileshares and copy some files for a data feed.
The source server is on our domain's network, and that works fine. The remote server, however, chokes on me and throws a "Could not find part of the path" error. I should add the destination server lives in a different domain than my source server.
The source and destination paths are read out of my app.config file.
I thought persistently mapping a drive would work, but since this is a scheduled task, that doesn't seem to work. I thought about using NET USE, but that doesn't seem to like taking a username and password.
The really weird thing - if I double click on the job while I'm logged into the machine, it'll run successfully.
Sample code:
DirectoryInfo di = new DirectoryInfo(srcPath);
try
{
FileInfo[] files = di.GetFiles();
foreach (FileInfo fi in files)
{
if(!(fi.Name.Contains("_desc")))
{
Console.WriteLine(fi.Name + System.Environment.NewLine);
File.Copy(fi.FullName, destPath + fi.Name, true);
fi.Delete();
}
}
}
Apparently this isn't as simple as copying the files over. Any suggestions on mapping a drive with credentials in C# 4.0?
EDIT
I'm trying to use a batch file called from the console application that maps the drive while the program is running. I'll know for sure whether that works in the morning.
I'd suggest looking into a proper file transfer protocol, like FTP.
Assuming that's out of the question, try using a UNC path like \\servername\path\file.txt. You will still need credentials, but assuming that the account running the application has those permissions you should be fine. Given that you mention a web.config file, I am guessing that would be an ASP.NET application, and therefore I mean the account that runs the Application Pool in IIS. See http://learn.iis.net/page.aspx/624/application-pool-identities/
What I finally wound up doing was mapping the drive in a batch file called by my program. I just launch a NET USE command and pause for a few seconds for the mapping to complete.
It looks like while the user is logged out, there's no context around mapped drives.
Using the .NET assembly of WinSCP to upload a file. OperationResultBase.Check() is throwing the following error:
WinSCP.SessionRemoteException: Transfer was successfully finished, but temporary transfer file 'testfile.zip.filepart' could not be renamed to target file name 'testfile.zip'. If the problem persists, you may want to turn off transfer resume support.
It seems that this happens with any zip file that I try to send. If it makes a difference, these are zip files that were created using the DotNetZip library.
Code that I'm using, taken pretty much directly from the example in the WinSCP documentation:
public void uploadFile(string filePath, string remotePath)
{
TransferOptions transferOptions = new TransferOptions();
transferOptions.TransferMode = TransferMode.Binary;
TransferOperationResult transferResult;
transferResult = currentSession.PutFiles(filePath, remotePath, false, transferOptions);
transferResult.Check();
foreach (TransferEventArgs transfer in transferResult.Transfers)
{
Console.WriteLine("Upload of {0} succeeded", transfer.FileName);
}
}
Discussion over at the WinSCP forum indicates that the assembly doesn't yet allow programmatic control of transfer resume support. Is there a workaround for this?
It sounds as if the filesystem on the destination server where the file is getting uploaded to does not allow file change permissions. This could be causing the renaming of the file at the finish of the upload to fail despite the fact that the complete file was uploaded and written to the filesystem with the temporary file name used while the transfer was in progress. If you don't have administrative access to the destination server, you can test that by trying to rename a file that is already on the destination server. If that fails also, then you will either need to have the proper permissions on the destination server changed in order for that to work. Otherwise you might have to use the advice provided in your error message to turn off the resume support so it is initially opened for writing with the desired filename instead of the temporary filename (with the .filepart extension).
Turn off the resumesupport:
put *.txt -nopreservetime -nopermissions -resumesupport=off
It would help, if you included full error message, including root cause as returned by the server.
My guess is that there's an antivirus application (or similar) running on the server-side. The antivirus application checks any file once upload finishes. That conflicts with WinSCP attempt to rename the file once the upload is finished. The problem may tend to occur more frequently for .ZIP archives, either because they tend to be larger or simply because they need to get extracted before the check (what takes time).
Anyway, you can disable the transfer to temporary file name using the TransferOptions.ResumeSupport.
See also the documentation for the error message "Transfer was successfully finished, but temporary transfer file ... could not be renamed to target file name ..."
All you have to do is to disable TransferResumeSupport using the below code.
transferOptions.ResumeSupport = new TransferResumeSuppor {State = TransferResumeSupportState.Off };
My client has configured a SFTP server and monitoring the folder using FileWatcher. As soon s as the file are copied to SFTP server, client picks them.
If the connection is broke down while transferring the file, client picks the invalid file.
In between, I go for deleting the invalid file, client has already picked and delete that file from that folder.
How I can stop access for client to that file until I finish the full transaction.
There exist two generic options - upload the file to different folder and move it (you have denied this for your particular case) and upload the file with different name and rename the file once upload is complete.
If you control the server's architecture, you can do the following trick: upload the file with the name of filename..ext . The server will check the file name and know expected size. Once the file is of specified size, it can be picked and renamed by the server.
You should use a temporary folder for upload, and move the files in the monitored folder only when the file is completely upload.