[英]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
,並在循環中使用ExtractFile
和ProcessFile
。 要勾勒出這個想法:
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.