Solved

c# Move file pointer to beginning of file streamwriter

Posted on 2011-02-28
48
979 Views
Last Modified: 2012-05-11
I have a list of lists:
List = ( ( 1,2,3,4),(5,6,7,8),(9,10,11,12));
i want to write the list to a file  in that way.
1 5 9
2 6 10
3 7 11
4 8 12
But what i am getting is:
1
2
3
4
5
6
7
8
.
.
.
I tried
 data.BaseStream.Seek(0, SeekOrigin.Begin);

Open in new window


But it's not working!! the pointer isn't getting to the beginning of the file.
0
Comment
Question by:dadadude
  • 22
  • 13
  • 7
  • +2
48 Comments
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 34995493
Please show your code as to how you initialise the list of lists
0
 

Author Comment

by:dadadude
ID: 34995615
code Part 1:
suppose that i have 5 (10x10) 2D arrays. matrix1 to matrix5
List of lists initialization:
 List<String[,]> matrix = new List<String[,]>();

Open in new window


part 2: filling the list with 2D-arrays:
int numberOfMatrices = 5;
for (int k = 0; k < numberOfMatrices; k++){
for (int i = 0; i < 10; i++){
for (int j = 0; j < 10;j++){
matrix.Add(matrix1[i,j]);
}
}
}

Open in new window

write matrices to file
StreamWriter data = new StreamWriter("result.txt");
        for (int i = 0; i < matrix.Count; i++)
        {

            data.BaseStream.Seek(0, SeekOrigin.Begin);
            if (i > 0 ) data.Write("    ");
            for (int x = 0; x < matrix[i].GetLength(1); x++)
            {
               
                for (int y = 0; y < matrix[i].GetLength(0); y++)
                {
                    
                    string value = matrix[i][y, x];
                    
                    data.WriteLine(value);
                }
               

            }
        }
        data.Close();

Open in new window

0
 
LVL 10

Expert Comment

by:Jacco
ID: 34995619
You mean something like this?

foreach(var list in yourListList)
{
  foreach(var v in list)
  {
    yourStreamWriter.Write(v.ToString() + " ");
  }
  yourStreamWriter.WriteLine();
}
0
 

Author Comment

by:dadadude
ID: 34995646
i think jacco it should be the opposite:
foreach(var list in yourListList)
{
  foreach(var v in list)
  {
    yourStreamWriter.WriteLine(v.ToString());
  }
  yourStreamWriter.Write(" ");
}
so for each list inside the list. it will write the elements of the inner-list as column then go back to the beginning of the file and write the elements of second inner-list as column etc...
the problem is that they are being written as 1 column and not getting to the beginning of the file
0
 
LVL 42

Expert Comment

by:sedgwick
ID: 34995669
if u initialized your list using List<List<int>> then simply loop through inner List:.
here's an example:

List<List<int>> lists = new List<List<int>>();
            lists.Add(new List<int>(new int[] { 1, 2, 3, 4 }));
            lists.Add(new List<int>(new int[] { 5, 6, 7, 8 }));
            lists.Add(new List<int>(new int[] { 9, 10, 11, 12 }));

            StringBuilder sb = new StringBuilder();
            int max = lists.Select(n => n.Count).Max();
            for (int i = 0; i < max; i++)
            {
                foreach (List<int> list in lists)
                {
                    if (list.Count > i)
                    {
                        sb.Append(list[i] + " ");
                    }
                }
                sb.AppendLine();
            }

            using (StreamWriter sw = new StreamWriter(@"D:\temp\output.log"))
            {
                sw.WriteLine(sb.ToString());
            }

Open in new window

0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 34995677
int numberOfMatrices = 5;
for (int k = 0; k < numberOfMatrices; k++){
for (int i = 0; i < 10; i++){
for (int j = 0; j < 10;j++){
matrix.Add(matrix1[i,j]);
}
}
}


and what is matrix1 ?
0
 
LVL 10

Expert Comment

by:Jacco
ID: 34995680
Ah ok, misread the data.

If all list have equal amounts of data you could do:

for(int c = 0; c <= yourListList[0].Count-1; c++)
{
  foreach(var list in yourListList)
  {
    yourStreamWriter.Write(list[c].ToString() + " ");
  }
  yourStreamWriter.WriteLine();
}
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 34995704
Is this what you require?

