views:

114

answers:

5

Hi Friends,

My file named as test.txt contains

This document is divided into about 5 logical sections starting with a feature and structure overview, followed by an overview of built in column and cell types. Next is an overview of working with data, followed by an overview of specific major features. Lastly, a “best practice” section concludes the main part of this document.

Now i want to delete 2nd line of the file. How to do it using c#?

Thanks in advance. Naveenkumar

+1  A: 

You can acheive this by splitting the text by \n and then using LINQ to select the lines you want to keep, and re-joining them.

var lineNum=5;
var lines=File
    .ReadAllText(@"src.txt")
    .Split('\n');
var outTxt=String
    .Join(
        "\n",
        lines
            .Take(lineNum)
            .Concat(lines.Skip(lineNum+1))
            .ToArray()
    );
spender
`File.ReadAllLines()` might be easier...
ck
This method suffers from loading the entire file into memory, and then produces a near copy in memory (minus the second line). Therefore caution should be exercised when the file is big and you have memory constraints.
Alex Humphrey
+4  A: 
List<string> lines = File.ReadAllLines(@"filename.txt").ToList();
if(lines.Count>lineNum){
   lines.RemoveAt(lineNum);
}
File.WriteAllLines(@"filename.txt",lines.ToArray());
Akash Kava
This code is short and also correct - which is the main thing. However, note that it will load the entire file's contents into memory at once. It's usefulness therefore depends on the size of the file and how much memory you have to spare.
Alex Humphrey
A: 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;


namespace rem2ndline
{
    class Program
    {
        static void Main(string[] args)
        {
            string inPath = @"c:\rem2ndline.txt";
            string outPath = @"c:\rem2ndlineresult.txt";
            StringBuilder builder = new StringBuilder();

            using (FileStream fso = new FileStream(inPath, FileMode.Open))
            {
                using (StreamReader rdr = new StreamReader(fso))
                {
                    int lineCount = 0;
                    bool canRead = true;
                    while (canRead) 
                    {
                        var line = rdr.ReadLine();
                        lineCount++;
                        if (line == null)
                        {
                            canRead = false;
                        }
                        else
                        {
                            if (lineCount != 2)
                            {
                                builder.AppendLine(line);   
                            }
                        }
                    }
                }

            }

            using(FileStream fso2 = new FileStream(outPath, FileMode.OpenOrCreate))
            {
                using (StreamWriter strw = new StreamWriter(fso2)) 
                {
                    strw.Write(builder.ToString());
                }
            }
        }
    }
}
A: 

Here's what I'd do. The advantage is that you don't have to have the file in memory all at once, so memory requirements should be similar for files of varying sizes (as long as the lines contained in each of the files are of similar length). The drawback is that you can't pipe back to the same file - you have to mess around with a Delete and a Move afterwards.

The extension methods may be overkill for your simple example, but those are two extension methods I come to rely on again and again, as well as the ReadFile method, so I'd typically only have to write the code in Main().

class Program
{
  static void Main()
  {
    var file = @"C:\myFile.txt";
    var tempFile = Path.ChangeExtension(file, "tmp");

    using (var writer = new StreamWriter(tempFile))
    {
      ReadFile(file)
      .FilterI((i, line) => i != 1)
      .ForEach(l => writer.WriteLine(l));    
    }

    File.Delete(file);
    File.Move(tempFile, file);
  }

  static IEnumerable<String> ReadFile(String file)
  {
    using (var reader = new StreamReader(file))
    {
      while (!reader.EndOfStream)
      {
        yield return reader.ReadLine();
      }
    }
  }
}

static class IEnumerableExtensions
{
  public static IEnumerable<T> FilterI<T>(
      this IEnumerable<T> seq, 
      Func<Int32, T, Boolean> filter)
  {
    var index = 0;

    foreach (var item in seq)
    {
      if (filter(index, item))
      {
        yield return item;
      }

      index++;
    }
  }

  public static void ForEach<T>(
      this IEnumerable<T> seq,
      Action<T> action)
  {
    foreach (var item in seq)
    {
      action(item);
    }
  }
}
Alex Humphrey
+1  A: 

Here's a pretty efficient way to do it.

FileInfo x = new FileInfo(@"path\to\original");
string xpath = x.FullName;

FileInfo y = new FileInfo(@"path\to\temporary\new\file");

using (var reader = x.OpenText())
using (var writer = y.AppendText())
{
    // write 1st line
    writer.WriteLine(reader.ReadLine());

    reader.ReadLine(); // skip 2nd line

    // write all remaining lines
    while (!reader.EndOfStream)
    {
        writer.WriteLine(reader.ReadLine());
    }
}

x.Delete();
y.MoveTo(xpath);
Dan Tao
+1 - similar principles to mine, without the reusability-mania!
Alex Humphrey