I have a TextReader object.
Now, I want to stream the whole content of the TextReader to a File. I cannot use ReadToEnd() and write all to a file at once, because the content can be of high size.
Can someone give me a sample/tip how to do this in Blocks?
using (var textReader = File.OpenText("input.txt"))
using (var writer = File.CreateText("output.txt"))
{
do
{
string line = textReader.ReadLine();
writer.WriteLine(line);
} while (!textReader.EndOfStream);
}
Something like this. Loop through the reader until it returns null and do your work. Once done, close it.
String line;
try
{
line = txtrdr.ReadLine(); //call ReadLine on reader to read each line
while (line != null) //loop through the reader and do the write
{
Console.WriteLine(line);
line = txtrdr.ReadLine();
}
}
catch(Exception e)
{
// Do whatever needed
}
finally
{
if(txtrdr != null)
txtrdr.Close(); //close once done
}
Use TextReader.ReadLine:
// assuming stream is your TextReader
using (stream)
using (StreamWriter sw = File.CreateText(#"FileLocation"))
{
while (!stream.EndOfStream)
{
var line = stream.ReadLine();
sw.WriteLine(line);
}
}
Related
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();
}
}
}
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
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();
}
}
}
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.
To answer the actual question:
using var reader = new StreamReader(someInput);
using var writer = new StreamWriter(someOutput);
reader.CopyTo(writer.BaseStream);
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);
}
}
}
}
i read the file, when Form loads
string line;
if (!File.Exists(dir)) File.Create(dir);
StreamReader reader = new StreamReader(dir);
while ((line = reader.ReadLine()) != null)
{ /* do something */}
reader.Close();
then I press the button and write something in this file. but in line
System.IO.StreamWriter file = new StreamWriter(dir);
i have an error "file used by another process". why? i close my reader..
File.Create opens the file and returns you FileStream. Try:
using (var fs = File.Open(dir, FileMode.OpenOrCreate))
{
using (var reader = new StreamReader(fs))
{
while ((line = reader.ReadLine()) != null)
{ /* do something */}
}
}
EDIT
You can also do
if (!File.Exists(dir)) File.Create(dir).Close();
to make sure stream is closed
These 2 lines conflict:
if (!File.Exists(dir)) File.Create(dir);
StreamReader reader = new StreamReader(dir);
because File.Create() creates a new file and keeps it open. Therefore blocking the opening of the file for the StreamReader.
On the API level, File.Create() does not what you think. It is very different from Directory.Create().
But functionally your code makes no sense either, why would you create a new file just before reading it? It will always be empty.
Just use
if (File.Exitst(dir))
{
var lines = System.IO.File.ReadLines(dir);
foreach(string line in lines) { /* do something */ }
}
I have binary file
BinaryWriter binwriter = new BinaryWriter(File.Open("C:\\temp\\Users.bin", FileMode.Create));
binwriter.Write(buff);
binwriter.Close();
It works, but how can I read data from this file?
I need to read new line each time, while it is not end of file.
BinaryReader binreader = new BinaryReader(File.Open("C:\\temp\\Users.bin", FileMode.Open));
byte[] m = binreader.ReadBytes(??????); //I to read only 1 line to m, and then I need to read again new line to m.
Binary file doesn't have the concept of a "line", however you can try to read it like a text file by doing this way :
using (var streamReader = new StreamReader(filePath))
{
string line;
while ((line = streamReader.ReadLine()) != null)
{
Console.WriteLine(line);
}
}
using (StreamReader sr = new StreamReader(path))
{
while (sr.Peek() >= 0)
{
Console.WriteLine(sr.ReadLine());
}
}
you can of course adapt it to your needs instead of printing it on the Console.
Plenty of information on StreamReader and not locking files on stackoverflow, but does a dialogue box somehow change that? I'd have to say no, but maybe I am not using it right, and it is locking the file? My code is:
private void read1()
{
TextReader tr = new StreamReader(#"T:\\testfile");
string input = null;
while ((input = tr.ReadLine()) != null)
{
if (input.Contains("test"))
{
MessageBox.Show(input);
}
}
}
I think you need to use a FileStream to do that.
Also, you're not closing your stream or calling Dispose() on it. You should use a using statement to make sure it happens. The following code should ensure the file isn't locked.
private void read1()
{
using (var fs = new FileStream(#"T:\testfile", FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) {
using (var tr = new StreamReader(fs)) {
string input = null;
while ((input = tr.ReadLine()) != null)
{
if (input.Contains("test"))
{
MessageBox.Show(input);
}
}
}
}
}
I'm overwriting a file using C# in Windows Phone 7. When I do this a seemingly random character is added to the start of each line.
Why is this happening?
Code:
public static bool overwriteFile(string filename, string[] inputArray)
{
try
{
IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication();
FileStream stream = store.OpenFile(filename, FileMode.Create);
BinaryWriter writer = new BinaryWriter(stream);
foreach (string input in inputArray)
{
writer.Write(input + "\n");
}
writer.Close();
return true;
}
catch (IOException ex)
{
return false;
}
}
Lodaing Code:
public static Idea[] getFile(string filename)
{
try
{
IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication();
string fileContents = null;
if (store.FileExists(filename)) // Check if file exists
{
IsolatedStorageFileStream save = new IsolatedStorageFileStream(filename, FileMode.Open, store);
StreamReader streamReader = new StreamReader(save);
fileContents = streamReader.ReadToEnd();
save.Close();
}
string[] lines = null;
if (fileContents != null)
{
lines = fileContents.Split('\n');
}
Idea[] ideaList = null;
if (lines != null)
{
ideaList = new Idea[lines.Length];
for (int i = 0; i < lines.Length; i++)
{
ideaList[i] = new Idea(lines[i].TrimEnd('\r'));
}
}
return ideaList;
}
catch (IOException ex)
{
return null;
}
}
The random character is a length prefix; see http://msdn.microsoft.com/en-us/library/yzxa6408.aspx.
You should be using some type of TextWriter to write strings to the file; NOT a BinaryWriter.
A StreamWriter might be the best and then you could use the WriteLine method.
Instead of using '\n', try using Environment.NewLine
You are using a BinaryWriter to write, and a TextReader to read. Change your write code to use a StreamWriter (which is a TextWriter) instead of a BinaryWriter. This will also get you the WriteLine method that Naveed recommends.
try changing this
writer.Write(input + "\n");
to
writer.WriteLine(input);