Quá trình này sẽ là một cái gì đó như thế này:
- Mở
StreamWriter
vào một tập tin tạm thời.
- Mở một
StreamReader
vào tệp đích.
- Đối với mỗi dòng:
- Tách văn bản thành các cột dựa trên dấu tách.
- Kiểm tra các cột cho các giá trị bạn muốn thay thế và thay thế chúng.
- Tham gia các giá trị cột lại với nhau bằng dấu phân cách của bạn.
- Viết dòng vào tệp tạm thời.
- Khi bạn hoàn tất, xóa tệp đích và di chuyển tệp tạm thời sang đường dẫn tệp đích.
Lưu ý về bước 2 và 3.1: Nếu bạn tin tưởng vào cấu trúc tệp của mình và đơn giản là đủ, bạn có thể thực hiện tất cả điều này như được mô tả (Tôi sẽ đưa mẫu vào một lúc). Tuy nhiên, có các yếu tố trong tệp CSV có thể cần chú ý (chẳng hạn như nhận ra khi dấu phân cách đang được sử dụng theo nghĩa đen trong giá trị cột). Bạn có thể tự mình thực hiện điều này hoặc thử một số existing solution.
Basic dụ chỉ sử dụng StreamReader
và StreamWriter
:
var sourcePath = @"C:\data.csv";
var delimiter = ",";
var firstLineContainsHeaders = true;
var tempPath = Path.GetTempFileName();
var lineNumber = 0;
var splitExpression = new Regex(@"(" + delimiter + @")(?=(?:[^""]|""[^""]*"")*$)");
using (var writer = new StreamWriter(tempPath))
using (var reader = new StreamReader(sourcePath))
{
string line = null;
string[] headers = null;
if (firstLineContainsHeaders)
{
line = reader.ReadLine();
lineNumber++;
if (string.IsNullOrEmpty(line)) return; // file is empty;
headers = splitExpression.Split(line).Where(s => s != delimiter).ToArray();
writer.WriteLine(line); // write the original header to the temp file.
}
while ((line = reader.ReadLine()) != null)
{
lineNumber++;
var columns = splitExpression.Split(line).Where(s => s != delimiter).ToArray();
// if there are no headers, do a simple sanity check to make sure you always have the same number of columns in a line
if (headers == null) headers = new string[columns.Length];
if (columns.Length != headers.Length) throw new InvalidOperationException(string.Format("Line {0} is missing one or more columns.", lineNumber));
// TODO: search and replace in columns
// example: replace 'v' in the first column with '\/': if (columns[0].Contains("v")) columns[0] = columns[0].Replace("v", @"\/");
writer.WriteLine(string.Join(delimiter, columns));
}
}
File.Delete(sourcePath);
File.Move(tempPath, sourcePath);
trong trường hợp như vậy tại sao bạn không thử sử dụng Hadoop MapReduce .... –
Bạn sẽ có thể làm thay đổi chỉ khi dòng sửa đổi sẽ có chiều dài mà không vượt gốc dòng dài –
Tại sao không chỉ viết thư cho một tập tin mới? Vì vậy: 1. Đọc 2. Sửa đổi 3.Write để sao chép. Đó có phải là điều bạn không muốn làm hay chỉ là tìm kiếm một cách "thanh lịch" để làm điều này? – StampedeXV