Проверка и печать файлов - PullRequest
       2

Проверка и печать файлов

2 голосов
/ 16 сентября 2011

Я пишу программу, которая открывает по одному файлу за раз, анализирует его и выводит проанализированные данные в новый документ .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.И если он совпадает, укажите имя файла в текущей строке.Если он не совпадает, создайте новую строку и добавьте номер детали и имя файла, а затем отсортируйте файл численно по номеру детали.

Может кто-нибудь помочь мне разобраться?

Ответы [ 3 ]

2 голосов
/ 16 сентября 2011

Надеюсь, ты не сдался. Вот пример класса. Я закончил это из моего последнего поста. Сохраните данные базы данных выше в 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();
        }
    }
}
1 голос
/ 16 сентября 2011

Не разбирайте CSV самостоятельно. Для этого используйте FileHelpers Библиотека. Может быть много исключений, и FileHelpers справляется с ними очень хорошо.

Во-вторых, вы выполняете достаточно операций с данными, в которых может помочь простая база данных. Может быть, SQL Express или отдельная файловая встроенная база данных (SQL Server Compact, SQLite).

Наконец, чтобы сделать это вручную, вам просто нужно создать таблицы в памяти. То, что у вас есть, - это отношение «многие ко многим» между номерами деталей и файлами. Таким образом, у вас есть две таблицы и промежуточная таблица соединений.

Теперь, так как «filename» имеет только один атрибут ( filename ) в вашем примере, его можно добавить в таблицу соединений в качестве дополнительного столбца. Итак, у вас есть 2 таблицы. Второй выглядит как

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

Первый стол, который у вас уже есть.

Так что, если вы реплицируете эти две таблицы в памяти, используя List<List<string>>, вы сможете закончить это с LINQ без каких-либо проблем. Хотя лично я буду создавать новые классы или, по крайней мере, структуры для представления двух кортежей таблиц.

Надеюсь, это поможет.

0 голосов
/ 16 сентября 2011

Вот краткий обзор ... он может определенно использовать улучшения, но это начало :)

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();
            }
        }

    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...