C#如何根据字符串内容在具有自定义名称的文件上书写?

我正在尝试在这里学习一些C#。我的目标是在多个自定义文件上创建和写入,这些文件的名称根据要写入的字符串的一部分而有所不同。下面是一些示例:

比方说,要写入的字符串基本上是csv文件的行:

2019-10-28 16:14:14;;15.5;0;;3;false;false;0;111;123;;;10;false;1;2.5;;;;0;
2019-10-28 16:13:11;;18;0;;1;false;false;222;333;123;;;10;false;1;1;;;;0;G
2019-10-29 16:13:11;;18;0;;3;false;false;true;

您可能会注意到,每个字符串的第一个字段是一个日期,这就是选择要写入的文件名的关键字段。

前两个字段具有相同的日期,因此两个字符串都将打印在一个文件中,第三个字段将打印在另一个文件中,因为它具有不同的日期。

预期结果:

第一个文件:

2019-10-28 16:14:14;;15.5;0;;3;false;false;0;111;123;;;10;false;1;2.5;;;;0;
2019-10-28 16:13:11;;18;0;;1;false;false;222;333;123;;;10;false;1;1;;;;0;

第二个文件:

2019-10-29 16:13:11;;18;0;;3;false;false;true;

现在我有多个类似的行,我想根据它们的第一个值将它们打印在不同的文件上。

我设法创建了一个class,它可以代表每一行:

class Value {
    public DateTime date = DateTime.Now;
    public decimal cod = 0;
    public decimal quantity = 0;
    public decimal price = 0;
    //Other irrelevant fields
}

我还尝试开发一个method以便在给定文件上写入单个值:

private static void WriteValue(Value content,string folder,string fileName) {
    using(StreamWriter writer = new StreamWriter(Path.Combine(folder,fileName),true,Encoding.ASCII)) {
        writer.Write(content.dataora.ToString("yyyyMMdd"));
        writer.Write("0000");
        writer.Write("I");
        writer.Write("C");
        writer.Write(content.codpro.ToString().PadLeft(14,'0'));
        writer.Write(Convert.ToInt64(content.qta * 100).ToString().PadLeft(8,'0'));
        writer.WriteLine();
    }
}

以及将Values写入文件的方法

static void WriteValues(List<Value> fileContent) {
        //Once I got all Values of File in a List of Values,I try to write them in files
    }
    if(fileContent.Count > 0) {
        foreach(Value riga in fileContent) {
            //Temp Dates,used to compare previous Date in order to know if I have to write Value in new File or it can be written on same File

            string dataTemp = riga.dataora.ToString("yyyy-MM-dd");
            string lastData = string.Empty;
            string FileName = "ordinivoa_999999." + DateTime.Now.ToString("yyMMddHHmmssfff");
            //If lastData is Empty we are writing first value
            if (string.IsnullOrEmpty(lastData)) {
                WriteValue(riga,toLinfaFolder,FileName);
                lastData = dataTemp;
            }
            //Else if lastData is equal as last managed date we write on same file
            else if (lastData == dataTemp) {
                WriteValue(riga,FileName);
            }
            else {
               //Else current date of Value is new,so we write it in another file
                string newFileName = "ordinivoa_999999." + DateTime.Now.AddMilliseconds(1).ToString("yyMMddHHmmssfff");
                WriteValue(riga,newFileName);
                lastData = dataTemp;
            }

        }
    }
}

我的问题是上述方法的行为异常,可以在一个文件中写入第一个相等的日期,这很好,但是即使我们有不同的日期,也可以在一个文件中写入所有其他值。

仅当日期值相同时,如何确保每个值都打印在单个文件中?

raytacer 回答:C#如何根据字符串内容在具有自定义名称的文件上书写?

您可以使用LINQ查询轻松地将相等的日期分组

private static void WriteValues(List<Value> fileContent)
{
    var dateGroups = fileContent
        .GroupBy(v => $"ordinivoa_999999.{v.date:yyMMddHHmmssfff}");
    foreach (var group in dateGroups) {
        string path = Path.Combine(toLinfaFolder,group.Key);
        using (var writer = new StreamWriter(path,true,Encoding.ASCII)) {
            foreach (Value item in group) {
                //TODO: write item to file
                writer.WriteLine(...
            }
        }
    }
}

由于DateTime以千分之一秒为单位存储值,因此一旦格式化,两个日期看起来就相等,可能仍然不同。因此,我建议对文件名进行分组以避免这种影响。我使用string interpolation来创建和格式化文件名。

不要打开和关闭每个文本行的文件。

您需要在代码文件的顶部

using System.Linq;
,

您在正确的位置上声明了一个类,但您同时也在做很多不必要的事情。使用#include <Preferences.h> Preferences eeprom; typedef struct { long var1 = -1; long var2 = -1; long var3 = 0; byte var4 = 0; } someObject; someObject object_[4][24]; someObject object_1_[4][24]; void setup() { Serial.begin(115200); eeprom.begin("Settings",false); object_[0][0].var1 = 25889; object_[0][0].var2 = 25890; object_[0][0].var3 = 25891; object_[1][2].var1 = 25892; object_[1][2].var2 = 25893; object_[1][2].var3 = 25894; eeprom.putBytes("someObject",&object_[4][24],sizeof(object_[4][24])); Serial.print("sizeof(object_[4][24]) = "); Serial.println(String(sizeof(object_[4][24]))); size_t schLen = eeprom.getBytes("someObject",NULL,NULL); Serial.print("sizeof(someObject) = "); Serial.println(String(schLen)); char buffer[schLen]; eeprom.getBytes("someObject",&object_1_[4][24],schLen); // I know use of "&" is wrong,but havn't idea to fix it Serial.println("--------**********************************"); Serial.println(String(object_[0][0].var1)); Serial.println(String(object_[0][0].var2)); Serial.println(String(object_[0][0].var3)); Serial.println("--------"); Serial.println(String(object_1_[1][2].var1)); Serial.println(String(object_1_[1][2].var2)); Serial.println(String(object_1_[1][2].var3)); Serial.println("==========================================="); Serial.println(buffer); } void loop() {} 可以大大简化这一过程。

首先,我定义一个类,由于您要做的就是编写每条记录,因此我将使用LINQ字段和整个原始记录的DateTime字段。

string

class MyRecordOfSomeType { public DateTime Date { get; set; } public string RawData { get; set; } } 的提交是为了便于您在进行DateTime时使用。

现在,我们遍历您的数据,使用LINQ进行拆分,然后创建您的类实例列表。

;

然后我们按日期分组。请注意,对var data = new List<string>() { "2019-10-28 16:14:14;;15.5;0;;3;false;false;0;111;123;;;10;false;1;2.5;;;;0;","2019-10-28 16:13:11;;18;0;;1;false;false;222;333;123;;;10;false;1;1;;;;0;G","2019-10-29 16:13:11;;18;0;;3;false;false;true;" }; var records = new List<MyRecordOfSomeType>(); foreach (var item in data) { var parts = item.Split(';'); DateTime.TryParse(parts[0],out DateTime result); var rec = new MyRecordOfSomeType() { Date = result,RawData = item }; records.Add(rec); } 结构的Date组件进行分组很重要,否则它将考虑DateTime组件,并且您将拥有更多的文件。

Time

最后,迭代您的组,并将每个组的内容写入新文件。

var groups = records.GroupBy(x => x.Date.Date);
本文链接:https://www.f2er.com/3156539.html

大家都在问