int numberOfMatrices = 5;
for (int k = 0; k < numberOfMatrices; k++){
for (int i = 0; i < 10; i++){
for (int j = 0; j < 10;j++){
matrix.Add(matrix1[j, i]);   //Note the swapping of i and j from your code
}
}
}
0
 

Author Comment

by:dadadude
ID: 34995725
AndyAinscow:
sorry for the confusion:
String [,] matrix1 = new String[10,10]
String [,] matrix2 = new String[10,10]
String [,] matrix3 = new String[10,10]
....

Open in new window

Jacco: no problem i'll check it.
sedgwick: I think that my question was confusing. it's a list of 2D arrays lol it's weird. but it isn't the same principle?
0
 

Author Comment

by:dadadude
ID: 34995734
AndyAinscow: I already did that I swapped the i,j . u mean like the transpose of the 2D array?
already did that. I don't know why it is wrong.
0
 

Author Comment

by:dadadude
ID: 34995769
the problem is the following:
I have the famous List:
List<String[,]> matrix = new List<String[,]>();

Open in new window


which is filled with 2D arrays. till now it's ok .
2D Array of different length:
so i want to loop through the list:
Write the first 2D array array. Then go back to line 1. Write the second 2D array:
For example:

matrix 1 = {{1,2,3,4}, {5,6,7,8}}
matrix2 =  {{1,2,3,4}, {5,6,7,8},{9,10,11,12}}

matrix.Add(matrix1);
matrix.Add(matrix2);

Writing to file:

i should have:

1 5 1 5 9
2 6 2 6 10
3 7 3 7 11
4 8 4 8 12

that's basically it.
0
 

Author Comment

by:dadadude
ID: 34995779
please check code

StreamWriter data = new StreamWriter(file);
       
        for (int i = 0; i < matrix.Count; i++)
        {
            //go back to start of file
            data.BaseStream.Seek(0, SeekOrigin.Begin);
            if (i > 0 ) data.Write("    ");
            for (int x = 0; x < matrix[i].GetLength(1); x++)
            {
               
                for (int y = 0; y < matrix[i].GetLength(0); y++)
                {
                    
                    string value = matrix[i][y, x];
                    
                    data.WriteLine(value);
                }
                //go back to start of the file.
                data.BaseStream.Seek(0, SeekOrigin.Begin);

            }
        }
        data.Close();

Open in new window

0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 34995780
I'm trying to understand what you are doing in your code.  From your question it seems like you wanted the rows and columns transposed for the printout, that is why I wondered if just swapping the i and j indices would achieve what you wanted.  But that still didn't affect your ordering in the log file?

ps.  I think you mean matrix[k], not matrix1...
0
 
LVL 44

Assisted Solution

by:AndyAinscow
AndyAinscow earned 150 total points
ID: 34995793
>>Write the first 2D array array. Then go back to line 1. Write the second 2D array:

Aha - NO CAN DO.  You need to construct each line then write the lines to the file.  Going back in the file will (at best) just overwrite the previous contents, not insert as you think.
0
 
LVL 10

Expert Comment

by:Jacco
ID: 34995812
Correct: Can't go back in stream writing :-)
0
 

Author Comment

by:dadadude
ID: 34995831
oh ok. now i have a new problem. gee it's complicated now.
I tried to open the file again it says: File already in use.
sheeshhhhhhhhhhhhhhhhhhhh
0
 

Author Comment

by:dadadude
ID: 34995836
i'll try as u sedgwick: Stringbuilder. then write them to the file.
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 34995844
>>I tried to open the file again it says: File already in use.

