Autor Beitrag
haschme
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 57
Erhaltene Danke: 1



BeitragVerfasst: Fr 28.08.15 14:54 
Hallo zusammen,

ich versuche derzeit bestimmte Zeilen einer Datei mit Hilfe der Stream.Seek Methode zu erfassen
und dann in eine andere Datei zu schreiben.

Dabei gehe ich folgendermaßen vor:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
 StreamWriter sw = new StreamWriter(outPutFilePath, false, Encoding.GetEncoding(codepage));      
 Stream stream = File.Open(_filePath, FileMode.Open);

 int counter = 0;
 byte[] line = new byte[fileLineLength];

 foreach(int rowNumber in RowNumbers) // RowNumbers ist eine List<int>
 {
   counter++;
   
   stream.Seek((fileLineLength * (rowNumber -1)),SeekOrigin.Begin); 
   stream.Read(line,0,fileLineLength));
 }

sw.BaseStream.Write(line, 0, fileLineLength);


Bei kleinen Dateien funktioniert das auch super.
Allerdings bekomme ich bei Dateien so ca ab 2GB Größe, Probleme.

Folgende Fehlermeldung entsteht dann in der Zeile in der Seek() ausgeführt wird:
"IO.Exception Es wurde versucht, den Dateizeiger vor den Anfang der Datei zu bewegen.\r\n"

Ich habe schon überall im Internet geschaut und verschiedene Lösungsansätze
ausprobiert aber ich werde den Fehler nicht los.

Hat vielleicht jemand eine Idee oder einen Tip auf Lager?

Vielen Dank und Liebe Grüße!

Moderiert von user profile iconTh69: C#-Tags hinzugefügt
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4796
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Fr 28.08.15 16:41 
Hallo,

von welchem Datentyp ist fileLineLength?
Lagere mal den Offset als eigene long-Variable aus:
ausblenden C#-Quelltext
1:
long offset = (long)fileLineLength * (rowNumber - 1);					

So sollten keine negativen Zahlen entstehen (außer einer der rowNumber-Werte ist negativ).

Für diesen Beitrag haben gedankt: haschme
haschme Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 57
Erhaltene Danke: 1



BeitragVerfasst: Do 10.09.15 16:19 
Vielen Dank für deine Hilfe.

Für alle Anderen die vielleicht mal das selbe Problem haben, ich konnte das Problem mitlerweile beheben.
Tatsächlich war die Fehlermeldung etwas irreführend, da der Wert rein rechnerisch nie negeativ war.
Allerdings wurde der Wert zu groß um ihn erfassen zu können.

Dies hing aber anscheinend nicht nur mit den von mir genutzten Datentypen sondern auch mit der Dateigröße zusammen.

Da das Programm x86 basierend fungierte konnte die Datei mit über 2GB nicht mehr korrekt eingelesen werden.

Nachdem ich es auf Any CPU umstellte funktionierte es direkt!
Mit einem 32 Bit Betriebssystem hätte ich allerdings sicherlich wieder das selbe Problem.
Blup
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 174
Erhaltene Danke: 43



BeitragVerfasst: Mo 14.09.15 11:27 
Das hat primär nichts mit dem Betriebsystem zu tun, sondern mit dem von dir verwendeten Datentyp für die Angabe der Position innerhalb der Datei.
Seek() erwartet einen 64Bit-Datentyp als Parameter für die Position.

"int" ist eigentlich ein Datentyp, dessen Bitbreite vom Compiler abhängig ist.
Normalerweise werden 32Bit verwendet, damit könnte man maximal 4GB adressieren.
Allerdings wird das oberste Bit als Vorzeichen interpretiert.
Ergibt deine Berechnung "fileLineLength * (rowNumber -1)" 2GB oder mehr, wird das Ergebnis durch den Übertrag auf das oberste Bit also negativ.
7FFF FFFF + 0000 0001 = 8000 0000 (Das ist die Darstellung von -2GB.)

Durch die Umstellung auf "Any CPU" verändern sich vermutlich bestimmte Voreinstellungen des Compilers, der dann 64Bit verwendet.

Für diesen Beitrag haben gedankt: haschme