如何使用 ChoETL 附加到同一个 csv 文件?
How to append to the same csv file with ChoETL?
目前我在下面的代码调用 JsonToCsv() 来解析 JSON 文件并相应地附加到 csv,所以结果是这样的:
result.csv
File Name Page Practice Name
file1.json 1 Associates & Co
但是,如您所见,我正在使用 for 循环迭代一堆 JSON 文件,我的意图是解析它们并将它们附加到 csv。所以如果我有 3 json 个文件,预期的 csv 文件应该像这样:
File Name Page Practice Name
fileXYZ.json 1 XYZ & Co
fileAB2.json 1 ABC & Co
file1.json 1 Associates & Co
然而,发生的事情是 csv 文件被覆盖,我只能看到 csv 文件中最后一个文件的结果。我如何让它附加到同一个文件?
static void Main(string[] args)
{
//Output to CSV
foreach (var jsonFile in Directory.GetFiles(jsonFilesPath))
{
JsonToCsv(jsonFile, csvFilePath);
}
}
public static void JsonToCsv(string jsonInputFile, string csvFile)
{
using (var p = new ChoJSONReader(jsonInputFile).WithJSONPath("$..readResults"))
{
using (var w = new ChoCSVWriter(csvFile)//.WithFirstLineHeader())
.WithField("FileName", fieldName: "File Name")
.WithField("Page")
.WithField("PracticeName", fieldName: "Practice Name")
.WithFirstLineHeader()
)
{
// Limit the result to page 1 since the fields below only exist on the 1st page
w.Write(p
.Where(r1 => r1.page == 1)
.Select(r1 =>
{
var lines = (dynamic[])r1.lines;
return new
{
FileName = inputFile,
Page = r1.page,
PracticeName = lines[6].text,
};
}
));
}
}
}
第一个选项。我建议您更改方法签名以接受多个文件。
public static void JsonToCsv(IEnumerable<string> jsonInputFiles, string csvFile)
{
using (var w = new ChoCSVWriter(csvFile)
.WithField("FileName", fieldName: "File Name")
.WithField("Page")
.WithField("PracticeName", fieldName: "Practice Name")
.WithFirstLineHeader()
)
{
foreach (var jsonInputFile in jsonInputFiles)
{
using (var p = new ChoJSONReader(jsonInputFile).WithJSONPath("$..readResults"))
{
w.Write(p
.Where(r1 => r1.page == 1)
.Select(r1 =>
{
var lines = (dynamic[])r1.lines;
return new
{
FileName = inputFile,
Page = r1.page,
PracticeName = lines[6].text,
};
}
));
}
}
}
}
第二个选项。将 FileStream 与 Append 选项一起使用,并做一些额外的代码来处理不同的情况,请参阅评论。
using (var fs = new FileStream(@"D:\file.csv", FileMode.Append, FileAccess.Write))
{
using (var writer = new ChoCSVWriter(fs))
{
writer.WithField("FileName", fieldName: "File Name")
.WithField("Page")
.WithField("PracticeName", fieldName: "Practice Name");
if (fs.Position == 0) // we don't need header if file already existed before
{
writer.WithFirstLineHeader();
}
writer.Write(new
{
FileName = "Test",
Page = 1,
PracticeName = "Abc"
});
}
fs.Write(Environment.NewLine); // append new line carrier so we don't write to the same line when file reopened for writing
}
第三个选项 - 来自评论(基于第二个)。在创建和附加选项之间切换
bool someCondition = true;
FileMode fileMode = someCondition ? FileMode.Append : FileMode.Create;
using (var fs = new FileStream(@"D:\file.csv", fileMode, FileAccess.Write))
目前我在下面的代码调用 JsonToCsv() 来解析 JSON 文件并相应地附加到 csv,所以结果是这样的:
result.csv
File Name Page Practice Name
file1.json 1 Associates & Co
但是,如您所见,我正在使用 for 循环迭代一堆 JSON 文件,我的意图是解析它们并将它们附加到 csv。所以如果我有 3 json 个文件,预期的 csv 文件应该像这样:
File Name Page Practice Name
fileXYZ.json 1 XYZ & Co
fileAB2.json 1 ABC & Co
file1.json 1 Associates & Co
然而,发生的事情是 csv 文件被覆盖,我只能看到 csv 文件中最后一个文件的结果。我如何让它附加到同一个文件?
static void Main(string[] args)
{
//Output to CSV
foreach (var jsonFile in Directory.GetFiles(jsonFilesPath))
{
JsonToCsv(jsonFile, csvFilePath);
}
}
public static void JsonToCsv(string jsonInputFile, string csvFile)
{
using (var p = new ChoJSONReader(jsonInputFile).WithJSONPath("$..readResults"))
{
using (var w = new ChoCSVWriter(csvFile)//.WithFirstLineHeader())
.WithField("FileName", fieldName: "File Name")
.WithField("Page")
.WithField("PracticeName", fieldName: "Practice Name")
.WithFirstLineHeader()
)
{
// Limit the result to page 1 since the fields below only exist on the 1st page
w.Write(p
.Where(r1 => r1.page == 1)
.Select(r1 =>
{
var lines = (dynamic[])r1.lines;
return new
{
FileName = inputFile,
Page = r1.page,
PracticeName = lines[6].text,
};
}
));
}
}
}
第一个选项。我建议您更改方法签名以接受多个文件。
public static void JsonToCsv(IEnumerable<string> jsonInputFiles, string csvFile)
{
using (var w = new ChoCSVWriter(csvFile)
.WithField("FileName", fieldName: "File Name")
.WithField("Page")
.WithField("PracticeName", fieldName: "Practice Name")
.WithFirstLineHeader()
)
{
foreach (var jsonInputFile in jsonInputFiles)
{
using (var p = new ChoJSONReader(jsonInputFile).WithJSONPath("$..readResults"))
{
w.Write(p
.Where(r1 => r1.page == 1)
.Select(r1 =>
{
var lines = (dynamic[])r1.lines;
return new
{
FileName = inputFile,
Page = r1.page,
PracticeName = lines[6].text,
};
}
));
}
}
}
}
第二个选项。将 FileStream 与 Append 选项一起使用,并做一些额外的代码来处理不同的情况,请参阅评论。
using (var fs = new FileStream(@"D:\file.csv", FileMode.Append, FileAccess.Write))
{
using (var writer = new ChoCSVWriter(fs))
{
writer.WithField("FileName", fieldName: "File Name")
.WithField("Page")
.WithField("PracticeName", fieldName: "Practice Name");
if (fs.Position == 0) // we don't need header if file already existed before
{
writer.WithFirstLineHeader();
}
writer.Write(new
{
FileName = "Test",
Page = 1,
PracticeName = "Abc"
});
}
fs.Write(Environment.NewLine); // append new line carrier so we don't write to the same line when file reopened for writing
}
第三个选项 - 来自评论(基于第二个)。在创建和附加选项之间切换
bool someCondition = true;
FileMode fileMode = someCondition ? FileMode.Append : FileMode.Create;
using (var fs = new FileStream(@"D:\file.csv", fileMode, FileAccess.Write))