文件检查与打印

发布于 2024-12-04 17:17:31 字数 2580 浏览 1 评论 0 原文

我正在编写一个程序,一次打开一个文件,解析它,并将解析后的数据输出到一个新的 .txt 文档中,该文档根据传入的文件命名。将读取 50 多个文件并解析。

因此,如果打开文件的命名类似于:STACK-OVERFLOW-125663-D2.txt,则输出文件将类似于以下内容125663-D2.txt

每次读取文件时,都会解析其部件号。每个文件将包含类似于此的行(第 8 个分隔的逗号值(即 119082、119083、119040、119085、119084)是零件编号值。)

"00003",6,"D","C20",-70.10,42.06,90.00,"119082",0,1,2,0,0,"",0,"001"
"00004",6,"D","C21",-67.91,42.06,90.00,"119082",0,1,2,0,0,"",0,"001"
"00005",13,"D","C23",-66.91,59.07,180.00,"119083",0,1,2,0,0,"",0,"002"
"00006",13,"D","R10",-77.32,66.88,90.00,"119040",0,1,2,0,0,"",0,"003"
"00007",13,"D","L3",-77.64,77.48,90.00,"119085",0,1,2,0,0,"",0,"004"
"00008",20,"D","D1",-62.91,103.77,0.00,"119084",0,1,2,0,0,"",0,"005"
"00009",21,"D","D1",-25.83,103.77,0.00,"119084",0,1,2,0,0,"",0,"005"
"00010",14,"D","L3",-40.56,77.48,90.00,"119085",0,1,2,0,0,"",0,"004"
"00011",14,"D","R10",-40.24,66.88,90.00,"119040",0,1,2,0,0,"",0,"003"

现在我需要做的是检查另一个 .txt 文件.. 假设它被称为“DATABASE.txt”,以查看这些零件编号是否已存在。该数据库文件将如下所示:

119082:    125663-D2, 123456-A1,
119083:    125663-D2,
119085:    125663-D2, 123456-A1, 987654321-Z11234, 1111111-B50

因此,在 DATABASE.txt 文件和上面打开的文件中,我想检查打开的文件中的所有零件号,看看它们是否存在于数据库中。

  • 如果该部件确实存在,我想将文件名(输出文件)连接到找到该部件号的行的末尾。

  • 如果该部分不存在,我想将该部分添加到文件中并使用 list.Sort() 对文件进行排序。

我不确定如何做到这一点,有人可以帮忙吗?


这是到目前为止我的一些代码:

List<string> partNumberLines = new List<string>();
string file = openFile.FileName;
string splitFile = file.Split('\\');
string[] savedName = splitFile[splitFile.Length - 1].Split('.');
string[] lineNumber = savedNamed[2].Split('-');
string fileName = savedNamed[1] + "-" + lineNumber[0] + ".txt";

foreach (string line in fileList)
{
    string[] splitLine = line.Split('\n');
    for (int i = 0; i < splitLine.Length; i++)
    {
        string tempSplit = splitLine[i].Split(',');  // splits each line by commas
        if (tempSplit.Length.Equals(16))
        {
            tempSplit[7] = tempSplit[7].TrimStart('"');  //trims the quotes from the part numbers
            tempSplit[7] = tempSplit[7].TrimEnd('"');
        }
    }
}
partNumberLines = partNumberLines.Distinct().ToList();  //gets rid of duplicate partnumbers in one file.

所以我的代码正在获取所有零件号和文件名。我只是不知道如何打开现有文件(如果不存在,则创建它)并搜索该文件并在列表: partNumberLines 中查找匹配项。如果匹配,则将文件名连接到当前行。如果不匹配,请创建一个新行并添加部件号和文件名,然后按部件号对文件进行数字排序。

谁能帮我解决这个问题吗?

I am writing a program that opens up one file at a time, parses it, and outputs the parsed data into a new .txt document that is named based off of the file coming in. There are over 50 files that are going to be read and parsed.

So if the opened file was named something like this: STACK-OVERFLOW-125663-D2.txt, the output file would be something like this 125663-D2.txt.

