i'm trying to learn something new about uploading through ftp connection to another host.
i know how to upload single file. but what if i want to upload full folder with its full subfolders and files that exists on it?
this is my one single file upload
private void Form1_Load(object sender, EventArgs e)
{
Upload("Test.txt");
}
public void Upload(string fileToUpload)
{
try
{
FileInfo toUpload = new FileInfo(fileToUpload);
FtpWebRequest request = (FtpWebRequest)WebRequest.Create("ftp://127.0.0.1/" + toUpload.Name);
MessageBox.Show(WebRequestMethods.Ftp.ListDirectory);
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Credentials = new NetworkCredential("Uploader", "3635451");
Stream ftpStream = request.GetRequestStream();
FileStream file = File.OpenRead(fileToUpload);
int length = 1024;
byte[] buffer = new byte[length];
int bytesRead = 0;
do
{
bytesRead = file.Read(buffer, 0, length);
ftpStream.Write(buffer, 0, bytesRead);
}
while (bytesRead != 0);
file.Close();
ftpStream.Close();
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
i google'd alot about uploading folder but i have just failed
thank you in advance.
You could use the WinSCP library. It is free, and supports FTP as well as SFTP. I have found it easy to use, and works flawlessly.
The PutFiles method will process an entire folder, including sub-folders. It also has a SynchronizeDirectories method.
The answer is you cannot.
You may be interested by libraries for doing such operations, if not you can look at their source code.
If you want to upload a folder you have to create the folder on your FTP and then copy each file one by one.
Example of a folder on local:
/Folder/File1.txt
/Folder/File2.txt
If you want to upload the folder "Folder".
Create directory in FTP
Open the FTP directory
Copy "File1.txt"
Copy "File2.txt"
Related
I have to change an older C# script (created back in 2010 in C# Express) to use SFTP instead of FTP. It took some doing to get this script out of an old repository - and to download a version of C# 2010 Express to get the script open! But I finally managed it. I have never coded in C# so please be kind. We have several off-site PCs that need to transfer files to and from the server on their network. This script is a .dll which is referenced in several other programs on these systems, so I'll need to change the calls to this .dll in those scripts as well. I have researched using SFTP in C# and from what I've seen thought it was best to install Renci.SshNet, so that has been installed as a reference in the project. What I'm looking to do is change the function below to use SFTP instead of FTP, but I'm not really sure how to even begin -
public TimeSpan FTPTo(string strFTPServer, string strLocalFileandPath, string strFTPFileandPath, string strFTPUser, string strFTPPassword)
{
try
{
DateTime dtStart = DateTime.Now;
FtpWebRequest ftp = (FtpWebRequest)FtpWebRequest.Create(strFTPServer + "/" + strFTPFileandPath);
ftp.Proxy = null;
ftp.Credentials = new NetworkCredential(strFTPUser, strFTPPassword);
//userid and password for the ftp server to given
ftp.KeepAlive = true;
ftp.UseBinary = true;
ftp.Method = WebRequestMethods.Ftp.UploadFile;
FileStream fs = File.OpenRead(strLocalFileandPath);
byte[] buffer = new byte[fs.Length];
fs.Read(buffer, 0, buffer.Length);
fs.Close();
Stream ftpstream = ftp.GetRequestStream();
ftpstream.Write(buffer, 0, buffer.Length);
ftpstream.Close();
return DateTime.Now - dtStart;
}
catch (Exception ex1)
{
throw ex1;
}
}
Any suggestions/help would be greatly appreciated.
To upload a file to an SFTP server using SSH.NET, use SftpClient.UploadFile.
A trivial example is like:
var client = new SftpClient("example.com", "username", "password");
client.Connect();
using (var sourceStream = File.Open(#"C:\local\path\file.ext"))
{
client.UploadFile(sourceStream, "/remote/path/file.ext");
}
There's no relation to your original code. The API is completely different. You basically have to start from the scratch.
I have written a program that downloads a file from a remote ftp site and saves it to the local c drive then uploads that file to a separate server. The problem now is that when the file gets downloaded, there is no data inside the text file it creates on the local C and I can't figure out why that is. Here is the code I'm using
// Download File
public void download(string remoteFile, string localFile)
{
try
{
// Create an FTP Request
ftpRequest = (FtpWebRequest)FtpWebRequest.Create(downhost + "/" + remoteFile);
// Log in to the FTP Server with the User Name and Password Provided
ftpRequest.Credentials = new NetworkCredential(downuser, downpass);
// When in doubt, use these options
ftpRequest.UseBinary = true;
ftpRequest.UsePassive = true;
ftpRequest.KeepAlive = true;
/* Set HTTP Proxy to Null to avoid The Requested FTP Command Is Not Supported When Using HTTP Proxy error */
ftpRequest.Proxy = null;
// Specify the Type of FTP Request
ftpRequest.Method = WebRequestMethods.Ftp.DownloadFile;
// Establish Return Communication with the FTP Server
ftpResponse = (FtpWebResponse)ftpRequest.GetResponse();
// Get the FTP Server's Response Stream
ftpStream = ftpResponse.GetResponseStream();
// Open a File Stream to Write the Downloaded File
FileStream localFileStream = new FileStream(localFile, FileMode.Create);
// Buffer for the Downloaded Data
byte[] byteBuffer = new byte[bufferSize];
int bytesRead = ftpStream.Read(byteBuffer, 0, bufferSize);
// Download the File by Writing the Buffered Data Until the Transfer is Complete
try
{
while (bytesRead > 0)
{
localFileStream.Write(byteBuffer, 0, bytesRead);
bytesRead = ftpStream.Read(byteBuffer, 0, bufferSize);
}
}
catch (Exception ex) { Console.WriteLine(ex.ToString()); }
// Resource Cleanup
localFileStream.Close();
ftpStream.Close();
ftpResponse.Close();
ftpRequest = null;
}
catch (Exception ex) { Console.WriteLine(ex.ToString()); }
return;
}
I used the code found at http://www.codeproject.com/Tips/443588/Simple-Csharp-FTP-Class as the basis to build my program off of and I've done Google searches on how other people have written their ftp download scripts but can't figure out any reason why the data isn't being written.
Any help is appreciated.
Flush the file. Call localFileStream.Flush(); before you close it.
I realise that this is a bit late, but i was having the same issue trying to use that example, i managed to get a FTP download working with an example from here:
http://www.techrepublic.com/blog/howdoi/how-do-i-use-c-to-upload-and-download-files-from-an-ftp-server/165
I'm having issues with the same method. I did find a way to get the system to work but I had to copy the ftpstream in your code to another stream like this: (in vb.net, I know, I'm sorry)
ftpStream.copyTo(MySecondStream)
ftpStream.close()
'do whatever you want with the copy now
Return MySecondStream
Maybe it has something to do with how the initial stream is handled and how long it stays open. I posted my question here: Why do I have to copy an FTP stream to another variable to return it to the calling method?
I had the same problem on an upload. 0 bytes written. Code was working on one FTP server, but not on another. Just had to do the following:
client.FtpStream.Flush();
client.FtpStream.Close();
I have an application that uses a template file and a CSV file. It works perfectly fine since I do have the said files on my computer and I am referencing their paths. The only thing I want to do is that when the software is published and installed (and the said files are in the Resources folder so it would make them an embedded resource), the csv and template files would be copied to a directory folder that my program would use. Preferably the paths it would be copied to would be something like this : "C:\FILES" + template.dotx .
Now how do I get/retrieve the said files from the Resources Folder in my software into a new folder?
You could call
System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceNames();
And inspect which embedded resources are accessible. Then you can compare that against what you are passing in to see if you are indeed accomplishing what you expected to.
string FileExtractTo = "C:\FILES";
DirectoryInfo dirInfo = new DirectoryInfo(FileExtractTo);
if (!dirInfo.Exists())
dirInfo.Create();
using (Stream input = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
using (Stream output = File.Create(FileExtractTo + "\template.dotx"))
{
CopyStream(input, output);
}
CopyStream Method:
public static void CopyStream(Stream input, Stream output)
{
// Insert null checking here for production
byte[] buffer = new byte[8192];
int bytesRead;
while ((bytesRead = input.Read(buffer, 0, buffer.Length)) > 0)
{
output.Write(buffer, 0, bytesRead);
}
}
I have a windows form application in which i am using a background worker to ftp upload files. After uploading 209 files successfully it gave error on file which only had size of 7.8kb that While Processing Img1.jpg Unable to write data to the transport connection. An existing connection was forcibly closed by the remote host.
string uri1;
ftpInfoUpload = LoadHostedSiteData(hs);
ftpInfoUpload[5] = imgRow["Filename"].ToString();
uri1 = String.Format("ftp://{0}/{1}/images/{2}", ftpInfoUpload[1], ftpInfoUpload[2], ftpInfoUpload[5]);
requestUpload = (FtpWebRequest)WebRequest.Create(uri1);
requestUpload.UsePassive = false;
requestUpload.UseBinary = true;
requestUpload.Method = WebRequestMethods.Ftp.UploadFile;
requestUpload.Credentials = new NetworkCredential(ftpInfoUpload[3], ftpInfoUpload[4]);
requestUpload.ContentLength = memStream.Length;
byte[] buff = new byte[bufferSize];
int contentLen;
// Stream to which the file to be upload is written
Stream strm = requestUpload.GetRequestStream();
memStream.Seek(0, SeekOrigin.Begin);
contentLen = memStream.Read(buff, 0, bufferSize);
// Till Stream content ends
while (contentLen > 0)
{
// Write Content from the file stream to the FTP Upload Stream
strm.Write(buff, 0, contentLen);
contentLen = memStream.Read(buff, 0, bufferSize);
}
//Close the file stream and the Request Stream
strm.Close();
strm.Dispose();
ftpStream.Close();
memStream.Close();
//responseUpload.Close();
responseDownload.Close();
And ideas whats happening?
I have set ftprequest.KeepAlive=true & set ftprequest.ConnectionGroupName = "Some Value", so that underlying code does not have to new create connection which have the same ftp server. I found this solution here. I also found this helpful. Also make sure not to create a new NetworkCredential object everytime you transfer a file that can cause exception. I have tested my code twice transferring 300 files and seems to work perfectly and quick. Setting KeepAlive=false can make transfers slow
I'm trying to create a ZIP file on the fly which might contain a few thousands of pictures.
public static void CompressAndSendFiles(List files)
{
HttpContext.Current.Response.ClearContent();
// LINE1: Add the file name and attachment, which will force the open/cance/save dialog to show, to the header
HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=\"Jpeg Package "
+ DateTime.Now.ToString("MM-dd-yyyy hh-mm-ss") + ".zip\"");
// Add the file size into the response header
//HttpContext.Current.Response.AddHeader("Content-Length", file.Length.ToString());
// Set the ContentType
HttpContext.Current.Response.ContentType = ReturnHttpContentType("download.zip");
ZipOutputStream oZipStream =
new ZipOutputStream(HttpContext.Current.Response.OutputStream);
try
{
foreach (string file in files)
{
FileInfo fInfo = new FileInfo(file);
ZipEntry oZipEntry = new ZipEntry(fInfo.Name);
oZipStream.PutNextEntry(oZipEntry);
byte[] buffer = File.ReadAllBytes(file);
oZipStream.Write(buffer, 0, buffer.Length);
//oZipStream.Flush();
}
}
catch (Exception ex)
{
throw ex;
}
finally
{
oZipStream.Finish();
oZipStream.Close();
oZipStream.Dispose();
}
HttpContext.Current.Response.OutputStream.Flush();
HttpContext.Current.Response.End();
}
Everything is fine, unless when number of files get big.
My question:
Is there a way to initiate the download (let the download manager on client side popup), and then start writing on the stream?
I monitored w3wp.exe (IIS) process, and it seems that the data is being written on memory instead of Stream. When w3wp.exe memory usage riches a certain number, it releases the memory and nothing happens (no download).
Thank you in advance.
Have you tried using this?
HttpContext.Current.Response.BufferOutput = false;
As far as I know, you cannot stream it while archiving. You need to zip them first, then stream it. As the result, server is finally out of memory if the final zip is extremely large.
What I end up doing is I write it to a temporary zip file then stream that temporary file.