Slettet bruger
07. april 2009 - 18:26
Der er
16 kommentarer og 1 løsning
Redigere enkelt linje i tekstfil
Hej eksperter, Jeg har behov for at ændre en enkelt linje i en fil, og jeg kan ikke bare læse hele filen, rette linjen og gemme filen igen, da der er tale om en tekstfil på 96 MB, der skal opdateres mindst 20 gange i sekundet. Hvad kan jeg gøre?
Annonceindlæg fra DE-CIX
07. april 2009 - 18:45
#1
Skifte fra flad fil til database ! :-)
07. april 2009 - 18:47
#2
Det er principielt umuligt at erstatte en linie midt i en fil med en vilkaarlig anden tekst. Hvis du kan garantere at det nye anhold er praecis lige saa langt som det gamle indhold, saa kan du overskriver med brug af Stream Seek og Write.
Slettet bruger
07. april 2009 - 19:34
#3
#2 Det kan jeg - lige et øjeblik.
Slettet bruger
07. april 2009 - 20:18
#4
Godt så, jeg har nu lavet en mekanisme til at finde index for hvert af de tegn, der skal erstattes. Dog skal de nye tegn vist opgiver per byte, så hvordan konverterer jeg en char til et byte array?
07. april 2009 - 20:23
#5
Encoding.UTF8.GetBytes(dinstring) Encoding.Default.GetBytes(dinstring) vil jeg tro
Slettet bruger
07. april 2009 - 21:40
#6
Jeg kan ikke helt få det til at virke, men det har nok noget at gøre med følgende: //... for (int i = 0; i < 3; i++) { if (GetProperties(i)[0] == "2") { Progress++; continue; } while (CurrentThreads >= MaxThreads) ; _Index = i; Console.WriteLine("Before: " + _Index.ToString()); new Thread(new ThreadStart(StartThread)).Start(); } //... private static void StartThread() { Console.WriteLine("After: " + _Index.ToString()); CurrentThreads++; int index = _Index; Console.WriteLine(index.ToString() + ": New thread."); string[] p = GetProperties(index); Console.WriteLine(index.ToString() + ": Waiting..."); while (!_SaveAllowed) ; _SaveAllowed = false; Console.WriteLine(index.ToString() + ": Ready."); // Status -> 1 SaverStream = new FileStream(_Source, FileMode.OpenOrCreate); Saver = new StreamWriter(SaverStream); Saver.BaseStream.Seek(Entries[index], SeekOrigin.Begin); Console.WriteLine(index.ToString() + ": " + Saver.BaseStream.Position.ToString()); Saver.BaseStream.Write(Encoding.Unicode.GetBytes("1"), 0, 1); Saver.Close(); SaverStream.Close(); // TODO: Download file // TODO: Status -> 2 _SaveAllowed = true; Progress++; CurrentThreads--; } Output: Before: 0 Before: 1 Before: 2 After: 2 2: New thread. 2: Waiting... 2: Ready. After: 2 2: New thread. 2: Waiting... After: 2 2: New thread. 2: Waiting... 2: 388 2: Ready. 2: Ready. 2: 388 2: 388 Hvordan kan _Index ændres til 2 for alle gennemløb, når den kun håndteres uden for multitrådet kode?
08. april 2009 - 03:13
#7
Vil du virkeligt bruge Encoding.Unicode således at "1" bliver til 2 bytes ?
08. april 2009 - 03:16
#8
_Index er vel et static field, så når den er blevet talt op til 2 så forbliver den 2. Og det kan sagtens tænkes at din for løkke kører alle 3 genneløb igennem inden de startede tråde faktisk begynder at køre. Skal du evt. have sendt _Index med over som argument til StartThread ??
08. april 2009 - 03:17
#9
Din StreamWriter bruger du vel slet ikke.
08. april 2009 - 03:17
#10
Og jeg gætter på at der mangler noget synkronisering.
Slettet bruger
08. april 2009 - 09:33
#11
#7 Jeg går ud fra, at tekstfilen indeholder 16-bit-tekst i forvejen...? #8 Aha, ja, så må jeg finde ud af noget smartere. #9 Næh :) Jeg er bare så vandt til at bruge den, at jeg ikke overvejede, at jeg faktisk har omgået det her... Så den skal selvfølgelig fjernes. #10 Yesh. Jeg får lige styr på mine threads.
Slettet bruger
08. april 2009 - 09:35
#12
#11#7 Næh, det er sgu 8 bit per karakter. Jeg har stadig ikke helt styr på, hvornår hvad anvendes :)
Slettet bruger
08. april 2009 - 09:42
#13
for (int i = 0; i < 3; i++) { if (GetProperties(i)[0] == "2") { Progress++; continue; } while (CurrentThreads >= MaxThreads) ; _Index = i; Console.WriteLine("Before: " + _Index.ToString()); _ThreadStarted = false; new Thread(new ThreadStart(StartThread)).Start(); while (!_ThreadStarted) ; } private static void StartThread() { Console.WriteLine("After: " + _Index.ToString()); CurrentThreads++; int index = _Index; _ThreadStarted = true; Console.WriteLine(index.ToString() + ": New thread."); string[] p = GetProperties(index); Console.WriteLine(index.ToString() + ": Waiting..."); while (!_SaveAllowed) ; _SaveAllowed = false; Console.WriteLine(index.ToString() + ": Ready."); // Status -> 1 Saver = new FileStream(_Source, FileMode.OpenOrCreate); Saver.Seek(Entries[index], SeekOrigin.Begin); Console.WriteLine(index.ToString() + ": " + Saver.Position.ToString()); Saver.Write(Encoding.UTF8.GetBytes("1"), 0, 1); Saver.Close(); // TODO: Download file // TODO: Status -> 2 _SaveAllowed = true; Progress++; CurrentThreads--; } Please select mode; r: Generate master reference a: Analyze sites f: Fix collection *: Download content Before: 0 After: 0 0: New thread. Before: 1 0: Waiting... 0: Ready. 0: 0 After: 1 1: New thread. 1: Waiting... Before: 2 1: Ready. After: 2 2: New thread. 2: Waiting... 1: 194 2: Ready. 2: 388 Great success :) Og det lader endda til, at programmet skriver korrekt til tekstfilen.
Slettet bruger
08. april 2009 - 09:43
#14
Jeps, det virker. Tak for hjælpen... Bare smid et svar, så opretter jeg en ny tråd, hvis jeg støder på flere problemer.
09. april 2009 - 02:30
#15
OK
09. april 2009 - 02:30
#16
Men jeg tror stadig at koden kan bruge en ordentlig overhaling.
Slettet bruger
09. april 2009 - 03:25
#17
Ja, det burde nok laves med en database.
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.