Diskuze: textový parser, potřebuji pár rad

C# .NET .NET (C# a Visual Basic) textový parser, potřebuji pár rad American English version English version

Avatar
Dog
Člen
Avatar
Dog:
Console.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}", i, stacktemp, stacktemp1, stacktemp2, stacktemp3);
writer.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}", i, stacktemp, stacktemp1, stacktemp2, stacktemp3);

(1)jak je možné, že v konzoli to samozřejmě zobrazí vše (277 případů) a v textáku jen 268 a ten končí uprostřed řádku, jako by to nestihl zapsat tak rychle jako do konzole nebo já nevím (dělám c++)

(2)dále mám mimo if definovany promenne, ktere nefungují v if, který s nimi nepracuje, další věc, kterou nechápu.

(3)jak rozsekat string readline (text = reader.ReadLine();) tak do string text se načetl celej řádek a potřebuji vytáhnout jen pár slov :-) stačí, když napíšete tu metodu :)

Díky moc.

 
Odpovědět 1. června 19:57
Avatar
Jan Vargovský
Redaktor
Avatar
Odpovídá na Dog
Jan Vargovský:
  1. Chybí tam jen konec? Kdyžtak více infa
  2. Ukaž kód...
  3. string.Split(...)
 
Nahoru Odpovědět 1. června 20:57
Avatar
Odpovídá na Dog
Antonín Tonini:

(1) Můžeš postnout celý kód od té části, kdy otevíráš stream? Používáš blok using, či to otevíráš manuálně přes .Open()?
(2) Pokud jsem to pochopil správně, tak neskočí to bloku if ačkoliv by měl. Ověřil sis, jestli dané hodnoty nejsou null a dodáváš tomu správný vstup?
(3) Záleží na formátu toho řetězce a podle toho se zvolí metoda extrakce. Pokud to máš jen ve formátu "slovo1 slovo2 slovo3", tak stačí použít splitter (vrací pole těch slov).

string[] array = Console.ReadLine().Split('oddělovač');

Při nějakém složitějším formátu by bylo asi na místě použít regulární výrazy.

 
Nahoru Odpovědět 1. června 20:59
Avatar
Dog
Člen
Avatar
Dog:

Dávám sem dva textáky, první je můj, kód kde jsou problémy v komentářích (tento parser vytahuje jen data, se kterymi chci pracovat, není to komplatní parser, ale pouze vytahuje to s čím chci pracovat dále)... a další je logfile, který potřebuji naparsovat a ještě nevím jak přesně to udělám, aby to fungovalo všechno tak jak má.
Sharp se mi líbí asi se ho začnu učit, je tu funkce a metoda i na utření nosu :-D

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

namespace ConsoleApplication24
{
    class Program
    {

        static void Main(string[] args)
        {
            string path = @"C:\\Users\\Marek Schwarz\\Desktop\\PokerStars.log.0";
            string pathoff = @"C:\\Users\\Marek Schwarz\\Desktop\\log.txt";

            StreamReader reader = new StreamReader(path);
            StreamWriter writer = new StreamWriter(pathoff);

            string text;

            string cardtemp;
            string cardtemp1;
            string cardtemp2;

            string stacktemp;
            string stacktemp1;
            string stacktemp2;
            string stacktemp3;

            int i = 0;

            while (reader.EndOfStream == false)
            {
                text = reader.ReadLine();
                if (text.Contains("MSG_0x0009-T"))
                {
                    cardtemp = text;
                    text = reader.ReadLine();
                    if (text.Contains(":::"))
                    {
                        cardtemp1 = text;
                        text = reader.ReadLine();
                        if (text.Contains(":::"))
                        {
                            i++;
                            cardtemp2 = text;
                            Console.WriteLine("{0}\t{1}\t{2}\t{3}", i, cardtemp, cardtemp1, cardtemp2);
                            writer.WriteLine("{0}\t{1}\t{2}\t{3}", i, cardtemp, cardtemp1, cardtemp2); //(1) nevím čím to je, že mi to vždycky načte o něco mín než v consoli
                        }
                    }
                }

                if (text.Contains("MSG_0x0007-T"))
                {
                    stacktemp = text;
                    text = reader.ReadLine();
                    if (text.Contains("'F'") || text.Contains("'w'"))
                    {
                        stacktemp1 = text;
                        text = reader.ReadLine();
                        if (text.Contains("'C'") || text.Contains("'c'") || text.Contains("'W'"))
                        {
                            stacktemp2 = text;
                            text = reader.ReadLine();
                            if (text.Contains("'*'"))
                            {
                                stacktemp3 = text;
                                Console.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}", i, stacktemp, stacktemp1, stacktemp2, stacktemp3); //(3) tyhlety lajny budu chtít rozdělit a dále se něma pracovat (cardtemp, cardtemp1, cardtemp2, stacktemp, stacktemp1, stacktemp2, stacktemp3)
                                writer.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}", i, stacktemp, stacktemp1, stacktemp2, stacktemp3);
                            }
                            else
                            {
                                Console.WriteLine("{0}\t{1}\t{2}\t{3}", i, stacktemp, stacktemp1, stacktemp2); //(2)když chci dát sem např. cardtemp, cardtemp1 nebo 2, tak to píše "use unassigned local variable 'cardtemp'
                                writer.WriteLine("{0}\t{1}\t{2}\t{3}", i, stacktemp, stacktemp1, stacktemp2);
                            }
                        }
                    }
                }
            }
            Console.ReadKey();
        }
    }
}

