簡體   English   中英

如何在C#中以更好的方式提取和處理文件

[英]how to extract and process file in a better way in c#

我在FTP位置上存儲了大約5000個文件。因此,首先我必須從FTP下載文件,然后必須解壓縮.gz文件,最后我必須處理該文件並將數據推送到oracle數據庫。我使用了TamirSSh程序集以從FTP和ionic.zip檢索到解壓縮文件。 但是Downloadfile() ,Extractfile() and ProcessFile()方法需要花費很長時間才能完成。用c#下載,解壓縮和處理文件的更好方法是什么。這是一個控制台應用程序

static void Main(string[] args)
    {
        Downloadfile();
    }

private static void Downloadfile()
{
     //Download 5000 file
       Sftp ftp = new Sftp(dtr["FTP_SERVER"].ToString(), dtr["FTP_USER_ID"].ToString(), dtr["FTP_PASSWORD"].ToString());
                                    ftp.Connect<ftp://ftp.connect/>();
                                    System.IO.Directory.CreateDirectory(@localDestnDir);
                                    ArrayList list;
                                    list = ftp.GetFileList(remotepath<ftp://ftp.getfilelist(remotepath/>);
                                    //GExport_EI_DN_G_6542_StarMetroDeiraHotel&Apartment_10.235.155.37_20161120003108.xml.gz
                                    foreach (string item in list)
                                    {
                                        if (item.StartsWith("GExport_") &&(!item.ToUpper().Contains("DUM")))
                                        {
                                            path = item;
                                            //path = "GExport_EI_DN_G_6542_StarMetroDeiraHotel&Apartment_10.235.155.37_20161120003108.xml.gz";
                                            ftp.Get(dtr["REMOTE_FILE_PATH"].ToString() + path, @localDestnDir + "\\" + dtr["SOURCE_PATH"].ToString());
                                            download_location_hw = dtr["LOCAL_FILE_PATH"].ToString();
                                          //  ExtractZipfiles(download_location_hw + "//" + path, dtr["REMOTE_FILE_PATH"].ToString(), dtr["FTP_SERVER"].ToString(), dtr["FTP_USER_ID"].ToString(), dtr["TECH_CODE"].ToString(), dtr["VENDOR_CODE"].ToString());
                                        }
                                    }
                                    ftp.Close();
        //extract 5000 file by using Ionic.zip 
                    Extractfile();
        //then process 5000 files
        ProcessFile();
}

但是Downloadfile(),Extractfile()和ProcessFile()方法需要花費很長時間才能完成。用c#下載,解壓縮和處理文件的更好方法是什么。這是一個控制台應用程序

pipleline基本上下載壓縮文件,提取並處理就可以了。 但是,當您的系統正在處理時,它可以並行下載下一個,因為與解壓縮和處理相比,網絡傳輸不占用大量CPU。

一種非常簡單,快速的方法是在循環中使用Parallel.ForEach ,並在循環中使用ExtractFileProcessFile 要勾勒出這個想法:

private static void Downloadfile()
{
    //Download 5000 file
    Sftp ftp = new Sftp(dtr["FTP_SERVER"].ToString(), dtr["FTP_USER_ID"].ToString(), dtr["FTP_PASSWORD"].ToString());
    ftp.Connect<ftp://ftp.connect/>();
    System.IO.Directory.CreateDirectory(@localDestnDir);       
    var list = ftp.GetFileList(remotepath).ToList();

    Parallel.ForEach(list, item => 
        {
            if (item.StartsWith("GExport_") &&(!item.ToUpper().Contains("DUM")))
            {
                path = item;
                //path = "GExport_EI_DN_G_6542_StarMetroDeiraHotel&Apartment_10.235.155.37_20161120003108.xml.gz";
                ftp.Get(dtr["REMOTE_FILE_PATH"].ToString() + path, @localDestnDir + "\\" + dtr["SOURCE_PATH"].ToString());
                download_location_hw = dtr["LOCAL_FILE_PATH"].ToString();
                //  ExtractZipfiles(download_location_hw + "//" + path, dtr["REMOTE_FILE_PATH"].ToString(), dtr["FTP_SERVER"].ToString(), dtr["FTP_USER_ID"].ToString(), dtr["TECH_CODE"].ToString(), dtr["VENDOR_CODE"].ToString());
            }

            //extract file by using Ionic.zip 
             Extractfile(item);   <= Extractfile works on a single file now
            //then process file
            ProcessFile(item);    <= ProcessFile works on a single file now
        });
        ftp.Close();

}

如果不看所有代碼,很難說,但是很可能您將從並行化中受益。 現在,這在C#中非常容易實現。 代替您當前正在使用的foreach循環,請嘗試如下操作:

        Parallel.ForEach(list.ToArray(), item => {
            // Download the item with ftp.Get
            // Unzip the file you just downloaded
            // Process the file
        });

這樣的速度優勢是,您將在計算機也等待下載下一個文件的同時,對第一個文件進行脫機處理(解壓縮,處理)。

現在,這將嘗試一次下載多個文件。 那可能不是一個好主意,因為您可能不堪重負FTP服務器。 因此,另一種方法是一次下載一個文件,然后在前台繼續下載另一個文件時立即在后台處理每個文件:

        Task[] myTasks = new Task[list.Count];
        int i = 0;
        foreach (string item in list)
        {
            // Download the item with ftp.Get and store its location in download_location_hw
            ftp.Get(dtr["REMOTE_FILE_PATH"].ToString() + path, @localDestnDir + "\\" + dtr["SOURCE_PATH"].ToString());
            string download_location_hw = dtr["LOCAL_FILE_PATH"].ToString();
            // Spin off a background task to process the file we just downloaded
            myTasks[i++] = Task.Run(() => {
                // Extract the zip file referred to by  download_location_hw
                // Process the extracted zip file
            });
        }
        Task.WaitAll(myTasks);

對於這兩個示例,請確保您正在using System.Threading.Tasks;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM