Sigmond Gatt Ответов: 2

Копирование нескольких файлов в один файл на языке Си#


Привет разработчикам,

Это мой код для копирования нескольких файлов данных в один:

public void generateMonthReport()
       {
           string[] inputFilePaths = Directory.GetFiles("//Path to directory for multiple files","*.txt.2018-"+DateTime.Now.ToString("MM")+"-*");

           using (var outputStream = File.Create("//Path to save the new file" + DateTime.Now.ToString("MM-yyyy") + "-Statistics.txt"))
           {
               foreach (var inputFilePath in inputFilePaths)
               {
                   using (var inputStream = File.OpenRead(inputFilePath))
                   {
                       inputStream.CopyTo(outputStream);
                   }

               }
           }
       }



Фото выхода (см.)
https://image.ibb.co/etL5T9/Capture.jpg

на этой фотографии выделена дата. В этой строке записывается новый файл.

Проблема в том, что эта выделенная дата написана иначе, чем другая, и когда я прихожу, чтобы прочитать ее с регулярным выражением, выводится ошибка.

Я попытался поместить эту выделенную строку в текстовую строку regex101, и она была прочитана как пуля
Изображение : https://image.ibb.co/hF7YgU/Capture1.jpg


ОБНОВЛЕНИЕ ПО ЗАПРОСУ :
Это мое регулярное выражение (многострочное) :
^(?<date>[^ ]+) (?<time>[^A-Z]+) (?<errorMessage>[^[]+) \[1\] (?<programName>[^.]+)[.](?<formName>[^.]+)[.](?<event>[^ ]+)[^a-z]+(?<username>[^:]+):(?<message>[^.]+).+$"


В hexEditor я обнаружил, что строка начинается с (возможно, это может помочь):
* » ¿ - > EF BB BF

Это код для чтения данных из файла :
var MyTextFileDataSet = new TextFileDataSet.TextFileDataSet();
          using (var filestream = new FileStream("//path of file to read.", FileMode.Open, FileAccess.Read,FileShare.ReadWrite))
          {
              MyTextFileDataSet.ContentExpression = new Regex(@"^(?<date>[^ ]+) (?<time>[^A-Z]+) (?<errorMessage>[^[]+) \[1\] (?<programName>[^.]+)[.](?<formName>[^.]+)[.](?<event>[^ ]+)[^a-z]+(?<username>[^:]+):(?<message>[^.]+).+$", RegexOptions.Multiline);

              MyTextFileDataSet.Fill(filestream);

          }


          int counterError = 0, counterFatal = 0, counterWarning = 0;



          var rows = MyTextFileDataSet.Tables[0].AsEnumerable();
          string errorMessage = "";
          string transactionsMessage = "";
          int counter = 0;
          foreach (var row in rows)
          {
              errorMessage = row.Field<string>("errorMessage");
              var date = DateTime.Parse(row.Field<string>("date"));
              var name = row.Field<string>("username").Trim();
              transactionsMessage = row.Field<string>("message");
              string transactionsString = "";
              if (transactionsMessage.Contains("generated"))
              {
                  transactionsString = getBetween(transactionsMessage, "generated", "transactions");
              }
              if (transactionsString != "")
              {
                  var transactions = Convert.ToInt32(transactionsString);
                  var logItem = logItems
                                            //.Where(n => n.Date == date)
                                            .Where(n => n.Name == name)
                                            .FirstOrDefault();
                  if (logItem == null)
                  {
                      logItems.Add(new LogItemGeneration
                      {
                          Date = date,
                          Name = name,
                          Transactions = transactions
                      });
                  }
                  else
                  {
                      logItem.Transactions += transactions;
                  }
              }


              switch (errorMessage)
              {
                  case "ERROR":
                      counterError++;
                      break;
                  case "FATAL":
                      counterFatal++;
                      break;
                  case "WARN":
                      counterWarning++;
                      break;

                  default:
                      break;
              }
              //GENERATING CHART

              counter++;

эта линия :
var date = DateTime.Parse(row.Field<string>("date"));
это дает исключение формата, когда речь заходит о той строке, где данные записываются по-разному



Если вы чего то не поняли или хотите что то уточнить не стесняйтесь комментировать и я отвечу :)

Что я уже пробовал:

Когда я изменил эту линию, как и другие (ручные), все работало нормально.

Я попытался найти другие методы в интернете, но не смог этого сделать.

Richard MacCutchan

Разница, которую вы видите, присутствует только в приложении, которое отображает данные. Фактическое содержимое файла одинаково для всего текста. Возможно, если вы отредактируете свой вопрос, покажете фактическое содержание и объясните, какое регулярное выражение вы используете и какую ошибку получаете, люди смогут помочь.

Sigmond Gatt

Вопрос обновлен , может быть, это может помочь вам больше я действительно сожалею, но английский не мой первый язык

Richard MacCutchan

Не нужно извиняться за ваш английский, мой Мальтийский ужасен.

<quote>В hexEditor я обнаружил, что строка начинается с (может быть, это может помочь):
* » ¿ - > EF BB BF
Эти байты просто идентифицируют содержимое как закодированное в UTF-8, но это не влияет на формат. Любой редактор или программа обработки текста будут пропускать эти байты. Однако если они находятся в середине файла, они не будут интерпретированы правильно. Вы также должны проверить файл, содержащий источник этого текста, чтобы увидеть, не происходит ли дополнительный символ(ы) из исходного файла.

Sigmond Gatt

Прежде всего спасибо за понимание меня , я думаю, что это происходит в середине моего файла, потому что я вводю несколько файлов в 1, и я читаю целые файлы, включая эти символы, а также я попытаюсь проверить streamreaders и streamwriters, может быть, я смогу работать с ними

Richard MacCutchan

Смотрите мой последний комментарий выше.

Richard MacCutchan

Я подозреваю, что проблема возникает из-за того, что вы используете FileStream для чтения текстового файла. Но ... FileStream обрабатывает содержимое как двоичное, поэтому он будет копировать управляющие символы, а также обычные символы. Вы должны использовать a TextReader для чтения входных файлов и a TextWriter чтобы записать обновленный файл.

Sigmond Gatt

Сделайте это замечание в качестве решения.

Richard MacCutchan

Это нормально, Google все равно найдет его, для тех, кто заинтересован.

2 Ответов

Рейтинг:
2

Eric Lynch

Я думаю, что проблема в том, что вы пытаетесь слиться линии текстовых файлов, которые состоят из персонажи, не беспокоясь о том, что кодировка символов.

Шестнадцатеричный код, который вы упомянули, выглядит как метка порядка байтов (BOM) для UTF-8, см.:

Знак порядка байтов - Википедия[^]

Поскольку вы рассматриваете файлы как потоки байтов, вы дословно копируете метки порядка байтов. Это прекрасно работает для первой строки, так как нормально иметь спецификацию в начале файла, где она принадлежит.

Однако для второго и последующих файлов это не работает. Это происходит потому, что вы копируете спецификацию в середину файла, где ей не место.

Вы должны смотреть в использовании с потоками чтения / записи в поток, который сделает кодировки для вас. Видеть:

Как читать текст из файла | Microsoft Docs[^]
Как записать текст в файл | Microsoft Docs[^]

Кроме того, следующее может упростить чтение строк:

Метод File.ReadLines (System.IO) | Microsoft Docs[^]

Существует эквивалент для записи строк, но он не очень хорошо подходит для объединения нескольких файлов:

Файл.Метод WriteAllLines (System.IO) | Microsoft Docs[^]


Richard MacCutchan

Это определенно кажется проблемой. Смотрите мои комментарии и ответы ОП выше.

Рейтинг:
1

OriginalGriff

Начните с просмотра файлов, которые вы открываете: используйте шестнадцатеричный редактор, чтобы посмотреть на конец первого и начало следующего. Важно использовать шестнадцатеричный редактор, потому что текстовый редактор (например, блокнот) будет делать предположения о содержимом файла, которое "скроет" то, что вам нужно искать.
как будет выглядеть "объединенный файл"? Есть ли там что-нибудь, кроме прямых букв, цифр, знаков препинания и новой строки (либо 0x0D, 0x0A, \n, \r, либо комбинация)? Если да, то что?
Затем посмотрите на "комбинированный" файл с помощью того же шестнадцатеричного редактора - как выглядит "соединение"? Все ли в точности так, как вы ожидали бы от ваших наблюдений за входными данными?

Вам нужно собрать информацию о том, что именно происходит - и мы не можем сделать это за вас, у нас нет доступа к вашей файловой системе!