Část log file, je to např. 50 tisíc řádků
-> MSG_0x1006-T 2454436107 0A349971
-> MSG_0x1004-T 2564984434 0B1BCD16
  sit0  nCards=2
-> MSG_0x1003-T 2454436107 0A349971
  sit1  nCards=2
  dealerPos=1
TableAnimation::dealPlayerCards
-> MSG_0x1003-T 2454436107 0A349971
TournProcessorConnection{2224984568}::connect
Game #I64u CE1F0C84
OnTableData() round -1
-> MSG_0x1006-T 2564984434 0B1BCD16
-> MSG_0x1003-T 2564984434 0B1BCD16
-> MSG_0x1003-T 2564984434 0B1BCD16
Game #I64u CE1F0C84
OnTableData() round -1
-> MSG_0x0009-T 2564984434 0B1BCD16
::: 10s
::: 14s
------ 000BCD16
Table::OnPlayerCards, myCards.changed=0, n=2, flags=0
myCards.changed=1
-> MSG_0x1004-T 2454436107 0A349971
  sit0  nCards=2
  sit1  nCards=2
  dealerPos=1
-> MSG_0x1014-T 2454436107 0A349971
CommClientConnectionPool: _COMM_MSGTYPE_CONNECT_REQUEST_ACCEPTED: thisId=120E2C57 peerId=120E285B
[2016/05/24 19:21:47]
CommClientConnectionPool: _COMM_MSGTYPE_CONNECT_REQUEST_GRANTED: thisId=120E2C57 peerId=120E285B priority=6
CommClientConnectionPool: _COMM_MSGTYPE_CONNECT_GUARD_REQUEST_GRANTED: thisId=120E2C57 peerId=120E285B sessionId=99D1FDDF priority=6
<- MSG_1020-M 3564994444 0A1BCE11
UpdateMyCard 0: 6s [BCD16]
-> MSG_1021-M 3564994444 0A1BCE11 - 0
<- MSG_1020-M 3564994444 0A1BCE11
UpdateMyCard 1: 14s [BCD16]
-> MSG_1021-M 3564994444 0A1BCE11 - 0
TournProcessorConnection{2224984568}::disconnect
-> MSG_0x1014-T 2564984434 0B1BCD16
-> MSG_0x1004-T 2564984434 0B1BCD16
  sit0  nCards=2
  sit1  nCards=2
  dealerPos=1
UpdateMyCard 0: 10s [BCD16]
UpdateMyCard 1: 14s [BCD16]
-> MSG_0x0014-T 2564984434 0B1BCD16
configAdvActions 000BCD16
box[ 0 ] 0
 act 'c' -1
 act 'F' -1
box[ 2 ] 0
 act 'c' -1
box[ 3 ] 0
 act 'c' -1
 act 'C' -1
-> MSG_0x1014-T 2564984434 0B1BCD16
[2016/05/24 19:21:49]
-> MSG_0x1014-T 2564984434 0B1BCD16
-> MSG_0x1003-T 2454436107 0A349971
-> MSG_0x1014-T 2454436107 0A349971
-> MSG_0x1003-T 2564984434 0B1BCD16
-> MSG_0x0007-T 2564984434 0B1BCD16
 'F' 65536
 'C' 410
