-1

我正在创建一个应用程序,它很快从互联网上抓取两个文件,检查它们并创建第三个文件。抓取部分的部分已经完成,所以目前我有两个文件。

第一个是一个 .txt 文件,其中包含如下文本:

Order Code|Stock
ACREPAIR|1031
AF813|18
AF823|12
AFCOB11|21
AFCS300|33
AFCS3000|1
AFEM4|5
AFOMNI|17
AFOX2|-3
AFOX3|-3
AFROD|28
AFSENSOR|50
AFUF21|24
AN00001|-1
AN00002|21
AN00003|4
AN00004|4
AN00005|9
...

该文件每一行中的文本是某个项目的代码和一个项目的库存(目前有多少产品可用)。有数十万条这样的行

然后我有另一个文件,它也是一个 .txt,格式如下:

Action,CategoryPath,ID,Name,Code,Stock
"Product","Home > Opto-electronics > LED > Standard LED, Multicolour",2226,"KINGBRIGHT LED, 3MM, HE-RED/GRN L-93WEGW","SC07621",202
"Product","Home > Resistors > Fixed",2228,"VISHAY DRALORIC RESISTOR, 0402, 5%, 10K0 CRCW040210K0JNEAIF","RE06211",0
"Product","Home > Resistors > Fixed",2229,"VISHAY DRALORIC RESISTOR, 0402, 5%, 3R90 CRCW04023R90JNEAIF","RE06212",0
"Product","Home > Resistors > Fixed",2230,"VISHAY DRALORIC RESISTOR, 0402, 5%, 2R70 CRCW04022R70JNEAIF","RE06220",25
"Product","Home > Resistors > Fixed",2231,"VISHAY DRALORIC RESISTOR, 0402, 5%, 33R0 CRCW040233R0JNEAIF","RE06221",0
"Product","Home > Resistors > Fixed",2232,"VISHAY DRALORIC RESISTOR, 0402, 5%, 100R CRCW0402100RJNEAIF","RE06226",0
"Product","Home > IC's > Comparators",2234,"STMICROELECTRONICS IC, COMPARATOR DUAL, DIP8, 393 LM393N","SC10207",57
"Product","Home > IC's > Amplifiers > Operational",2237,"STMICROELECTRONICS OP AMP, QUAD JFET, DIP14 TL084CN","SC07929",82
"Product","Home > IC's > Amplifiers > Audio Power",2239,"NATIONAL SEMICONDUCTOR AMP, AUDIO 0.25W, DIP8, 386 LM386N-1","SC08430",83
"Product","Home > IC's > Microcontrollers",2241,"MICROCHIP 8BIT FLASH MCU, 12F675, DIP8 PIC12F675-I/P","ACREPAIR",16
...

我的问题来了。我需要我的应用程序从第一个文件中获取一行,分别获取代码和库存,然后在第二个文件中找到匹配的代码并比较库存值。如果它们在第二个文件中不同,则库存将替换为第一个文件中的库存价值。但如果值相同,则应删除第二个文件中包含代码和相同股票值的行(替换为空)。

需要解释的部分:

  1. 如何通过获取由代码 ex 组成的几个变量来读取第一个文件。ACREPAIR和股票前。1031

  2. 如何在第二个文件中找到代码如下所示的行:“产品”、“主页 > IC 的 > 微控制器”、2241、“MICROCHIP 8BIT FLASH MCU、12F675、DIP8 PIC12F675-I/P”、“ ACREPAIR ” ,16并且 16 将被 1031 替换,或者如果值相同,则将从第二个文件中删除该行。

我将非常感谢有关如何做到这一点的建议甚至片段。

4

3 回答 3

3

我希望这对开始有任何帮助。Skip完成调用以跳过文件的标题行。请注意,可以通过多种方式优化此代码(使用 aHashSet而不是数组 for compareTo,避免硬编码拆分索引等),但我相信您有责任这样做。

var items = File.ReadAllLines("file1.txt").
    Skip(1).
    Select(s =>
    {
        var strings = s.Split('|');
        if (strings.Length != 2) throw new FormatException();
        return new {Code = strings[0], Stock = Convert.ToInt32(strings[1])};
    }).
    ToArray();
var compareTo = File.ReadAllLines("file2.txt").
    Skip(1).
    Select(s =>
    {
        var strings = s.Split(',');
        if (strings.Length != 6) throw new FormatException();
        return new {Code = strings[4].Trim('"'), Stock = Convert.ToInt32(strings[5])};
    }).
    ToArray();
//You can use Intersect after having defined your EqualityComparer, 
//avoid anonymous types in your final code
foreach (var item in items.Where(i => compareTo.Any(i2 => i.Code == i2.Code)))
{
    //Operate, be aware that compareTo is dissociated from your original file
    //So you'll have to adapt the above approach for your needs.
}
于 2013-01-02T02:37:05.403 回答
1

由于我不知道您的 C# 技能如何,所以我只会给您一个路线图。

这两个文件乍一看似乎非常不同,但如果你仔细观察,你会发现它们在结构上非常相似:两个文件都是“逗号分隔”的。唯一的区别是分隔符(|反对,)和列的数量,即在第二个文件中你有你不需要的列。

所以一个可能的算法可能是:

  1. 将第一个文件读入内存并用于string.Split()获取每行的名称/值对。

  2. 将第二个文件也读入内存(我希望文件不会太大)并用于string.Split()获取所有列值,包括那些您实际上不需要的值。您需要它们来编写 (6) 中的整个文件。

  3. 关闭两个文件的文件句柄!这对于在 (6) 中覆盖它很重要。

  4. 遍历第二个文件的行,对于每一行,在第一个文件的行中搜索等效条目。

  5. 现在您可以比较这些值并执行您想要的操作(更改第二个文件的值、删除整行等)。比较/更改时请注意文件 2 中的引号!

  6. 打开文件 2 的写句柄并覆盖文件,将文件 2 的(已更改!)行列表以正确的格式打印到新文件中。要生成类似 CSV 的格式,您可以使用string.Join().

于 2013-01-02T03:21:29.117 回答
0

假设您的 Txt 文件最后包含产品代码和库存计数,这应该可以解决问题。

如果您的文本文件很大,这可能会执行得很慢,但是您可以根据需要进行重构,但这应该是一个很好的起点。

List<string[]> stock = new List<string[]>(File.ReadAllLines("G:\\Stock.txt").Select(line => line.Split('|')));
List<string[]> products = new List<string[]>(File.ReadAllLines("G:\\Products.txt").Select(line => line.Split(',')));

products.ForEach(p =>
{
    // since not all arrays in this case are the same lenght, we will go backwards from the end
    int productStockIndex = Array.IndexOf(p, p.Last());

    // product name is before the stock count
    int productNameIndex = productStockIndex - 1;

    // get product name to find in Stock.txt and remove extra quotes from product name
    string productName = p[productNameIndex].Replace("\"", "");

    // check if Stock.txt contains the product
    if (stock.Any(s => s[0] == productName))
    {
        // Update the stock count
        p[productStockIndex] = stock.First(stk => stk[0] == productName)[1];
    }       
});

保存存档....

于 2013-01-02T02:53:06.563 回答