Append Text at exact location in text - c#

I was looking to append text to a exact location in a text file. I have used StreamReader to find the text in the file I am looking for. I thought about using StreamWriter but that obviously doesn't make sense. I was hoping to find some "append" method in some class somewhere that would help me do this but with now success. Or is there a better way to do this than to use StreamReader?
using (StreamReader sr = new StreamReader(fileName))
{
string line;
while ((line = sr.ReadLine()) != null)
{
if (line.Contains("VAR_GLOBAL CONSTANT"))
{
//append text before this variable
// e.g. (*VAR_GLOBAL CONSTANT
// append the (* before VAR_GLOBAL CONSTANT
}
if (line.Contains("END_VAR"))
{
//append text after this variable
// e.g. END_VAR*)
// append the *) after END_VAR
}
}
}
Does anyone have any thoughts on how to accomplish this?

One way to do it would be to read the file contents into a string, update the contents locally, and then write it back to the file again. This probably isn't very feasible for really large files, especially if the appending is done at the end, but it's a start:
var filePath = #"f:\public\temp\temp.txt";
var appendBeforeDelim = "VAR_GLOBAL CONSTANT";
var appendAfterDelim = "END_VAR";
var appendBeforeText = "Append this string before some text";
var appendAfterText = "Append this string after some text";
var newFileContents = File.ReadAllText(filePath)
.Replace(appendBeforeDelim, $"{appendBeforeText}{appendBeforeDelim}")
.Replace(appendAfterDelim, $"{appendAfterDelim}{appendAfterText}");
File.WriteAllText(filePath, newFileContents);

Related

How can I read Persian line in csv file c#

