I just can’t do and understand my assignment, so I decided to pour it in parts here. Since you need to do but need tips and instructions from professionals.

There is a certain class countFiles and in it there are fields user, address, date, traffic.
There is a constructor that initializes everything.
There is a parsingfiles method that parses the files.

Question: In what place did I make a mistake, file proparsil, saved the result in a variable list?

I create a new instance of the countFiles class to process the next file, and it was here that errors fell down.

 class countFiles { public string user { get; set; } public string adres { get; set; } public int trafik { get; set; } public DateTime data { get; set; } public countFiles(string userr = "", string adress = "", int traffic = 0,DateTime datta=new DateTime()) { user = userr; adres = adress; trafik = traffic; data = datta; } public static countFiles parsingfiles(string lline) { string[] filelist = Directory.GetFiles(@"D:\logfiles", "*.txt"); List<countFiles> list = new List<countFiles>(); //здесь будет результат DateTime datat; int trafic; for (int i = 1; i < filelist.Length; i++) { if (filelist[i] == "") continue; string[] lineParts = filelist[i].Split(' '); list.Add(new countFiles(lineParts[0], lineParts[1], int.Parse(lineParts[2]),DateTime.Parse(lineParts[3]))); countFiles ekz = new countFiles(list[user],list[adres],trafic,datat);---Ошибки здесь return ekz; } } } 

Errors:

  1. The most appropriate overloaded method for "Lab_2.2.CountFiles.countFiles (string, string, int, System.DateTime)" has several invalid arguments

4 fields, all initialized but he swears that unacceptable. Why?

  1. Error 1 For a non-static field, method, or property "Lab_2.countFiles.user.get", an object reference is required.

That is, I need to do both class and constructor static? And if you do not want?

  1. Error 4 Argument "1": type conversion from "Lab_2.2.countFiles" to "string" is not possible.

This is a dead end, since the question is also interesting lines and sheet. Identical. Propalsil and brought, proparsil and brought that he does not like.

Problem number two.

 static Statistics processFile(String file) { //если нет файла - то нет и статистики по нему if (!File.Exists(file)) { return new Statistics(); } StreamReader sr = System.IO.File.OpenText(file); String line; Statistics sc = new Statistics(); //читаем строки while ((line = sr.ReadLine()) != null) { //парсим var ekz = countFiles.parsingfiles(line); //обновляем статистику по критериям UInt64 bytes = 0; sc.userstat[ekz.user] = (sc.userstat.TryGetValue(ekz.user, out bytes) ? bytes : 0) + ekz.trafik; sc.adrestat[ekz.adres] = (sc.adrestat.TryGetValue(ekz.adres, out bytes) ? bytes : 0) + ekz.trafik; sc.trafikstat[ekz.data] = (sc.trafikstat.TryGetValue(ekz.data, out bytes) ? bytes : 0) + ekz.trafik; } return sc; } 

Error - The operator "+" cannot be applied to operands of the type "ulong" and "int".

I need to take statistics, and I have traffic there in general, and here is it? It turns out you need to change to another type or something?


Thanks for the tips to the classes.

Changed a little under the task, and added flows.

 using System; using System.Collections.Generic; using System.Linq; using System.IO; using System.Data; using System.Collections; using System.Text.RegularExpressions; using System.Threading; using System.Text; using System.Threading.Tasks; namespace LabWork2 { public class Line { public string User; public string Address; public int Traffic; public DateTime Date; public string ToCsv(bool header = false) { var s = ", "; return header ? String.Concat("User", s, "Address", s, "Traffic", s, "Date") : String.Concat( this.User, s, this.Address, s, this.Traffic, s, this.Date.ToString("d.MM")); } public static IEnumerable<Line> Parse(string logDir, string pattern, int skip = 0) { foreach (var file in Directory.EnumerateFiles(logDir, pattern)) foreach (var line in ParseFile(file, 1)) yield return line; } public static IEnumerable<Line> ParseFile(string path, int skip = 0) { return Parse(File.ReadLines(path).Skip(skip)); } } class Stat { public class Item { public string Key; public string Address; public int Traffic; public DateTime From; public DateTime To; public string ToCsv(bool header=false) { var s = ", "; return header ? String.Concat("Key", s, "Traffic", s, "From", s, "To") : String.Concat( this.Key, s, this.Traffic, s, this.From.ToString("d.MM"), s, this.To.ToString("d.MM")); } public string ToCsv1(bool header = false) { var s = ", "; return header ? String.Concat("Adress", s, "Traffic", s) : String.Concat( this.Address, s, this.Traffic, s); } public string ToCsv2(bool header = false) { var s = ", "; return header ? String.Concat( "Traffic", s, "From", s, "To") : String.Concat( this.Traffic, s, this.From.ToString("d.MM"), s, this.To.ToString("d.MM")); } } Dictionary<string, Item> tbl = new Dictionary<string, Item>(); public void Add(string key, Line line) { Item itm; if (tbl.TryGetValue(key, out itm) == false) { itm = new Item { Key = key, From = line.Date, To = line.Date }; tbl.Add(key, itm); } itm.From = new DateTime(Math.Min(itm.From.Ticks, line.Date.Ticks)); itm.To = new DateTime(Math.Max(itm.To.Ticks, line.Date.Ticks)); itm.Traffic += line.Traffic; } public IEnumerable<Item> Items { get { return tbl.Values; } } } class Program { static Queue<String> m_workFiles = new Queue<String>();//файлы на обработку static System.Collections.Generic.List<Stat> m_threadResult; //результат выполнения потока static bool m_iscomplete = false;//флаг завершения ввода static readonly object m_locker = new object();//мьютекс для регулирования доступа к очереди файлов на обработку public void processDirectory(String logDir)//извлечь все файлы очередь для обработки { if (!Directory.Exists(logDir)) { return; } lock (m_locker)//захватить мьютекс { foreach (var x in Directory.EnumerateFiles(logDir)) { m_workFiles.Enqueue(x); } } m_iscomplete = true;//установить флаг завершения } static void Main(string[] args) { Console.WriteLine("Ввод каталога:"); String logDir = Console.ReadLine(); Program pr = new Program(); pr.processDirectory(logDir); Line ln = new Line(); Stat st = new Stat(); string file; var userstat = new Stat(); Thread[] threads = new Thread[7]; for (int i = 0; i < 7; i++) { threads[i] = new Thread(new ThreadStart(Line.ParseFile(file,1))); threads[i].Name = String.Format("Работает поток {0}",i); } for (int i = 0; i < 7; i++) { threads[i] = new Thread(new ThreadStart(Stat.Add(1,line))); threads[i].Name = String.Format("Работает поток {0}", i); } foreach (var line in ln.ParseFile(logDir, "log*.txt", 1)) userstat.Add(line.User, line); Console.WriteLine(ln.ToCsv(true)); foreach (var si in userstat.Items) Console.WriteLine(si.ToCsv()); Console.WriteLine("Запись файлов-отчётов"); File.WriteAllLines(logDir + "userstat.txt",userstat.Items.Select(si => si.ToCsv())); File.WriteAllLines(logDir + "adrestat.txt",userstat.Items.Select(si => si.ToCsv1())); File.WriteAllLines(logDir + "datastat.txt",userstat.Items.Select(si => si.ToCsv2())); Console.WriteLine("Файлы записаны"); } } } 

Errors

 threads[i] = new Thread(new ThreadStart(Line.ParseFile(file,1))); 

Error 2 Expected method name.

Before that, the compiler cursed that it was not necessary to create an instance, I directly addressed the class, and wrote that the name of the method was expected.

Or do you need to create a delegate?

 threads[i] = new Thread(new ThreadStart(Stat.Add(1,line)));- Имя "line" отсутствует в текущем контексте 

Right here I honestly forgot, how do I call the method in the stream with the parameters that in the class they need to be declared in Maine or do the link?

 public static IEnumerable<Line> ParseFile(string path, int skip = 0) { return Parse(File.ReadLines(path).Skip(skip));----- Ни одна из перегрузок метода "Parse" не принимает "1" аргументов,если напишу отдельно каждый всё равно компилятор светит ошибку. } 

What I represent under these variables and what I understood from the code corrected: logDir(root) is the name of the directory where I have files;
pattern - file template (its contents);
skip - the number of elements in which the Skip method of the same name will be traversed.

 public static IEnumerable<Line> Parse(string logDir, string pattern, int skip = 0) { foreach (var file in Directory.EnumerateFiles(logDir, pattern)) foreach (var line in ParseFile(logDir,file, 1)) yield return line; } public static IEnumerable<Line> ParseFile(string path,string text, int skip = 0) { return Parse(File.ReadLines(path).Skip(skip),File.ReadAllText(text).Skip(skip),File.ReadAllText(text.ToString()).Skip(skip)); } 

In this line, return Parse(File.ReadLines(path).Skip(skip),File.ReadAllText(text).Skip(skip),File.ReadAllText(text.ToString()).Skip(skip));

A bunch of bugs:

  • Error 1 The most appropriate overloaded method for "System.IO.File.ReadAllText (string)" has several invalid arguments

  • Error 2 The most appropriate overloaded method for "LabWork2.Line.Parse (string, string, int)" has several invalid arguments

  • Error 3 Argument "1": type conversion from "System.Collections.Generic.IEnumerable" to "string" is impossible

  • Error 4 Argument "2": type conversion from "System.Collections.Generic.IEnumerable" to "string" is impossible

  • Error 5 Argument "3": type conversion from "System.Collections.Generic.IEnumerable" to "int" is not possible

The Parse() method is called with 3 arguments. That is, I read the path and template of the file and the number of elements.

If I understood the first, then with the second and third misunderstandings.

Using ReadAllText I already read the file name or its contents (2nd argument).

Concerning the 3rd time, the argument is an integer or ToString or ToInt?

Regarding the transformations, I think that after errors with arguments, errors can and will go away.

  • Describe the problem to be solved, then I can give an option how to fix it. So far, the implementation of the processFile method looks very strange and it’s not clear what result you expect from it - rdorn
  • Please make changes to the question, but do not list them as separate answers. - PashaPash

3 answers 3

If you need to parse the next text file

 user address traffic date User2 Yandex 600 23.07 User1 Yahoo 800 28.08 User2 Yandex 120 14.09 User3 Yahoo 100 23.10 User1 Yandex 160 17.11 User2 Google 700 25.11 

So we write

 using System.IO; using System.Text.RegularExpressions; public class Line { public string User; public string Address; public int Traffic; public DateTime Date; public string ToCsv(bool header = false) { var s = ", "; return header ? String.Concat("User", s, "Address", s, "Traffic", s, "Date") : String.Concat( this.User, s, this.Address, s, this.Traffic, s, this.Date.ToString("d.MM")); } } static IEnumerable<Line> Parse(IEnumerable<string> lines) { foreach (var line in lines) { var arr = Regex.Split(line.Trim(), @"\s+"); yield return new Line { User = arr[0], Address = arr[1], Traffic = int.Parse(arr[2]), Date = DateTime.ParseExact(arr[3], "d.MM", null) }; } } static IEnumerable<Line> ParseFile(string path, int skip=0) { return Parse(File.ReadLines(path).Skip(skip)); } 

 var root = @"C:\Temp\"; foreach (var line in ParseFile(root + "log1.txt", 1)) Console.WriteLine(line.ToCsv()); 

Result

 User2, Yandex, 600, 23.07 User1, Yahoo, 800, 28.08 User2, Yandex, 120, 14.09 User3, Yahoo, 100, 23.10 User1, Yandex, 160, 17.11 User2, Google, 700, 25.11 

If you need to parse several files, for example, log1.txt, log2.txt, etc., then we write

 static IEnumerable<Line> ParseFiles(string root, string pattern, int skip=0) { foreach (var file in Directory.EnumerateFiles(root, pattern)) foreach (var line in ParseFile(file, 1)) yield return line; } 

 var root = @"C:\Temp\logs\"; foreach (var line in ParseFiles(root, "log*.txt", 1)) Console.WriteLine(line.ToCsv()); 

UPDATE

To collect statistics, you can use the class TrafficStat .

    There are a lot of errors in your code, but we will try to make out the orders listed by you.

    OShibka- 1) The most appropriate overloaded method for "Lab_2.2.countFiles.countFiles (string, string, int, System.DateTime)" has several invalid arguments

    4 fields, all initialized but he swears that unacceptable. Why?

    This error occurs because you pass incorrect arguments to the constructor, look in more detail:

    countFiles ekz = new countFiles ( list [user] , list [adres] , trafic, datat);

    The selected arguments are not the strings that the constructor expects, but are elements of the list , which you define as List<countFiles> list , which means that the list consists of countFiles objects

    2) Error 1 For a non-static field, method or property "Laboratory_2.countFiles.user.get", a reference to the object is required. That is, I need to make both the class and the constructor static? And if I do not want.

    This error is caused by calling non-static class fields from a static method (see selection):

    countFiles ekz = new countFiles (list [ user ], list [ adres ], trafic, datat);

    In the code of a static method, you can access only static members of the class. Frankly speaking, I didn’t understand what result you expected to see at this place of your code, I think it’s worth adding a description of the problem to the question, then you will be able to suggest a correction option.

    3) Error 4 Argument "1": type conversion from "Lab_2.2.countFiles" to "string" is not possible here is a dead end, since the question is also interesting lines and the sheet is identical. Proparsil and brought, proparsil and brought that he does not like

    see the answer to the first error.

    Error - Operator "+" cannot be applied to operands of type "ulong" and "int"

    I need to take statistics, and I have traffic there in general, and here is it? It turns out you need to change to another type or something?

    It is not necessary to change the type of field in the class; it is enough to bring all the terms of the expression to ulong . However, if you keep only positive numbers in the class fields, it may make sense.

    Update Try to fix the line:

    countFiles ekz = new countFiles (list [user], list [adres], trafic, datat); --- Errors here

    in this way:

     countFiles ekz = new countFiles(list[i].user,list[i].adres,trafic,datat); 

    It will be compiled, but the architecture still has to work and work.

    Well, about the integers. .NET supports 2 variants of integers, signed and unsigned. Arithmetic operations between them without an explicit cast are prohibited, since There is no one-to-one mapping of unsigned integers to signed ones and vice versa.

      For parallel processing of elements of the collection, you can use the AsParallel method together with ForAll

       using System.Collections.Concurrent; using System.Linq; var cq = new ConcurrentQueue<TrafficStat>(); var root = @"C:\Temp\logs\"; // параллельно ... Directory.EnumerateFiles(root, "log*.txt").AsParallel().ForAll(file => { Console.WriteLine("@" + Environment.CurrentManagedThreadId + "\t" + file); var userstat = new TrafficStat(); // собрать статистику из файла foreach (var line in ParseFile(file, 1)) userstat.Add(line.User, line); // сохранить статистику для дальнейшего агрегирования cq.Enqueue(userstat); }); Console.WriteLine(cq.Count); 

      You can do the same thing based on Task.

       using System.Threading.Tasks; var cq = new ConcurrentQueue<TrafficStat>(); var root = @"C:\Temp\logs\"; // параллельно ... var ts = Directory.EnumerateFiles(root, "log*.txt").Select(file => { return Task.Run(() => { Console.WriteLine("@" + Environment.CurrentManagedThreadId + " " + file); var userstat = new TrafficStat(); // собрать статистику из файла foreach (var line in ParseFile(file, 1)) userstat.Add(line.User, line); // сохранить статистику для дальнейшего агрегирования cq.Enqueue(userstat); }); }); Task.WaitAll(ts.ToArray()); Console.WriteLine(cq.Count);