Each time a file is read, it is parsed for their part numbers. Each file will contain lines similar to this (The 8th seperated comma values (ie, 119082, 119083, 119040, 119085, 119084) are the part number values.):

"00003",6,"D","C20",-70.10,42.06,90.00,"119082",0,1,2,0,0,"",0,"001"
"00004",6,"D","C21",-67.91,42.06,90.00,"119082",0,1,2,0,0,"",0,"001"
"00005",13,"D","C23",-66.91,59.07,180.00,"119083",0,1,2,0,0,"",0,"002"
"00006",13,"D","R10",-77.32,66.88,90.00,"119040",0,1,2,0,0,"",0,"003"
"00007",13,"D","L3",-77.64,77.48,90.00,"119085",0,1,2,0,0,"",0,"004"
"00008",20,"D","D1",-62.91,103.77,0.00,"119084",0,1,2,0,0,"",0,"005"
"00009",21,"D","D1",-25.83,103.77,0.00,"119084",0,1,2,0,0,"",0,"005"
"00010",14,"D","L3",-40.56,77.48,90.00,"119085",0,1,2,0,0,"",0,"004"
"00011",14,"D","R10",-40.24,66.88,90.00,"119040",0,1,2,0,0,"",0,"003"

Now what I need to do is check another .txt file.. let's say it is called "DATABASE.txt" to see if these part number exist in there already. This data base file will look something like this:

119082:    125663-D2, 123456-A1,
119083:    125663-D2,
119085:    125663-D2, 123456-A1, 987654321-Z11234, 1111111-B50

So, in the DATABASE.txt file and the file opened above, I want to check all of the part numbers from the opened file and see if they exist in the data base.

  • If the part does exist, I want to concat the filename (the output file) to the end of the line that the part number was found on.

  • If the part does not exist, I want to add the part to the file and sort the file using list.Sort().

I am unsure on how to do this, can anyone help?


Here is some of my code so far:

List<string> partNumberLines = new List<string>();
string file = openFile.FileName;
string splitFile = file.Split('\\');
string[] savedName = splitFile[splitFile.Length - 1].Split('.');
string[] lineNumber = savedNamed[2].Split('-');
string fileName = savedNamed[1] + "-" + lineNumber[0] + ".txt";

foreach (string line in fileList)
{
    string[] splitLine = line.Split('\n');
    for (int i = 0; i < splitLine.Length; i++)
    {
        string tempSplit = splitLine[i].Split(',');  // splits each line by commas
        if (tempSplit.Length.Equals(16))
        {
            tempSplit[7] = tempSplit[7].TrimStart('"');  //trims the quotes from the part numbers
            tempSplit[7] = tempSplit[7].TrimEnd('"');
        }
    }
}
partNumberLines = partNumberLines.Distinct().ToList();  //gets rid of duplicate partnumbers in one file.

So my code is getting all of the part numbers and the name of the file.. I just do not know how to open up an existing file (and if it does not exist, create it) and search through the file and look for matches in the List: partNumberLines. And if it matches, concat the file name to the current line. If it does not match, create a new line and add the part number and file name and then sort the file numerically by part number.

Can anyone help me figure this out?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

夜吻♂芭芘 2024-12-11 17:17:31

希望你还没有放弃。这是一个示例类。我已经从上一篇文章完成了它。将上面的数据库数据保存到 database.txt 并将零件数据保存到 parts.txt 并修改路径以查看其工作原理。希望对您有帮助。如果您还有其他疑问,请随时提问。