<- MSG_0x0024-T 2564984434 0B1BCD16
configAdvActions 000BCD16
-> MSG_0x1014-T 2564984434 0B1BCD16
[2016/05/24 19:21:50]
mouse button clicked { window: 000BCD16; pos: (623,457); }
USR ACT button 'CallX' 000BCD16
<- MSG_0x0008-T 2564984434 0B1BCD16
108 'C' 410 - 0
-> MSG_0x1003-T 2454436107 0A349971
-> MSG_0x1003-T 2564984434 0B1BCD16
-> MSG_0x1001-T 2564984434 0B1BCD16
-> MSG_0x1001-T 2454436107 0A349971
[2016/05/24 19:21:51]
MoveToPot 0
-> MSG_0x1001-T 2564984434 0B1BCD16
UpdateMyCard 0: 6s [BCD16]
UpdateMyCard 1: 14s [BCD16]
UpdatePlayerCard 1 0: 13c 000BCD16
UpdatePlayerCard 1 1: 6d 000BCD16
[2016/05/24 19:21:52]
-> MSG_0x1005-T 2564984434 0B1BCD16
   nCards=3 runItTwice=0
-> MSG_0x1005-T 2454436107 0A349971
OnTableData() round 1
-> MSG_0x1005-T 2564984434 0B1BCD16
:::TableViewImpl::updateBoard() 11d (0) [BCD16]
:::TableViewImpl::updateBoard() 14d (1) [BCD16]
:::TableViewImpl::updateBoard() 8h (2) [BCD16]
OnTableData() round 1
[2016/05/24 19:21:54]
-> MSG_0x1005-T 2564984434 0B1BCD16
   nCards=1 runItTwice=0
-> MSG_0x1005-T 2454436107 0A349971
OnTableData() round 2
-> MSG_0x1005-T 2564984434 0B1BCD16
:::TableViewImpl::updateBoard() 12s (3) [BCD16]
OnTableData() round 2
[2016/05/24 19:21:55]
-> MSG_0x1005-T 2564984434 0B1BCD16
   nCards=1 runItTwice=0
-> MSG_0x1005-T 2454436107 0A349971
OnTableData() round 3
[2016/05/24 19:21:56]
-> MSG_0x1005-T 2564984434 0B1BCD16
:::TableViewImpl::updateBoard() 12c (4) [BCD16]
OnTableData() round 3
[2016/05/24 19:21:57]
-> MSG_0x0014-T 2564984434 0B1BCD16
configAdvActions 000BCD16
OnTableData() round -2
-> MSG_0x0015-T 2564984434 0B1BCD16
OnTableData() round -2
[2016/05/24 19:21:58]
-> MSG_0x1002-T 2564984434 0B1BCD16
-> MSG_0x1002-T 2454436107 0A349971
-> MSG_0x1007-T 2454436107 0A349971
-> MSG_0x1014-T 2454436107 0A349971
OnTableData() round -3
-> MSG_0x1014-T 2564984434 0B1BCD16
MoveFromPot 0
-> MSG_0x1002-T 2564984434 0B1BCD16
-> MSG_0x1007-T 2564984434 0B1BCD16
<- MSG_0x001C-T 2564984434 0B1BCD16
-> MSG_0x1014-T 2564984434 0B1BCD16
OnTableData() round -3
-> MSG_0x001B-T 2564984434 0B1BCD16
Stat 00003BD1 for 000BCD16
-> MSG_0x1004-T 2564984434 0B1BCD16
  sit0  nCards=2
  sit1  nCards=2
  dealerPos=0
TableAnimation::dealPlayerCards
-> MSG_0x0009-T 2564984434 0B1BCD16
------ 000BCD16
Table::OnPlayerCards, myCards.changed=0, n=0, flags=0
myCards.changed=1
[2016/05/24 19:21:59]
-> MSG_0x1006-T 2454436107 0A349971
-> MSG_0x1003-T 2454436107 0A349971
-> MSG_0x1003-T 2454436107 0A349971
TournProcessorConnection{2224984568}::connect
Game #I64u CE1F3235
OnTableData() round -1
-> MSG_0x1006-T 2564984434 0B1BCD16
-> MSG_0x1003-T 2564984434 0B1BCD16
-> MSG_0x1003-T 2564984434 0B1BCD16
Game #I64u CE1F3235
OnTableData() round -1
-> MSG_0x1004-T 2454436107 0A349971
  sit0  nCards=2
  sit1  nCards=2
  dealerPos=0