I want to read a simple CSV file with comma separated with this code:
var reader = new StreamReader(File.OpenRead(#"d:\34.csv"));
List<string> listA = new List<string>();
List<string> listB = new List<string>();
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
var values = line.Split(',');
listA.Add(values[0]);
listB.Add(values[1]);
}
MessageBox.Show("READ IT!!!");
But when I read the file an debug that code,attention can not read Persian or Arabic character! How can I solve that? I think my file is not valid encoding?
if your CSV file contains just one line the ReadToEnd could be acceptable, but if you have a log file composed by more than one line then it is better to read line by line using ReadLine of the StreamReader object
link for true answer and more information
using (StreamReader sr = new StreamReader("c:/temp/34.csv"))
{
string currentLine;
// currentLine will be null when the StreamReader reaches the end of file
while((currentLine = sr.ReadLine()) != null)
{
// Search, case insensitive, if the currentLine contains the searched keyword
if(currentLine.IndexOf("I/RPTGEN", StringComparison.CurrentCultureIgnoreCase) >= 0)
{
Console.WriteLine(currentLine);
}
}
}
More information
You can create a class composed of get and set for each line of the CSV . You can then instantiate an object list to retrieve the CSV lines.
Try this way :
class Program
{
static void Main(string[] args)
{
var reader = new StreamReader(File.OpenRead(#"YourCSV"),Encoding.Unicode);
List<Customer> customer = new List<Customer>();
while (!reader.EndOfStream)
{
Customer c = new Customer
{
m_line1 = null,
m_line2 = null,
};
var line = reader.ReadLine();
var tokens = line.Split(',');
c.m_line1 = tokens[0];
c.m_line2 = tokens[1];
customer.Add(c);
}
foreach(var s in customer)
{
Console.Writline(s);
Console.Readline();
}
}
}
class Customer
{
private string line1;
public string m_line1
{
get
{
return line1;
}
set
{
line1= value;
}
}
private string line2;
public string m_line2
{
get
{
return line2;
}
set
{
line2= value;
}
}
You will have to pass the character encoding to the StreamReader constructor. There is no such thing as plain text. Reading text requires knowing its encoding.
The line
using (StreamReader sr = new StreamReader("c:/temp/34.csv"))
should be
using (StreamReader sr = new StreamReader("c:/temp/34.csv"), myencoding)
what myencoding is is something only you can know. With what encoding was the file saved? That's the encoding you need there. If the file was generated on Windows, and educated guess of the most likely encoding would be it is UTF-16LE. That encoding is available as Encoding.Unicode - which is a bad name, it should have been Encoding.UTF16LE, but that's the name the .NET framework uses.
Other possible encodings that are supported by StreamReader are listed on https://msdn.microsoft.com/en-us/library/System.Text.Encoding_properties(v=vs.110).aspx
If you don't know with what encoding the file was saved, some encodings leave hints in the form of a Byte order mark sometimes abbreviated to BOM. A byte order mark are the first few bytes of a text document that tell you its encoding. You can find more information on the byte order mark, and some of its values on http://en.wikipedia.org/wiki/Byte_order_mark
Relying on the BOM is generally a bad idea, because
it's not a full-proof solution: some encodings don't use a BOM, or make the BOM optional
Even if you successfully determine the encoding, that doesn't mean that StreamReader knows how to handle that encoding (though this is unlikely, but possible)
the BOM might not be a BOM at all, but be part of the actual text (also unlikely but possible)
In some cases it is impossible to know the encoding of a file, notably if the file comes from a file upload on the web, or if someone just mailed you the file, and they don't know how they encoded it. This can be a good reason not to allow "plain text" uploads (which is reasonable because, it can do with a little repetition, there is no such thing as plain text).
tl;dr: The most likely thing to work is one of
using (StreamReader sr = new StreamReader(File.OpenRead(#"c:/temp/34.csv"),Encoding.Unicode) {
...
}
or
using (StreamReader sr = new StreamReader(File.OpenRead(#"c:/temp/34.csv"),Encoding.UTF8)
or
using (StreamReader sr = new StreamReader(File.OpenRead(#"c:/temp/34.csv"),Encoding.UTF32)

Attempting to create string from a file

Currently trying to create a string from a text file, however their seems to be an error preventing the stream reader from reading the text file correctly.
private string testString = "Cheese";
private void openToolStripMenuItem_Click(object sender, EventArgs e)
{
if (openFileDialog.ShowDialog() != DialogResult.Cancel)
{
fileName = openFileDialog.FileName;
LoadFile();
}
}
private void LoadFile()
{
String lineFromFile = "Chicken";
*StringBuilder RawFileInput = new StringBuilder();
using (StreamReader reader = new StreamReader(fileName))
{
while ((lineFromFile = reader.ReadLine()) != null)
{
RawFileInput.AppendLine(lineFromFile);
}
}*
testString = lineFromFile;
testTB.Text = testString;
}
The output should the code execute has the output textbox be empty, however should the block of code between the asterisks be commented out, the output textbox obviously displays the test phrase of Chicken. As such I'm pretty sure there is a problem with this particular block, however I can't seem to figure out what.
Thanks in advance.
If I understood well your code, you are trying to set the testTB.Text with the text in your file. Taking that in account, shouldn't your last lines be:
testString = RawFileInput.ToString();
testTB.Text = testString;
You can achieve the same result with no need of a StringBuilder, replacing your whole LoadFile method with this line:
testTB.Text = File.ReadAllText(fileName);
You should be able to read a document in entirety, like the following:
var builder = new StringBuilder();
using(var reader = new StreamReader(path))
builder.Append(reader.ReadToEnd());
That would be the ideal, as it is more performant than ReadAllText.
ReadToEnd works best when you need to read all the input from the
current position to the end of the stream. If more control is needed
over how many characters are read from the stream, use the
Read(Char[], Int32, Int32) method overload, which generally results in
better performance. ReadToEnd assumes that the stream knows when it
has reached an end. For interactive protocols in which the server
sends data only when you ask for it and does not close the connection,
ReadToEnd might block indefinitely because it does not reach an end,
and should be avoided.
If you're wanting the contents of a file to populate a textbox, just set the Multiline property to true, and use File.ReadAllLines()
testTb.Lines = File.ReadAllLines(fileName);

File in use error C# reading text from user specified file

My code is giving a runtime error that the file is in use already. I am not sure how I work around this. I need the file dialog to interact with the user but I want read through it line by line. the file is semicolon delimited and I parse it manually and feed it into the system. How can I release the file from opendialog so I can work with it. Any help much appreciated thanks in advance.
List<string> datalinestream = new List<string>();
FileDialog FD = new System.Windows.Forms.OpenFileDialog();
if (FD.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
TextReader reader = new StreamReader(FD.FileName);
using (reader)
{
string line = "";
while ((line = reader.ReadLine()) != null)
{
while (!string.Equals(reader.Read(),"/r"))
{
datalinestream.Add(GetWord(reader));
}
LuceneDB.AddUpdateLuceneIndex(new MATS_Doc( datalinestream));
datalinestream.Clear();
}
}
}
What I'd do is I will create a temporary file that contains the same information of the original text file. I will make sure to format the filename with something like a GUID so it will not cause any issues again. My code then will do all of the work on the temporary file.
Afterwards, (if you need to) update the original file with the changes that you did on the temporary file.
Working with files sometimes is a headache but workarounds or tricking the system does the job.
I would suggest separating out the FileOpenDialog interaction from the parsing.
Something like this:
List<string> datalinestream = new List<string>();
string fileName;
using(FileDialog FD = new System.Windows.Forms.OpenFileDialog())
{
if(FD.ShowDialog() == DialogResult.OK)
fileName = FD.FileName;
else
return;
}
TextReader reader = new StreamReader(fileName);
using (reader)
{
string line = "";
while ((line = reader.ReadLine()) != null)
{
while (reader.Read() != '\r')
{
datalinestream.Add(GetWord(reader));
}
LuceneDB.AddUpdateLuceneIndex(new MATS_Doc( datalinestream));
datalinestream.Clear();
}
}
I'm also assuming that you want to check for a \r character, instead of a string with the two characters / and r, as StreamReader.Read() returns a single character, otherwise your inner loop will have to change pretty drastically.

Displaying Text Content

Pretty simple one I hope. I have an article of text that I want to display in a window. Now rather than have this massive load of text in the centre of my code, can I add it as a Resource and read it out to the window somehow?
For those asking why, it's simply because it is a massive article and would be very ugly looking stuck in the middle of my code.
UPDATE FOR H.B.
I have tried a number of different approaches to this and am currently looking into the GetManifestResourceStream and using an embeddedResource (txt file) and writing that out to screen. Haven't finished testing it yet but if it works it would be a heck of a lot nicer than copying and pasting the entire text txtbox1.Text = "...blah blah blah".
_textStreamReader = new
StreamReader(Assembly.GetExecutingAssembly().GetManifestResourceStream("Problem.Explaination.txt"));
try
{
if (_textStreamReader.Peek() != -1)
{
txtBlock.Text = _textStreamReader.ReadLine();
}
}
catch
{
MessageBox.Show("Error writing text!");
}
My query remains, is there a better way of achieving this (assuming this is even successful)
Thanks
NOTE
In my example above I only want one line of text. If you were adapting this to read a number of lines from a file you would change it like so;
StreamReader _textStreamReader;
_textStreamReader = new StreamReader(Assembly.GetExecutingAssembly().GetManifestResourceStream("Problem.Explaination.txt"));
var fileContents = _textStreamReader.ReadToEnd();
_textStreamReader.Close();
String[] lines = fileContents.Split("\n"[0]);
String[] lines2;
Int16 count;
foreach (string line in lines)
{
txtBlock.Text += line;
}
Add the file as a resource and, in your code, load it into a string.
StringBuilder sb = new StringBuilder();
using (var stream = this.GetType().Assembly.GetManifestResourceStream("MyNamespace.TextFile.txt"))
using(var reader = new StreamReader(stream))
{
string line;
while ((line = reader.ReadLine()) != null)
{
sb.AppendLine(line);
}
}
ViewModel.Text = sb.ToString();
You could place that text in a text file, and read it out in code
http://msdn.microsoft.com/en-us/library/db5x7c0d.aspx

Removing the first line of a text file in C#

I can currently remove the last line of a text file using:
var lines = System.IO.File.ReadAllLines("test.txt");
System.IO.File.WriteAllLines("test.txt", lines.Take(lines.Length - 1).ToArray());
Although, how is it possible to instead remove the beginning of the text file?
Instead of lines.Take, you can use lines.Skip, like:
var lines = File.ReadAllLines("test.txt");
File.WriteAllLines("test.txt", lines.Skip(1).ToArray());
to truncate at the beginning despite the fact that the technique used (read all text and write everything back) is very inefficient.
About the efficient way: The inefficiency comes from the necessity to read the whole file into memory. The other way around could easily be to seek in a stream and copy the stream to another output file, delete the original, and rename the old. That one would be equally fast and yet consume much less memory.
Truncating a file at the end is much easier. You can just find the trunaction position and call FileStream.SetLength().
Here is an alternative:
using (var stream = File.OpenRead("C:\\yourfile"))
{
var items = new LinkedList<string>();
using (var reader = new StreamReader(stream))
{
reader.ReadLine(); // skip one line
string line;
while ((line = reader.ReadLine()) != null)
{
//it's far better to do the actual processing here
items.AddLast(line);
}
}
}
Update
If you need an IEnumerable<string> and don't want to waste memory you could do something like this:
public static IEnumerable<string> GetFileLines(string filename)
{
using (var stream = File.OpenRead(filename))
{
using (var reader = new StreamReader(stream))
{
reader.ReadLine(); // skip one line
string line;
while ((line = reader.ReadLine()) != null)
{
yield return line;
}
}
}
}
static void Main(string[] args)
{
foreach (var line in GetFileLines("C:\\yourfile.txt"))
{
// do something with the line here.
}
}
var lines = System.IO.File.ReadAllLines("test.txt");
System.IO.File.WriteAllLines("test.txt", lines.Skip(1).ToArray());
Skip eliminates the given number of elements from the beginning of the sequence. Take eliminates all but the given number of elements from the end of the sequence.
To remove fist line from a text file
System.IO.StreamReader file = new System.IO.StreamReader(filePath);
string data = file.ReadToEnd();
file.Close();
data = Regex.Replace(data, "<.*\n", "");
System.IO.StreamWriter file = new System.IO.StreamWriter(filePath, false);
file.Write(data);
file.Close();
can do in one line also
File.WriteAllLines(origialFilePath,File.ReadAllLines(originalFilePath).Skip(1));
Assuming you are passing your filePath as parameter to the function.

Categories

Resources