using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        private class DataBaseRecord
        {
            public string PartNumber { get; set; }
            public List<string> FileNames { get; set; }
            public DataBaseRecord(string _PartNumber, List<string> _FileNames)
            {
                PartNumber = _PartNumber;
                FileNames = _FileNames;
            }
        }

        private class DataBase
        {
            public string databaseFile { get; set; }
            List<DataBaseRecord> records;
            public DataBase(string _databaseFile)
            {
                databaseFile = _databaseFile;
                records = new List<DataBaseRecord>();
            }
            public void AddRecord(string partNumber, string fileName)
            {
                if (string.IsNullOrWhiteSpace(partNumber))
                    return;

                if (string.IsNullOrWhiteSpace(fileName))
                    return;

                bool exists = records.Count(x => x.PartNumber == partNumber) > 0;
                if (!exists)
                {
                    records.Add(new DataBaseRecord(partNumber, new List<string>() { fileName }));
                }
                else
                {
                    var record = from x in records where x.PartNumber == partNumber select x;
                    foreach (DataBaseRecord dbr in record)
                    {
                        exists = dbr.FileNames.Count(x => x == fileName) > 0;
                        if (!exists)
                            dbr.FileNames.Add(fileName);
                    }
                }
            }
            public void Read()
            {
                // read all database records into data structure
                using (StreamReader sr = new StreamReader(databaseFile))
                {
                    while (!sr.EndOfStream)
                    {
                        string line = sr.ReadLine();
                        string partNumber = line.Split(':')[0].Trim();
                        if (partNumber[0] == '\"')
                            partNumber = partNumber.Substring(1, partNumber.Length - 2);
                        string[] files = line.Split(new string[]{":"}, StringSplitOptions.None)[1].Split(new string[]{","}, StringSplitOptions.RemoveEmptyEntries);
                        List<string> fileNumbers = new List<string>();
                        foreach (String file in files)
                        {
                            if (!string.IsNullOrWhiteSpace(file))
                            {
                                fileNumbers.Add(file.Trim());
                            }
                        }
                        records.Add(new DataBaseRecord(partNumber, fileNumbers));
                    }
                }
            }
            public void Write()
            {
                // write out database using the records
                var sortedRecords = from x in records orderby x.PartNumber select x;
                using (StreamWriter sw = new StreamWriter(databaseFile))
                {
                    foreach (DataBaseRecord record in sortedRecords)
                    {
                        string line = record.PartNumber + ": ";
                        for (int index = 0; index < record.FileNames.Count; index++)
                        {
                            line += record.FileNames[index];
                            if (index < record.FileNames.Count - 1)
                                line += ", ";
                        }
                        sw.WriteLine(line);
                    }
                }
            }
        }

        static void Main(string[] args)
        {
            // replace with name of your database
            DataBase db = new DataBase(@"C:\Users\jondoe\Desktop\DataBase.txt");
            db.Read();

            // replace with list of your parts files
            string[] partsFiles = new string[] { @"C:\Users\jondoe\Desktop\parts.txt" };
            foreach (string partsFile in partsFiles)
            {
                using (StreamReader sr = new StreamReader(partsFile))
                {
                    while (!sr.EndOfStream)
                    {
                        string line = sr.ReadLine();
                        string partNumber = line.Split(new string[] { "," }, StringSplitOptions.None)[7];
                        if (partNumber[0] == '\"')
                            partNumber = partNumber.Substring(1, partNumber.Length - 2);
                        db.AddRecord(partNumber, Path.GetFileNameWithoutExtension(partsFile));
                    }
                }                
            }

            db.Write();
        }
    }
}

编辑

如果您想要一个静态数据库并且希望允许用户选择零件文件,那么您可以在按钮单击事件中执行此操作:

private void btnOpenFile_Click(object sender, EventArgs e)
{
    DataBase db = new DataBase(@"C:\Users\JonDoe\Desktop\DataBase.txt");
    db.Read();

    using (OpenFileDialog ofd = new OpenFileDialog())
    {
        if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
        {
            using (StreamReader sr = new StreamReader(ofd.FileName))
            {
                while (!sr.EndOfStream)
                {
                    string line = sr.ReadLine();
                    string partNumber = line.Split(new string[] { "," }, StringSplitOptions.None)[7];
                    if (partNumber[0] == '\"')
                        partNumber = partNumber.Substring(1, partNumber.Length - 2);
                    db.AddRecord(partNumber, Path.GetFileNameWithoutExtension(ofd.FileName));
                }
            }
            db.Write();
        }
    }
}

Hope you haven't given up. Here's a sample class. I've completed it from my last post. Save your database data above to database.txt and your parts data to parts.txt and modify the paths to see how it works. Hope it helps you. If you have any more questions, feel free to ask.