-> MSG_0x0009-T 2564984434 0B1BCD16
::: 6d
::: 5d
------ 000BCD16
Table::OnPlayerCards, myCards.changed=0, n=2, flags=0
myCards.changed=1
-> MSG_0x1014-T 2454436107 0A349971
CommClientConnectionPool: _COMM_MSGTYPE_CONNECT_REQUEST_ACCEPTED: thisId=120E2C58 peerId=120E285C
CommClientConnectionPool: _COMM_MSGTYPE_CONNECT_REQUEST_GRANTED: thisId=120E2C58 peerId=120E285C priority=6
CommClientConnectionPool: _COMM_MSGTYPE_CONNECT_GUARD_REQUEST_GRANTED: thisId=120E2C58 peerId=120E285C sessionId=99D22D2C priority=6
<- MSG_1020-M 3564994444 0A1BCE11
UpdateMyCard 0: 3d [BCD16]
UpdateMyCard 1: 5d [BCD16]
-> MSG_0x1014-T 2564984434 0B1BCD16
-> MSG_0x1004-T 2564984434 0B1BCD16
  sit0  nCards=2
  sit1  nCards=2
  dealerPos=0
UpdateMyCard 0: 6d [BCD16]
UpdateMyCard 1: 5d [BCD16]
-> MSG_0x0007-T 2564984434 0B1BCD16
 'F' 65536
 'C' 30
<- MSG_0x0024-T 2564984434 0B1BCD16
configAdvActions 000BCD16
-> MSG_0x1014-T 2564984434 0B1BCD16
-> MSG_1021-M 3564994444 0A1BCE11 - 0
<- MSG_1020-M 3564994444 0A1BCE11
-> MSG_1021-M 3564994444 0A1BCE11 - 0
TournProcessorConnection{2224984568}::disconnect
[2016/05/24 19:22:00]
mouse button clicked { window: 000BCD16; pos: (617,474); }
[2016/05/24 19:22:01]
USR ACT button 'CallX' 000BCD16
<- MSG_0x0008-T 2564984434 0B1BCD16
109 'C' 30 - 0
 
Nahoru Odpovědět 1. června 22:46
Avatar
Dog
Člen
Avatar
Dog:

Tak jsem uz vyřešil všechny otázky.
(1) chyběl close ()
(2) proměná nebyla inicializovava mimo if... Rozdíl oproti c++
(3) vyřešeno tím spilt

Další otazky:
Jak ten textak streamovat, myšleno tak, že se ten log stále doplňuje a já bych měl mít přístup jen k datum na první otevření, ale během toho se tam doplnili dalších např. 2 tisíce řádku.
Takhle když chci otevřít ten první parser, kterej vytahuje jen ty data se kterýma chci pracovat tak to napíše že je už používán v programu...
Potřebuji tedy log file vychází - > live stream do prvního parseru v programu, kterej bude v programu a vytahovat potřebné rádky pro druhej parser - > a z tohoto prvního parseru, do opět live stream do druhého, kterej bude vytahovat všechno co chci vytáhnout a z toho to už půjde do nějaké třídy.

Díky moc

 
Nahoru Odpovědět 2. června 15:36
Avatar
Odpovídá na Dog
Antonín Tonini:

Kdy uzavíráš ten StreamWriter z prvního parseru? Po naparsování a zapsání výsledků z prvního, nebo až po dokončení parsování z druhého parseru? Zdá se, že ti zůstává otevřený stream ze zápisu. Pokud chceš zapisovat a poté hned číst ze stejného souboru, tak bych otevřel jeden FileStream a ten předal writeru a readeru.

FileStream fs = new FileStream("cesta", FileMode.Open, FileAccess.ReadWrite);
StreamWriter writer = new StreamWriter(fs);
StreamReader reader = new StreamReader(fs);
//zápis v prvním parseru
fs.Position = 0; //čtení od začátku, filestream to tuším ale nepotřebuje
//parsování v druhém parseru

Ale nejlepší by podle mě bylo předávat ty hodnoty té dané třídě rovnou při zápisu do toho log souboru. -> Nebudeš ten soubor muset znovu načítat, nebudeš muset otevírat další StreamReader a ušetříš si čas.

 
Nahoru Odpovědět 2. června 19:43
Avatar
Dog
Člen
Avatar
Dog:

