7

I need to use StreamReader to read a .txt file on a console application, then create a new file or backup with a different name but same content. The problem is i cant figure out how to use the content from the first file to place into the new one. (This is for a school thing and im new to C#)

using System;
using System.IO;
namespace UserListCopier
{
    class Program
    {
        static void Main()
        {
            string fineName = "zombieList.txt";

            StreamReader reader = new StreamReader(fineName);

            int lineNumber = 0;

            string line = reader.ReadLine();

            while (line != null) {
                lineNumber++;
                Console.WriteLine("Line {0}: {1}", lineNumber, line);
                line = reader.ReadLine();
            }

            StreamWriter writetext = new StreamWriter("zombieListBackup.txt");

            writetext.Close();
            System.Console.Read();
            reader.Close();
        }
    }
}
Kohei TAMURA
  • 4,970
  • 7
  • 25
  • 49
claraichu
  • 71
  • 1
  • 1
  • 2

5 Answers5

9

Lets consider you have opened both streams, similar @jeff's solution, but instead of ReadToEnd (not really steaming effectively), you could buffer the transfer.

_bufferSize is an int set it to a buffer size that suits you (1024, 4096 whatever)

private void CopyStream(Stream src, Stream dest)
{
    var buffer = new byte[_bufferSize];
    int len;
    while ((len = src.Read(buffer, 0, buffer.Length)) > 0)
    {
        dest.Write(buffer, 0, len);
    }
}

here is a gist, containing a class which calculates the speed of transfer https://gist.github.com/dbones/9298655#file-streamcopy-cs-L36

dbones
  • 4,415
  • 3
  • 36
  • 52
5

This will do that:

using System;
using System.IO;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var reader = new StreamReader(@"C:\MyOriginalFile.txt"))
            using (var writer = new StreamWriter(@"C:\MyNewFile.txt", append: false))
            {
                writer.Write(reader.ReadToEnd());
            }
            Console.Read();
        }
    }
}
Jeff Prince
  • 658
  • 6
  • 13
  • 15
    But won't this read the whole input stream in one go and then write it out in one go? Doesn't this lose the point of using streams? If the data is large (multiple gigabytes) then you'll have the whole thing in memory in one go, instead of just a sliding window. – Martin Eden Jun 04 '17 at 17:49
2

For files on the disk, you just need File.Copy(inputPath, outputPath). I'm not certain whether this streams the content efficiently, or whether it reads it all into memory and then writes it all out in one go.

So for large files, or if you have a stream that doesn't resolve to a path on the disk, you can efficiently copy from one to the other, using the following functions:

private void copyFile(string inputPath, string outputPath)
{
    using (var inputStream = StreamReader(inputPath))
    {
        using (var outputStream = StreamWriter(outputPath))
        {
            copyToOutputStream(inputStream, outputStream);
        }
    }
}

private void copyToOutputStream(StreamReader inputStream, StreamWriter outputStream)
{
    string line = null;
    while ((line = inputStream.ReadLine()) != null)
    {
        outputStream.WriteLine(line);
    }
    outputStream.Write(inputStream.ReadToEnd());
}

This function copies from the input stream to the output stream one line at a time until the input stream ends. This means it only has one line in memory at a time (rather than the whole file) and that it can begin writing to the disk before the first stream has finished being read in / generated.

Martin Eden
  • 6,143
  • 3
  • 30
  • 33
  • 1
    Note that this will cause problems with binary data - or generally any file that does not contain line breaks and is very large. Also it can change the type of linebreak (LF -> CRLF). – Benno Straub Apr 18 '19 at 09:20
0
public static void ReadFromFile()
{
    using (StreamReader sr = File.OpenText(@"D:\new.txt"))
    {
        string line = null;
        while ((line = sr.ReadLine()) != null)
        {
            using (StreamWriter sw = File.AppendText(@"D:\output.txt"))
            {
                sw.WriteLine(line);
            }
        }
    }
}
Nick is tired
  • 6,860
  • 20
  • 39
  • 51
0

To answer the actual question:

using var reader = new StreamReader(someInput);
using var writer = new StreamWriter(someOutput);
reader.CopyTo(writer.BaseStream);
Brendan Molloy
  • 1,784
  • 14
  • 22
  • StreamReader has no CopyTo method. BaseStream property should be called here `reader.BaseStream.CopyTo()` – Sarrus Sep 14 '21 at 05:21