using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        private class DataBaseRecord
        {
            public string PartNumber { get; set; }
            public List<string> FileNames { get; set; }
            public DataBaseRecord(string _PartNumber, List<string> _FileNames)
            {
                PartNumber = _PartNumber;
                FileNames = _FileNames;
            }
        }

        private class DataBase
        {
            public string databaseFile { get; set; }
            List<DataBaseRecord> records;
            public DataBase(string _databaseFile)
            {
                databaseFile = _databaseFile;
                records = new List<DataBaseRecord>();
            }
            public void AddRecord(string partNumber, string fileName)
            {
                if (string.IsNullOrWhiteSpace(partNumber))
                    return;

                if (string.IsNullOrWhiteSpace(fileName))
                    return;

                bool exists = records.Count(x => x.PartNumber == partNumber) > 0;
                if (!exists)
                {
                    records.Add(new DataBaseRecord(partNumber, new List<string>() { fileName }));
                }
                else
                {
                    var record = from x in records where x.PartNumber == partNumber select x;
                    foreach (DataBaseRecord dbr in record)
                    {
                        exists = dbr.FileNames.Count(x => x == fileName) > 0;
                        if (!exists)
                            dbr.FileNames.Add(fileName);
                    }
                }
            }
            public void Read()
            {
                // read all database records into data structure
                using (StreamReader sr = new StreamReader(databaseFile))
                {
                    while (!sr.EndOfStream)
                    {
                        string line = sr.ReadLine();
                        string partNumber = line.Split(':')[0].Trim();
                        if (partNumber[0] == '\"')
                            partNumber = partNumber.Substring(1, partNumber.Length - 2);
                        string[] files = line.Split(new string[]{":"}, StringSplitOptions.None)[1].Split(new string[]{","}, StringSplitOptions.RemoveEmptyEntries);
                        List<string> fileNumbers = new List<string>();
                        foreach (String file in files)
                        {
                            if (!string.IsNullOrWhiteSpace(file))
                            {
                                fileNumbers.Add(file.Trim());
                            }
                        }
                        records.Add(new DataBaseRecord(partNumber, fileNumbers));
                    }
                }
            }
            public void Write()
            {
                // write out database using the records
                var sortedRecords = from x in records orderby x.PartNumber select x;
                using (StreamWriter sw = new StreamWriter(databaseFile))
                {
                    foreach (DataBaseRecord record in sortedRecords)
                    {
                        string line = record.PartNumber + ": ";
                        for (int index = 0; index < record.FileNames.Count; index++)
                        {
                            line += record.FileNames[index];
                            if (index < record.FileNames.Count - 1)
                                line += ", ";
                        }
                        sw.WriteLine(line);
                    }
                }
            }
        }

        static void Main(string[] args)
        {
            // replace with name of your database
            DataBase db = new DataBase(@"C:\Users\jondoe\Desktop\DataBase.txt");
            db.Read();

            // replace with list of your parts files
            string[] partsFiles = new string[] { @"C:\Users\jondoe\Desktop\parts.txt" };
            foreach (string partsFile in partsFiles)
            {
                using (StreamReader sr = new StreamReader(partsFile))
                {
                    while (!sr.EndOfStream)
                    {
                        string line = sr.ReadLine();
                        string partNumber = line.Split(new string[] { "," }, StringSplitOptions.None)[7];
                        if (partNumber[0] == '\"')
                            partNumber = partNumber.Substring(1, partNumber.Length - 2);
                        db.AddRecord(partNumber, Path.GetFileNameWithoutExtension(partsFile));
                    }
                }                
            }

            db.Write();
        }
    }
}

Edit

If you want a static database and you want to allow the user to choose a parts file, then you could do this in a button click event:

private void btnOpenFile_Click(object sender, EventArgs e)
{
    DataBase db = new DataBase(@"C:\Users\JonDoe\Desktop\DataBase.txt");
    db.Read();

    using (OpenFileDialog ofd = new OpenFileDialog())
    {
        if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
        {
            using (StreamReader sr = new StreamReader(ofd.FileName))
            {
                while (!sr.EndOfStream)
                {
                    string line = sr.ReadLine();
                    string partNumber = line.Split(new string[] { "," }, StringSplitOptions.None)[7];
                    if (partNumber[0] == '\"')
                        partNumber = partNumber.Substring(1, partNumber.Length - 2);
                    db.AddRecord(partNumber, Path.GetFileNameWithoutExtension(ofd.FileName));
                }
            }
            db.Write();
        }
    }
}
我要还你自由 2024-12-11 17:17:31

