4

I am trying to use StreamReader and StreamWriter to Open a text file (fixed width) and to modify a few specific columns of data. I have dates with the following format that are going to be converted to packed COMP-3 fields.

020100718F
020100716F
020100717F
020100718F
020100719F

I want to be able to read in the dates form a file using StreamReader, then convert them to packed fields (5 characters), and then output them using StreamWriter. However, I haven't found a way to use StreamWriter to right to a specific position, and beginning to wonder if is possible.

I have the following code snip-it.

System.IO.StreamWriter writer;

this.fileName = @"C:\Test9.txt";
reader = new System.IO.StreamReader(System.IO.File.OpenRead(this.fileName));

currentLine = reader.ReadLine();
currentLine = currentLine.Substring(30, 10);    //Substring Containing the Date
reader.Close();

...
// Convert currentLine to Packed Field 
...

writer = new System.IO.StreamWriter(System.IO.File.Open(this.fileName, System.IO.FileMode.Open));
writer.Write(currentLine);

Currently what I have does the following:

After:
!@#$%0718F
020100716F
020100717F
020100718F
020100719F 

!@#$% = Ascii Characters SO can't display 

Any ideas? Thanks!

UPDATE Information on Packed Fields COMP-3

Packed Fields are used by COBOL systems to reduce the number of bytes a field requires in files. Please see the following SO post for more information: Here

Here is Picture of the following date "20120123" packed in COMP-3. This is my end result and I have included because I wasn't sure if it would effect possible answers.

Picture of the following date 20120123 packed

My question is how do you get StreamWriter to dynamically replace data inside a file and change the lengths of rows?

Community
  • 1
  • 1
buzzzzjay
  • 1,140
  • 6
  • 27
  • 54
  • I can't seem to locate what your actual question is. It might help if you explain what a packed COMP-3 data field is. Might also help if you tell us the expected results. – Security Hound Jan 30 '12 at 18:12
  • Please don't prefix your titles with "C#" and such. That's what tags are for. – John Saunders Jan 30 '12 at 18:15
  • After BCD encoding you'll get **binary** data. Don't use StreamWriter to write it to file, use FileStream instead. – L.B Jan 30 '12 at 21:54

3 Answers3

3

I have always found it better to to read the input file, filter/process the data and write the output to a temporary file. After finished, delete the original file (or make a backup) and copy the temporary file over. This way you haven't lost half your input file in case something goes wrong in the middle of processing.

ChrisWue
  • 18,612
  • 4
  • 58
  • 83
1

You should probably be using a Stream directly (probably a FileStream). This would allow you to change position.

However, you're not going to be able to change record sizes this way, at least, not in-line. You can have one Stream reading from the original file, and another writing to a new, converted copy of the file.

John Saunders
  • 160,644
  • 26
  • 247
  • 397
0

However, I haven't found a way to use StreamWriter to right to a specific position, and beginning to wonder if is possible.

You can use StreamWriter.BaseStream.Seek method

using (StreamWriter wr = new StreamWriter(File.Create(@"c:\Temp\aaa.txt")))
{
   wr.Write("ABC");
   wr.Flush();
   wr.BaseStream.Seek(0, SeekOrigin.Begin);
   wr.Write("Z");                
}
Raj Ranjhan
  • 3,869
  • 2
  • 19
  • 29
  • 3
    That can be problematic depending on the encoding. You have to be careful not to position into the middle of a multi-byte character. – John Saunders Jan 30 '12 at 18:23
  • 2
    -1 There are other issues like `Flush`. try this: `StreamWriter wr = new StreamWriter(File.Create(@"c:\temp\aaa.txt")); wr.Write("ABC"); wr.BaseStream.Seek(0, SeekOrigin.Begin); wr.Write("Z"); wr.Close();` output won't be ZBC – L.B Jan 30 '12 at 22:38