Oh, an easy one - just close the file.  Stop the debugger / development environment.  (You might need a reboot if that doesn't cure it)
0
 

Author Comment

by:dadadude
ID: 34995847
this feature should be added in the new c# version not fair . lol
i didn't use c# since 6 years i came back again that's why i am a little bit lost.
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 34995851
Stringbuilder isn't necessarily necessary.  You just need to get the indices correct in your loop when writing to file.  Currently you want to work down a column (filewise) then attempt the next column.  Instead you should work across a row.
Typically this is just something like using j, i instead of i, j when accessing the array.
0
 
LVL 10

Expert Comment

by:Jacco
ID: 34995878
To prevent file open issues you might consider starting to use "using" sections:

using(var fs = new FileStream("data.tst", FileMode.Create))
{
  using(var sw = new StreamWriter(fs))
  {
    ... your code ...
  }
}
0
 
LVL 11

Expert Comment

by:Sudhakar Pulivarthi
ID: 34995881
Hi,

Here is the code modified from sedgwick: which works beautifully as per ur requirement. Please check it out dadadude.
int maxCount = 0;

            List<List<int>> lists = new List<List<int>>();
            lists.Add(new List<int>(new int[] { 1, 2, 3, 4 }));
            lists.Add(new List<int>(new int[] { 5, 6, 7, 8 }));
            lists.Add(new List<int>(new int[] { 9, 10, 11, 12 }));

            StringBuilder sb = new StringBuilder();

            foreach (List<int> list in lists)
            {
                // Get the max count in the list.
                if (list.Count > maxCount)
                {
                    maxCount = list.Count;
                }
            }

            for (int i = 0; i < maxCount; i++)
            {
                foreach (List<int> list in lists)
                {
                    if (list.Count > i)
                    {
                        sb.Append(list[i] + " ");
                    }
                }

                sb.AppendLine();
            }

            using (StreamWriter sw = new StreamWriter(@"C:\output.log"))
            {
                sw.WriteLine(sb.ToString());
            }

Open in new window

0
 

Author Comment

by:dadadude
ID: 34995904
I have to go back n times to the beginning of the file if i have a 2D array of n rows.
Then go back n times to the beginning of the list again if i have a n length List.
0
 
LVL 11

Expert Comment

by:Sudhakar Pulivarthi
ID: 34995916
Hi
Here is the code without stringbuilder. direct write to the file.
Pls provide a sample data for the requirement...
int maxCount = 0;

            List<List<int>> lists = new List<List<int>>();
            lists.Add(new List<int>(new int[] { 1, 2, 3, 4 }));
            lists.Add(new List<int>(new int[] { 5, 6, 7, 8 }));
            lists.Add(new List<int>(new int[] { 9, 10, 11, 12 }));

            foreach (List<int> list in lists)
            {
                // Get the max count in the list.
                if (list.Count > maxCount)
                {
                    maxCount = list.Count;
                }
            }

            using (StreamWriter sw = new StreamWriter(@"C:\output.log"))
            {
                for (int i = 0; i < maxCount; i++)
                {
                    foreach (List<int> list in lists)
                    {
                        if (list.Count > i)
                        {
                            sw.Write(list[i] + " ");
                        }
                    }

                    sw.Write(Environment.NewLine);
                }
            }

Open in new window

0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 44

Expert Comment

by:AndyAinscow
ID: 34995950
>>I have to go back n times to the beginning of the file if i have a 2D array of n rows.

You don't understand my earlier comment.  You NEVER go back to the beginning of the file, that just overwrites the existing contents.
0
 
LVL 42

Accepted Solution

by:
sedgwick earned 350 total points
ID: 34996044
@dadadude

instead of manipulating the file while writing to it, you better use stringbuilder to create a textual stream of the outcome and then write it all to the file.
the concept of moving the file pointer to achieve your requirement is fundamentally wrong.
instead, you need simply two loops which iterates the list of 2d arrays.

according to your requirement you want to display in each line (in the file), for each row, the data from a certain column.
the data will be represent in the file in the following manner:

[row[0],col[0]], [row[1],col[0]]
[row[0],col[1]], [row[1],col[1]]
[row[0],col[2]], [row[1],col[2]]

so basically, u need outer loop which iterates the columns and inner loop which iterates the rows.
in your case the number of columns is always 2 cause you declare your list as such (string[,])


0
 

Author Comment

by:dadadude
ID: 34996126
yes sedqwick i am trying it.
0
 

Author Comment

by:dadadude
ID: 34996391
now let me see what i did:
and here is the excel result. Well i want to switch the rows with the columns as u can see the arrow . Guess that i am close.
List<string> linesToWrite = new List<string>();
        for (int i = 0; i < matrix.Count; i++)
        {
          
            for (int k = 0; k < matrix[i].GetLength(0); k++)
            {
                StringBuilder line1 = new StringBuilder();
                for (int l = 0; l < matrix[i].GetLength(1); l++)
                {
                    line1.Append(matrix[i][k, l]).Append("    ");
                }
                linesToWrite.Add(line1.ToString());
            }
           
        }
        System.IO.File.WriteAllLines("data.txt", linesToWrite.ToArray());

Open in new window

1.jpg
0
 

Author Comment

by:dadadude
ID: 34996397
like the transpose of this matrix. U can turn the screen and look at it upside down lol
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 34996496
As I said earlier just swap k and l in the following line:
line1.Append(matrix[i][k, l]).Append("    ");   ---> line1.Append(matrix[i][l, k]).Append("    ");

Open in new window


Does that not give the result you want?
0
 

Author Comment

by:dadadude
ID: 34996542
lololololol I DID!!!!!!!!!!!!!!!! lololol I DID SWAP THEM
Look lol
 Mat = new String[mat.GetLength(1), mat.GetLength(0)];
        for (int i = 0; i < mat.GetLength(0); i++)
        {
            for (int j = 0; j < mat.GetLength(1); j++)
            {
                Mat[j, i] = mat[i, j];
            }
        }
There now it is swapped lol and still isn't working lololol. It's really getting on m nerves SHEESH
0
 

Author Comment

by:dadadude
ID: 34996555
AndyAinscow: nope not same result i'll have 1 column only.
Sheesh a simpl THING IS TAKING MOST OF MY DAY!!!!!!!!!!!!!!!!!!!!!!!!!!
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 34996567
Did you use Mat or mat when writing to file?  (You might have swapped but if you used the unswapped mat then it will still be wrong)
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 34996575
Can you post your complete code, including the contents of the arrays you are processing?  (Use dummy data if necessary)
0
 

Author Comment

by:dadadude
ID: 34996582
oh no no I am sure that i use Mat Andy. in that i am pretty sure.
0
 
LVL 42

Expert Comment

by:sedgwick
ID: 34996591
@dadadude

can u (please) post the whole code here?
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 34996596
>>oh no no I am sure that i use Mat Andy. in that i am pretty sure.
Check it to be certain.  Everyone can have an off day, especially when frustrated.
0
 

Author Comment

by:dadadude
ID: 34996670
Ok posting whole code:
Class Matrix: Where i transpose the matrices:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

public class Matrix
{
    private String[,] Mat;


    public Matrix(String[,] mat)
    {
       setMatrix(mat);
    }

    private void setMatrix(String [,] mat){
        //transpose
        
        Mat = new String[mat.GetLength(1), mat.GetLength(0)];
        for (int i = 0; i < mat.GetLength(0); i++)
        {
            for (int j = 0; j < mat.GetLength(1); j++)
            {
                Mat[j, i] = mat[i, j];
            }
        }
       
    }

    public String[,] getMatrix()
    {
        return Mat;
    }
}

Open in new window

// Created a list of indices [1,0,0,1,0,1] 1 means that i select a matrix, 0 No
List<int> index = new List<int>();
        for (int i = 0; i < g1.Count; i++)
        {

            index.Add(r.Next(0,1));
        }
Class Cluster where i do the work:
//Declaring an object mat of class Matrix
List <Matrix> mat= new List<Matrix>();
//10.orientations contour
        // initializating and filling the 2D Arrays from a DATA text File. I have to do that... 
       // it's not the most important thing
        String[,] contour = new String[obs.GetLength(0), 8];
        for (int i = 0; i < obs.GetLength(0); i++)
        {
            for (int j = 16; j < 24; j++)
            {

                contour[i, j - 16] = obs[i, j];
            }
        }
       
        mat.Add(new Matrix(contour));
        //11. Zernike
        String[,] zernike = new String[obs.GetLength(0), 35];
        for (int i = 0; i < obs.GetLength(0); i++)
        {
            for (int j = 24; j < 59; j++)
            {

                zernike[i, j - 24] = obs[i, j];
            }
        }
        mat.Add(new Matrix(zernike));
// Now i have a list of 2D matrices right??? Till now it's ok?
 List<String[,]> matrix = new List<String[,]>();
        // for loop to add the matrices to a new List matrix. now i have a list of 2D matrices
        for (int i = 0; i < index.Count; i++)
        {
            if (index[i] == 1)
            {
  
                matrix.Add(mat[i].getMatrix());
                
            }//end if

        }//end for
 List<String> linesToWrite = new List<String>();
        for (int i = 0; i < matrix.Count; i++)
        {
            
            for (int k = 0; k < matrix[i].GetLength(0); k++)
            {
                StringBuilder line1 = new StringBuilder();
                for (int l = 0; l < matrix[i].GetLength(1); l++)
                {
                    line1.Append(matrix[i][k, l]).AppendLine();
                }
                linesToWrite.Add(line1.ToString());
            }
          
           
        }
      
      
        System.IO.File.WriteAllLines("caracteristiques.txt", linesToWrite.ToArray());

Open in new window

0
 

Author Comment

by:dadadude
ID: 34996751
I have to admit :That's quite a nasty one!!
0
 
LVL 44

Expert Comment

by:AndyAinscow
ID: 34996801
I'd be very careful with code like this - you transpose the Matrix every time you (OR the system) creates a new Matrix.  This makes it potentially very difficult to understand what is the actual value in a Matrix at any time by just looking at the code.
0
 

Author Comment

by:dadadude
ID: 34996802
Well after looking and looking and loooooooooooooooooooooooooooooookingggg I found the solution:
StreamWriter sw = new StreamWriter("caracteristiques.car");
       
        for (int i = 0; i < obs.GetLength(0); i++)
        {

            foreach (String[,] entry in matrix)
            {
                for (int j = 0; j <= entry.GetUpperBound(0); j++)
                {
                   
                    sw.Write(entry[j, i] + "     ");

                }
            }
            sw.WriteLine();
        }

        sw.Close();

It was really tricky.
0
 
LVL 42

Expert Comment

by:sedgwick
ID: 34996819
i gotta ask this, why do u pass the private field String[,] Mat from the ctor to a function which initializes it???
this is better practice:

public class Matrix
{
    private readonly String[,] _matrix;

//ctor
    public Matrix(String[,] mat)
    {
       _matrix = new String[mat.GetLength(1), mat.GetLength(0)];
        for (int i = 0; i < mat.GetLength(0); i++)
        {
            for (int j = 0; j < mat.GetLength(1); j++)
            {
                _matrix[j, i] = mat[i, j];
            }
        }

    }
0
 
LVL 42

Expert Comment

by:sedgwick
ID: 34996830
then add a setter property which returns the private field:


public String[,] Matrix
{
get{return _matrix;}
}

Open in new window

0
 

Author Comment

by:dadadude
ID: 34996843
i will fix it thank you Sed. my mind is still working on c++ classes.
0
 

Author Comment

by:dadadude
ID: 34996865
sed i have a question :

public String[,] Matrix
    {
        get { return _matrix; }
    }
is giving me this: member names cannot be the same as their enclosing type
0
 
LVL 42

Expert Comment

by:sedgwick
ID: 34996890
cause Matrix is also the name of your class, so change the property to something else, for example:
public String[,] TheMatrix
    {
        get { return _matrix; }
    }
0
 

Author Comment

by:dadadude
ID: 34996897
Did c# change that much? when i first started in 2002 it was a little different.
But now after coming back i see that they added new things.

I was used to the c++ classes specially the get and set.
i have to get a new book. Anyway thanks again.
I think that the question is closed. I'll rate the answers. It's the hard part.

THANK YOU EVERYONE!!! For your help!!
0
 
LVL 42

Expert Comment

by:sedgwick
ID: 34996964
cheers :)
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Extention Methods in C# 3.0 by Ivo Stoykov C# 3.0 offers extension methods. They allow extending existing classes without changing the class's source code or relying on inheritance. These are static methods invoked as instance method. This…
Article by: Ivo
C# And Nullable Types Since 2.0 C# has Nullable(T) Generic Structure. The idea behind is to allow value type objects to have null values just like reference types have. This concerns scenarios where not all data sources have values (like a databa…
This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're looking for how to monitor bandwidth using netflow or packet s…
In this tutorial you'll learn about bandwidth monitoring with flows and packet sniffing with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're interested in additional methods for monitoring bandwidt…

746 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now