不要自己解析 CSV。为此,请使用 FileHelpers 库。可能会有很多异常,FileHelpers 可以很好地处理这些异常。

其次,您正在执行足够的数据操作,简单的数据库可能会有所帮助。也许是 SQL Express,或者单个文件嵌入式数据库(SQL Server Compact、SQLite)。

最后,要手动执行此操作,您只需在内存中构建表即可。您真正拥有的是零件编号和文件之间的多对多关系。所以你有两个表和一个连接表。

现在,由于“filename”在您的示例中只有一个属性 ( filename ),因此可以将其作为附加列附加到连接表中。所以你有 2 张桌子。第二个看起来像

JoinTable
-------------------
PartNum | Varchar
Filename| Varchar

您已有的第一个表。

因此,如果您使用 List> 在内存中复制这两个表,您应该能够使用 LINQ 轻松完成此操作。尽管我个人会构建新的类或至少结构来表示两个表元组。

希望这有帮助。

Do not parse CSV yourself. Use FileHelpers Library for that. There can be a lot of exceptions, and FileHelpers handles those really well.

Secondly, you're doing enough data operations were a simple database might help. Maybe SQL Express, or a single file embedded database ( SQL Server Compact, SQLite ).

Finally to do this manually, you simply have to build out your tables in memory. What you really have is a Many-to-Many relationship between part numbers and files. So you have two tables and a join table inbetween.

Now since "filename" has only a single attribute ( filename ) in your example, it can be appended in the join table as an additional column. So you have 2 tables. The second looks like

JoinTable
-------------------
PartNum | Varchar
Filename| Varchar

The first table you already have.

So if you replicate these two tables in memory using List<List<string>> you should be able to finish this with LINQ with no trouble at all. Though personally I would build out new classes or at least structs to represent the two table tuples.

Hope this helps.

反目相谮 2024-12-11 17:17:31

这是一个快速运行..它肯定需要改进,但它是一个开始:)

using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Text;

namespace ConsoleApplication2
{
    public class FileIo
    {
        private Dictionary<int, CommaDelimitedStringCollection> dataBase;
        private const string DATABASE_PATH = @"D:\Temp\Test\DATABASE.txt";

        public void Run()
        {
            var files = new List<string> { @"D:\Temp\Test\Test1.txt", @"D:\Temp\Test\Test2.txt", @"D:\Temp\Test\Test3.txt" };

            dataBase = GetDatabase();

            foreach (var file in files)
            {
                Search(file, GetPartNumbers(file));  
            }

            WriteFileContents(DATABASE_PATH, BuildPartsDbStr());
        }

        private void Search(string fileName, List<int> partNums)
        {
            foreach (var partNum in partNums)
            {
                var path = Path.GetFileNameWithoutExtension(fileName);
                if (dataBase.Keys.Contains(partNum))
                {
                    dataBase[partNum].Add(path);
                }
                else
                {
                    dataBase.Add(partNum, new CommaDelimitedStringCollection { path });
                }
            }
        }

        private string BuildPartsDbStr()
        {
            var sb = new StringBuilder();
            var db  = from x in dataBase orderby x.Key select x;

            foreach (var record in db)
            {
                sb.AppendLine(string.Format("{0}: {1}", record.Key, record.Value));
            }

            return sb.ToString();
        }

        private Dictionary<int, CommaDelimitedStringCollection> GetDatabase()
        {
            var contents = GetFileContents(DATABASE_PATH);
            var commaStr = new CommaDelimitedStringCollection();
            var db = new Dictionary<int, CommaDelimitedStringCollection>();
            var id = 0;
            var collection = new CommaDelimitedStringCollection();

            for (var i = 0; i < commaStr.Count; i++ )
            {
                var str = commaStr[i];
                if (str.Contains(":"))
                {
                    collection.Add(str.Split(':')[1]);
                    if (i > 0) db.Add(id, collection);
                    collection = new CommaDelimitedStringCollection();
                    id = int.Parse(str.Split(':')[0]);
                }
                else
                {
                    collection.Add(str);
                }
            }

            return db;
        }