No, tak jsem úspěšně dokončil parsery (tak na 98%, protože se nějaká data ztratila u načítání a zatím bohužel nevím jak vrátit o řádek výše ve čtení. díval jsem se na MDSN a tam je nějáká funkce position, zatím jsem to ale blíže nezkoumal.

teď už jen aby to streamovalo live (hlavni priorita) ta data a k tomu budu potřebovat position, aby to vždycky nenačítalo při každým spuštění všech x set tisíc řádků.

Antonín: díky moc, zítra na to mrknu i když to zatím moc nechápu... Mám jedno tlačítko a dva textboxy a vypadá to nějak takto:

        private void button1_Click(object sender, EventArgs e)
        {
            string path = @"C:\\Users\\Marek Schwarz\\Desktop\\zakladni log.txt";
            string pathoff = @"C:\\Users\\Marek Schwarz\\Desktop\\log.txt";

            StreamReader reader = new StreamReader(path);
            StreamWriter writer = new StreamWriter(pathoff);

// promenne

            while (reader.EndOfStream == false)
            {
                //vytahne všechna data, se kterymi chci pracovat do textbooxu1 a log.txt
            }

//***********************************************************************************
            string path1 = @"C:\\Users\\Marek Schwarz\\Desktop\\log.txt";
            string pathoff1 = @"C:\\Users\\Marek Schwarz\\Desktop\\logfinal.txt";

            StreamReader reader1 = new StreamReader(path1);
            StreamWriter writer1 = new StreamWriter(pathoff1);

        //promenne

            while (reader1.EndOfStream == false)
            {
                        // vyplní do spravnych promennych data, ktera jsem potřeboval, vyplni textbox2 a logfinal.txt
            }
            writer.Close();
            reader.Close();
            writer1.Close();
            reader1.Close();
        }
 
Nahoru Odpovědět 3. června 3:22
Avatar
Dog
Člen
Avatar
Dog:

Neví někdo já nevím moc co dělat s tím tvým tipem Antonín Tonini :-) struktura kodu je znazornena o post vyse :-)

 
Nahoru Odpovědět 3. června 17:41
Avatar
Odpovídá na Dog
Michal Štěpánek:

Používej "relativní cesty" k těm souborům, bo takhle stačí drobná úprava nebo změna názvu adresáře umístění a vyskočí ti problém...

Nahoru Odpovědět 3. června 18:39
Nikdy neříkej nahlas, že to nejde. Vždycky se totiž najde blbec, který to neví a udělá to...
Avatar
Odpovídá na Dog
Antonín Tonini:

Pokud použiješ pro StreamReader zdrojový stream FileStream, tak můžeš nastavit pozici čtení, takže po každém přečtení logu si jen zapamatuješ jeho poslední pozici a při dalším čtení mu ji jen nastavíš.
Buď nastavíš při otevření instance FileStreamu property Position, nebo můžeš pozici nastavit přes FileStream.Se­ek(pozice, SeekOrigin.Begin);
Mohlo by to vypadat zhruba takto: (Použil jsem tam bloky using, ty se pak postarají o uzavření proudu, tudíž nemusíš volat reader.Close();)

private static long defaultLogPosition = 0;
private static long logPosition = 0;
private void button1_Click(object sender, EventArgs e)
{
   string directoryName = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location); //Cesta do složky, kde se nachází .exe programu
   string log = "baseLog.txt", endLog = "log.txt", finalLog = "logfinal.txt";

   using (var reader = new StreamReader(new FileStream(string.Format("{0}\\{1}", directoryName, log), FileMode.Open) { Position = defaultLogPosition })) //Při otevírání streamu si rovnou nastavíš propery Position
   using (var writer = new StreamWriter(File.Open(string.Format("{0}\\{1}", directoryName, endLog), FileMode.Append)))
   {
      string line;
      while ((line = reader.ReadLine()) != null)
      {
         //Načítání dat (reader) a ukládání do logu (writer)...
      }
      defaultLogPosition = reader.BaseStream.Position; //uložení poslední pozice čtení původního logu
   }

   using (var reader = new StreamReader(new FileStream(string.Format("{0}\\{1}", directoryName, endLog), FileMode.Open) { Position = logPosition }))
   using (var writer = new StreamWriter(File.Open(string.Format("{0}\\{1}", directoryName, finalLog), FileMode.Append)))
   {
      string line;
      while ((line = reader.ReadLine()) != null)
      {
         //Načítání do proměnných...
      }
      logPosition = reader.BaseStream.Position; //Uložení poslední   pozice čtení logu
   }
}
Akceptované řešení
+20 Zkušeností
+1 bodů
Řešení problému
 
Nahoru Odpovědět 3. června 21:00
Avatar
Dog
Člen
Avatar
Dog:

Díky!!! Moc jsi mi pomohl... vyřešil jsem to už :-)
pomocí
filestreamwatcher{
FileStream, StreamWriter, filestream.position a filestream.seek()
}

Editováno 5. června 2:45
 
Nahoru Odpovědět 5. června 2:44
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 11 zpráv z 11.