0

I'm trying to write a text file, from a datatable, text file which later on will be imported by some other application, therefor I need to have no empty lines in the exported file (at the end or between). I used the following code:

DataTable table = FisierSoldata.dtSoldata;
 var result = new StringBuilder();
        foreach (DataRow row in table.Rows)
        {
            for (int i = 0; i < table.Columns.Count; i++)
            {
                result.Append(row[i].ToString());
                result.Append(i == table.Columns.Count - 1 ? "\n" : " ");
            }
            result.AppendLine();
        }

        StreamWriter objWriter = new StreamWriter(filePath, false);
        objWriter.WriteLine(result.ToString());
        objWriter.Close();

My datatable has 26 records and when the file is generated, it has one dataline followed by one empty line and another dataline and so on and at the end after the last dataline it has 3 empty lines. How can I modify the code in order to have only datalines without the empty one between data and without the last 3 empty ones? Regards,

LE:I've found a workaround, by reading some similar thread, but the solution was to use both streamwriter and streamreader in order to remove the unneeded data (empty lines) from the file which will be generated. But I wanted to know if there's a way of getting the file as needed from the start.

BogdanM
  • 957
  • 4
  • 15
  • 32
  • If(!String.isnullorempty(result.tostring()) {objWriter.WriteLine(result.ToString());} – Marco Bong Feb 29 '16 at 08:43
  • 1
    You really want to use a space as column delimiter? That's one of the most error-prone approaches you could use. Pray that a value never contains one. – Tim Schmelter Feb 29 '16 at 08:44
  • I have to used it, as the application which further on will process the data uses space as deliminator and there are only numeric data, no user imputed data. – BogdanM Feb 29 '16 at 08:47
  • You are getting two rows because you are using both result.AppendLine and objWriter.WriteLine(). Change WriteLine() to Write(). – jdweng Feb 29 '16 at 09:04

2 Answers2

3

Why not using File.WriteAllLines, it's using a StreamWriter behind the scenes but allows simpler code:

var fileLines = table.AsEnumerable()
    .Select(row => String.Join(" ", row.ItemArray))
    .Where(line => !String.IsNullOrWhiteSpace(line));
File.WriteAllLines(filePath, fileLines);

But you really want to use a space as column delimiter? That's very error-prone. It will fail as soon as one field value contains a space.

Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
  • thanks so much. I have to used it, as the application which further on will process the data uses space as deliminator and there are only numeric data, no user imputed data. – BogdanM Feb 29 '16 at 08:50
  • Really, really nice solution. Love the Linq approach. – BogdanM Feb 29 '16 at 08:52
  • Ok, it an improvement and an opportunity for me to learn more, but it still does not solve the hole issue, as the generated file has one empty line. Should I use streamReader and parse the exported file and delete the last empty line? Or is it something missing from your code? Regards, – BogdanM Feb 29 '16 at 08:56
  • @BogdanM: can you edit your question and provide a simple, small sample DataTable which let us reproduce this issue? I have created one and added rows with values and others with empty strings or `DBNull.Value`. All rows without a value, so only spaces were excluded. So it worked as expected. No empty line in the file. – Tim Schmelter Feb 29 '16 at 09:07
  • Hello Tim and thanks for your time. It's strange indeed as when I check the fileLines variable, it has the exact number of rows as datalines, but somehow when the file is generated an empty line appears. Idk how to provide you a sample...I have only text data. Do you want to post the 26 lines from my file? I checked the datatable I used in order to get the data and it has only 26 rows as well. Please advise. Regards – BogdanM Feb 29 '16 at 09:24
  • @BogdanM see this http://stackoverflow.com/questions/11689337/net-file-writealllines-leaves-empty-line-at-the-end-of-file – Pikoh Feb 29 '16 at 09:35
  • @BogdanM: yes, Pikoh is right. That's expected behaviour. Every line is written with `StreamWrite.WriteLine` which writes a string followed by a line terminator. Is the line-terminator at the end a problem for you? – Tim Schmelter Feb 29 '16 at 09:42
  • @TimSchmelter: I think that's the reason why I get the empty line at the file's end, it's actually a line terminator. It would be great if the last data line shouldn't have the line terminator anymore...but I'm not able to change Tim's code in such fashion to get rid of it, yet – BogdanM Feb 29 '16 at 10:05
  • @BogdanM: in my opinion it would be worse if the last line would be an exception. If you would append lines you had to take care of the additional line terminator at the beginning because it was missing. It's better to be consistent with the rest of the lines. If you read these lines you can use `File.ReadLines` or `File.ReadAllLines`, both won't read this "empty line" because it doesn't exist. – Tim Schmelter Feb 29 '16 at 10:10
0

I would try to avoid to add the empty lines to the Stringbuild. The Stringclass should give appropriate functions, maybe something like this:

            String stringToTestIsEmpty = row[i].ToString();
            //Check if it is not an empty line
            if( ! String.IsNullOrWhiteSpace(stringToTestIsEmpty ))
            {
                resutl.Append(stringToTestIsEmpty);
            }
DerKasper
  • 167
  • 2
  • 11