        private List<int> GetPartNumbers(string filePath)
        {
            var contents = GetFileContents(filePath);
            var commaStr = new CommaDelimitedStringCollection();
            var result = new List<int>();                

            commaStr.AddRange(contents.Split(','));

            for(var i = 7; i < commaStr.Count; i += 15)
            {
                result.Add(int.Parse(commaStr[i].Replace("\"", string.Empty)));
            }

            return result;
        } 


        private string GetFileContents(string path)
        {
            using (var stream = new StreamReader(path))
            {
                //yes I know this is evil - I don't have all night :P
                return stream.ReadToEnd();
            }
        }

        private void WriteFileContents(string path, string contents)
        {
            using (var stream = new StreamWriter(path, false))
            {
                stream.Write(contents);
                stream.Flush();
            }
        }

    }
}

Here's a quick run at it .. it could definitely use improvement but its a start :)

using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Text;

namespace ConsoleApplication2
{
    public class FileIo
    {
        private Dictionary<int, CommaDelimitedStringCollection> dataBase;
        private const string DATABASE_PATH = @"D:\Temp\Test\DATABASE.txt";

        public void Run()
        {
            var files = new List<string> { @"D:\Temp\Test\Test1.txt", @"D:\Temp\Test\Test2.txt", @"D:\Temp\Test\Test3.txt" };

            dataBase = GetDatabase();

            foreach (var file in files)
            {
                Search(file, GetPartNumbers(file));  
            }

            WriteFileContents(DATABASE_PATH, BuildPartsDbStr());
        }

        private void Search(string fileName, List<int> partNums)
        {
            foreach (var partNum in partNums)
            {
                var path = Path.GetFileNameWithoutExtension(fileName);
                if (dataBase.Keys.Contains(partNum))
                {
                    dataBase[partNum].Add(path);
                }
                else
                {
                    dataBase.Add(partNum, new CommaDelimitedStringCollection { path });
                }
            }
        }

        private string BuildPartsDbStr()
        {
            var sb = new StringBuilder();
            var db  = from x in dataBase orderby x.Key select x;

            foreach (var record in db)
            {
                sb.AppendLine(string.Format("{0}: {1}", record.Key, record.Value));
            }

            return sb.ToString();
        }

        private Dictionary<int, CommaDelimitedStringCollection> GetDatabase()
        {
            var contents = GetFileContents(DATABASE_PATH);
            var commaStr = new CommaDelimitedStringCollection();
            var db = new Dictionary<int, CommaDelimitedStringCollection>();
            var id = 0;
            var collection = new CommaDelimitedStringCollection();

            for (var i = 0; i < commaStr.Count; i++ )
            {
                var str = commaStr[i];
                if (str.Contains(":"))
                {
                    collection.Add(str.Split(':')[1]);
                    if (i > 0) db.Add(id, collection);
                    collection = new CommaDelimitedStringCollection();
                    id = int.Parse(str.Split(':')[0]);
                }
                else
                {
                    collection.Add(str);
                }
            }

            return db;
        }

        private List<int> GetPartNumbers(string filePath)
        {
            var contents = GetFileContents(filePath);
            var commaStr = new CommaDelimitedStringCollection();
            var result = new List<int>();                

            commaStr.AddRange(contents.Split(','));

            for(var i = 7; i < commaStr.Count; i += 15)
            {
                result.Add(int.Parse(commaStr[i].Replace("\"", string.Empty)));
            }

            return result;
        } 


        private string GetFileContents(string path)
        {
            using (var stream = new StreamReader(path))
            {
                //yes I know this is evil - I don't have all night :P
                return stream.ReadToEnd();
            }
        }

        private void WriteFileContents(string path, string contents)
        {
            using (var stream = new StreamWriter(path, false))
            {
                stream.Write(contents);
                stream.Flush();
            }
        }

    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文