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.
Related
I looked around for an answer to this and couldn't find anything. All I need to do is take an input from a text file with multiple lines selected from an OpenFileDialog box. Here's a selection from my code:
if (theDialog.ShowDialog() == DialogResult.OK)
{
try
{
if ((myStream = theDialog.OpenFile()) != null)
{
using (myStream)
{
//I need this to take input given from OpenFileDialog
this.read_display.Text = input;
}
}
}
I'm probably just overlooking something really obvious, but I'm not sure.
If you want to get the text from stream, you can create a StreamReader instance and call method ReadToEnd().
string input;
using (StreamReader sr = new StreamReader(myStream))
{
input = sr.ReadToEnd());
}
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);
I have to read some parameters from a txt file and then use them in my Windows Forms application.
The txt file looks like this:
[Parameter1]
1
[Parameter2]
1000
[Parameter3]
5
[Parameter4]
0
I've been searching for the right solution on the Internet, but didn't find one. The point is to achieve these points:
1. There can be empty lines (for example 5 empty lines between 1 and [Parameter2] in the txt file and the app needs to load those parameters anyway.
2. If the txt file misses any of these parameters, the app needs to load existing ones and then I'll attribute the missing ones with default values.
Code in my app:
if (File.Exists("path.txt"))
{
FileStream fs = new FileStream("path.txt", FileMode.Open);
StreamReader sr = new StreamReader(fs);
string linia;
while ((linia = sr.ReadLine()) != null)
{
string a = string.Empty;
string b = string.Empty;
string c = string.Empty;
string LogLevelstring = string.Empty;
if (string.Compare(linia, "[Parameter1]") == 0)
a = sr.ReadLine();
if (string.Compare(sr.ReadLine(), "[Parameter2]") == 0)
b = sr.ReadLine();
if (string.Compare(sr.ReadLine(), "[Parameter3]") == 0)
c = sr.ReadLine();
if (string.Compare(sr.ReadLine(), "[Parameter4]") == 0)
LogLevelstring= sr.ReadLine();
}
fs.Close();
sr.Close();
}
This function loads line by line. When the .txt file is correct, it works, but when it has any of things i pointed above, it doesn't work.
Any help and code samples would be very appreciated. Thanks!
You could also try Regular Expresions using the Regex class to filter each row. It can shorten youre code a lot. If you need help to build youre regex try this website : https://regex101.com/.
Hope this helps :D
Jasper.
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
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.