如果需要,我如何使用FileInfo []或如果需要字符串[]?

时间:2014-11-29 19:12:21

标签: c# .net winforms

在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 []一个字符串[]

2 个答案:

答案 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的每个实例(将代码分割成部分)

在我看来,您的问题的答案仅取决于您的品味,或者只需要对您运行逻辑的方式进行一些更改。