在form1中我有两个按钮,用于从目录单个文件或多个文件中选择文件。 第二个按钮是从目录中选择文件以获取所选目录中的所有文件。
现在我有一个班级我用来将文件/目录上传到我的ftp: 在课程的顶部,我做了:
public static DirectoryInfo d;
public static string[] files;
private FileInfo[] dirflist;
然后我在事件中使用它:
private void FtpProgress_DoWork(object sender, DoWorkEventArgs e)
{
try
{
dirflist = d.GetFiles();
//if (dirflist.Length > 0)
//{
foreach (string txf in files)
{
string fn = txf;//txf.Name;
BackgroundWorker bw = sender as BackgroundWorker;
f = e.Argument as FtpSettings;
string UploadPath = String.Format("{0}/{1}{2}", f.Host, f.TargetFolder == "" ? "" : f.TargetFolder + "/", Path.GetFileName(fn));//f.SourceFile));
if (!UploadPath.ToLower().StartsWith("ftp://"))
UploadPath = "ftp://" + UploadPath;
FtpWebRequest request = (FtpWebRequest)WebRequest.Create(UploadPath);
request.UseBinary = true;
request.UsePassive = f.Passive;
request.Method = WebRequestMethods.Ftp.UploadFile;
request.Timeout = 300000;
request.Credentials = new NetworkCredential(f.Username, f.Password);
long FileSize = new FileInfo(f.SourceFile).Length;
string FileSizeDescription = GetFileSize(FileSize);
int ChunkSize = 4096, NumRetries = 0, MaxRetries = 50;
long SentBytes = 0;
byte[] Buffer = new byte[ChunkSize];
using (Stream requestStream = request.GetRequestStream())
{
using (FileStream fs = File.Open(f.SourceFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
int BytesRead = fs.Read(Buffer, 0, ChunkSize);
while (BytesRead > 0)
{
try
{
if (bw.CancellationPending)
return;
requestStream.Write(Buffer, 0, BytesRead);
SentBytes += BytesRead;
string SummaryText = String.Format("Transferred {0} / {1}", GetFileSize(SentBytes), FileSizeDescription);
bw.ReportProgress((int)(((decimal)SentBytes / (decimal)FileSize) * 100), SummaryText);
}
catch (Exception ex)
{
Debug.WriteLine("Exception: " + ex.ToString());
if (NumRetries++ < MaxRetries)
{
fs.Position -= BytesRead;
}
else
{
throw new Exception(String.Format("Error occurred during upload, too many retries. \n{0}", ex.ToString()));
}
}
BytesRead = fs.Read(Buffer, 0, ChunkSize);
}
}
}
using (FtpWebResponse response = (FtpWebResponse)request.GetResponse())
System.Diagnostics.Debug.WriteLine(String.Format("Upload File Complete, status {0}", response.StatusDescription));
}
//}
}
catch (WebException ex)
{
switch (ex.Status)
{
case WebExceptionStatus.NameResolutionFailure:
ConnectionError = "Error: Please check the ftp address";
break;
case WebExceptionStatus.Timeout:
ConnectionError = "Error: Timout Request";
break;
}
}
}
现在我正在对string []数组进行循环。 因为我只选择多个文件。
但可能有一种情况我会选择一个目录。然后我将需要使用DirectoryInfo(d变量)和FileInfo []
如果我正在使用FileInfo []那么它就是这样的:
dirflist = d.GetFiles();
if (dirflist.Length > 0)
{
foreach (FileInfo txf in dirfilist)
{
string fn = txf.Name;
但我不想再为了字符串[]或仅为FileInfo []复制所有代码 我想制作一些东西,我将能够使用foreach中的FileInfo []或foreach中的字符串[]。
也许有时我会同时使用上传多个文件,然后上传包含所有文件的目录。
所以也许最好复制整个代码并使用一次string []和一次FileInfo []? 我的意思是制作两个方法,一个将使用FileInfo []一个字符串[]
答案 0 :(得分:1)
将处理单个文件的所有代码放入一个单独的方法中:
private void CopyFile(string fn)
{
BackgroundWorker bw = sender as BackgroundWorker;
f = e.Argument as FtpSettings;
...
}
现在决定你要做文件列表的东西还是dir list的东西,然后像这样调用你的新方法:
文件-列表:强>
foreach (string txf in files)
{
this.CopyFile(txt);
}
<强>目录 - 列表:强>
dirflist = d.GetFiles();
if (dirflist.Length > 0)
{
foreach (FileInfo txf in dirfilist)
{
this.CopyFile(txt.Name);
}
}
答案 1 :(得分:1)
我如何根据需要使用
FileInfo[]
或者如果需要string[]
?
private void SomeMethod(args)
{
// ...
/* Here I need a specific String Value, or Array of String Values
but sometimes I got it from an array of File,
and sometimes from an array of FileInfo... */
// Call a Function that always returns an array of String
files = GetMyFiles(args);
// resume the job using only files...
/* or replace the above that always manipulates an arrays of FileInfo-s
if you must use FileInfo-s */
}
然后你可以通过传递你想要的任何参数来重载你的函数GetMyFiles。
string[] GetMyFiles(String DirectoryPath)
// Returns an Array of String that contains all the Files in the Directory.
string[] GetMyFiles(FileInfo MyFileInfo)
// Returns an Array of String with just one File Path.
string[] GetMyFiles()
// Opens a MultiSelect OpenFileDialog,
// then returns the selected Files Path in an Array (or empty Array)
// ...
另一种方式:将您的代码分成多个部分,然后通过条件检查确定您将使用哪个部分......
private void FtpProgress_DoWork(object sender, DoWorkEventArgs e)
{
// Do the maximum you can do here...
// ...
if ImGoingToUseStringArray
{
string[] files = ....
ResumeWithStringArray(files, sender, e);
}
else
{
FileInfo[] dirflist = ....
ResumeWithFileInfo(dirfList, sender, e);
}
}
private void ResumeWithStringArray(string[] files, object sender, DoWorkEventArgs e)
{
// ...
// you can also call another core Function from here
sendMyFile(args)
}
private void ResumeWithFileInfo(FileInfo[] dirflist, object sender, DoWorkEventArgs e)
{
// ...
// you can also call another core Function from here
sendMyFile(args)
}
无论如何,你必须使用FileInfo来获取FileSize(我假设的文件传输需要)吗?但是,您决定创建FileInfo 每个文件的那一刻(或者您是否同时使用多个FileInfo?)如果您认为您的代码过于复杂,而且FileInfo的列表/数组来自开始时,只需在需要时动态创建FileInfo的每个实例(将代码分割成部分)
在我看来,您的问题的答案仅取决于您的品味,或者只需要对您运行逻辑的方式进行一些更改。