Diskuze: textový parser, potřebuji pár rad
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.
Jan Vargovský:1.6.2016 20:57
- Chybí tam jen konec? Kdyžtak více infa
- Ukaž kód...
- string.Split(...)
Antonín Tonini:1.6.2016 20:59
(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.
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
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
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
Antonín Tonini:2.6.2016 19:43
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.
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();
}
Michal Štěpánek:3.6.2016 18:39
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...
Antonín Tonini:3.6.2016 21:00
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.Seek(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
}
}
+20 Zkušeností
+2,50 Kč
Zobrazeno 11 zpráv z 11.