Reading resource txt line by line - c#

Had a txt file on my desktop with code:
string source = #"C:\Users\Myname\Desktop\file.txt"
string searchfor = *criteria person enters*
foreach (string content in File.ReadLines(source))
{
if (content.StartsWith(searchfor)
{
*do stuff*
}
}
I recently just learned I can add the txt as a resource file (as it will never be changed). However, I cannot get the program to read that file.txt as a resource line by line like above. I have tried
Assembly.GetExecutingAssembly().GetManifestResourceStream("WindowsFormsApplication.file.txt")
with a stream reader but it says invalid types.
Basic concept: user enters data, turned into a string, compared to the starting line of the file.txt as it reads down the list.
Any help?
edit
Jon, I tried as a test to see if it is even reading the file:
var assm = Assembly.GetExecutingAssembly();
using (var stream = assm.GetManifestResourceStream("WindowsFormsApplication.file.txt")) ;
{
using (var reader = new StreamReader(stream))
{
string line;
while ((line = reader.ReadLine()) != null)
{
label1.Text = line;
}
}
}
It says "The name stream does not exist in the current context" and "Possible Mistaken Empty Statement" for the stream = assm.Get line

You can use a TextReader to read a line at a time - and StreamReader is a TextReader which reads from a stream. So:
var assm = Assembly.GetExecutingAssembly();
using (var stream = assm.GetManifestResourceStream("WindowsFormsApplication.file.txt"))
{
using (var reader = new StreamReader(stream))
{
string line;
while ((line = reader.ReadLine()) != null)
{
...
}
}
}
You could write an extension method on TextReader to read all the lines, but the above is simpler if you only need this once.

Found the issue:
The file, while loaded as a resource, despite all the tutorials saying it is NameSpace.File, the truth is the system puts the location as NameSpace.Resources.File, so I had to update that as well.
Then I used the following code:
string searchfor = textBox1.Text
Assembly assm = Assembly.GetExecutingAssembly();
using (Stream datastream = assm.GetManifestResourceStream("WindowsFormsApplication2.Resources.file1.txt"))
using (StreamReader reader = new StreamReader(datastream))
{
string lines;
while ((lines = reader.ReadLine()) != null)
{
if (lines.StartsWith(searchfor))
{
label1.Text = "Found";
break;
}
else
{
label1.Text = "Not found";
}
}
}

Related

Stream reader to analysis computation times

I'm very new to C#, I'm trying to develop a program to analyze computational time. The simulations program's output gives me 4 files to 4 parts of the process.
The form should present only the time in seconds (that's why i got regex.replace)
Here is some of my code , so far.
I got a error " Not possible to read form closed textreader"
private void btn_read_Click(object sender, EventArgs e)
{
string line;
OpenFileDialog openFileDialog1 = new OpenFileDialog();
openFileDialog1.Filter = "Log operation A files (*.lga)|*.lgf|Log operation B files (*.lgb)|*.lgb|Log operation C files (*.lgc)|*.lgc|Log operation D files (*.lgd)|*.lgd|All files (*.*)|*.*";
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
string path;
path = openFileDialog1.FileName;
StringBuilder str = new StringBuilder();
// Read the file and display it line by line.
System.IO.StreamReader file = new System.IO.StreamReader(path);
using (StreamReader sr = new StreamReader(path))
{
// Read the stream to a string, and write the string to the console.
line = sr.ReadToEnd();
while ((line = file.ReadLine()) != null)
{
if (line.Contains("Computation Time for part A Analysis ="))
{
txt_t_a.Text = Regex.Replace(line, #"[^0-9.]+", "");
}
file.Close();
}
}
}
}
}
}
my code
an example of the log file folders
You're closing your reader while you're trying to read it, resulting in an error. The relevant code is below. Move the close and it should stop giving you that error.
using (StreamReader sr = new StreamReader(path))
{
// Read the stream to a string, and write the string to the console.
line = sr.ReadToEnd();
while ((line = file.ReadLine()) != null)
{
if (line.Contains("Computation Time for part A Analysis ="))
{
txt_t_a.Text = Regex.Replace(line, #"[^0-9.]+", "");
}
// Remove this line.
// file.Close();
}
// Put it here
file.Close()
}
// Or here
Delete this line:
System.IO.StreamReader file = new System.IO.StreamReader(path);
And Update:
using (StreamReader sr = new StreamReader(path))
{
// Read the stream to a string, and write the string to the console.
line = sr.ReadToEnd();
while ((line = sr.ReadLine()) != null)
{
if (line.Contains("Computation Time for part A Analysis ="))
{
txt_t_a.Text = Regex.Replace(line, #"[^0-9.]+", "");
}
sr.Close();
}
}

c# how to end streamreader

I am doing a project Windows form for assignment in Uni, I want to search an already created text file to match a first name and last name then write some additional information if the name and last name exist. I have the code constructed and showing no errors, however when I run and attempt to add information I am being provided with an error which essentially says the next process (Streamreader writer can not access the file as it is already in use by another process) I assume this process is streamreader, I have tried to code it to stop reading to no avail. I am in my first 3 months learning coding and would appreciate some assistance if possible, I have put a snippet of my code below.
//check if there is a file with that name
if (File.Exists(sFile))
{
using (StreamReader sr = new StreamReader(sFile))
{
//while there is more data to read
while (sr.Peek() != -1)
{
//read first name and last name
sFirstName = sr.ReadLine();
sLastName = sr.ReadLine();
}
{
//does this name match?
if (sFirstName + sLastName == txtSearchName.Text)
sr.Close();
}
//Process write to file
using (StreamWriter sw = new StreamWriter(sFile, true))
{
sw.WriteLine("First Name:" + sFirstName);
sw.WriteLine("Last Name:" + sLastName);
sw.WriteLine("Gender:" + sGender);
}
You are using your writer inside the reader, using the same file.
A using disposes the object inside it, after the closing curly braces.
using(StreamReader reader = new StreamReader("foo")){
//... some stuff
using(Streamwriter writer = new StreamWriter("foo")){
}
}
Do it like so :
using(StreamReader reader = new StreamReader("foo")){
//... some stuff
}
using(Streamwriter writer = new StreamWriter("foo")){
}
As per my comment regarding the using statement.
Rearrange to the below. I've tested locally and it seems to work.
using (StreamReader sr = new StreamReader(sfile))
{
//while there is more data to read
while (sr.Peek() != -1)
{
//read first name and last name
sFirstName = sr.ReadLine();
sLastName = sr.ReadLine();
//does this name match?
if (sFirstName + sLastName == txtSearchName.Text)
break;
}
}
using (StreamWriter sw = new StreamWriter(sfile, true))
{
sw.WriteLine("First Name:" + sFirstName);
sw.WriteLine("Last Name:" + sLastName);
sw.WriteLine("Gender:" + sGender);
}
I've replaced the sr.Close with a break statement to exit out. Closing the reader causes the subsequent peek to error as it's closed.
Also, I've noticed that you are not setting gender? unless its set elsewhere.
hope that helps
You can use FileStream. It gives you many options to work with file:
var fileStream = new FileStream("FileName", FileMode.Open,
FileAccess.Write, FileShare.ReadWrite);
var fileStream = new FileStream("fileName", FileMode.Open,
FileAccess.ReadWrite, FileShare.ReadWrite);
I think this is what you want/need. You can't append to a file the way you are trying to do it. Instead you'll want to read your input file, and write a temp file as you are reading through. And, whenever your line matches your requirements, then you can write the line with your modifications.
string inputFile = "C:\\temp\\StreamWriterSample.txt";
string tempFile = "C:\\temp\\StreamWriterSampleTemp.txt";
using (StreamWriter sw = new StreamWriter(tempFile))//get a writer ready
{
using (StreamReader sr = new StreamReader(inputFile))//get a reader ready
{
string currentLine = string.Empty;
while ((currentLine = sr.ReadLine()) != null)
{
if (currentLine.Contains("Clients"))
{
sw.WriteLine(currentLine + " modified");
}
else
{
sw.WriteLine(currentLine);
}
}
}
}
//now lets crush the old file with the new file
File.Copy(tempFile, inputFile, true);

How do I consume a file resource as a string, in Visual Studio?

When I add a txt file as a resource to a project, how can I then consume the contents of that resource as a string?
The closest I've been able to get is by using the Resource Manager, to pull an unmanaged stream. However, this throws a null error:
using (StreamReader sr = new StreamReader(
Properties.Resources.ResourceManager.GetStream(
"TestFile.txt", CultureInfo.CurrentCulture)))
{
Console.WriteLine(sr.ReadToEnd());
}
You could do this too:
var myAss = Assembly.GetExecutingAssembly();
var mytxtFileResource = "Namespace.Project.MyTxtFile.txt";
using (Stream stream = assembly.GetManifestResourceStream(mytxtFileResource))
using (StreamReader reader = new StreamReader(stream))
{
string result = reader.ReadToEnd();
}
You dont need to do it like that for text files
Just write it like this
https://msdn.microsoft.com/en-us/library/aa287548(v=vs.71).aspx
System.IO.StreamWriter file = new System.IO.StreamWriter("c:\\test.txt");
file.WriteLine(lines);
file.Close();
and read it like this:
https://msdn.microsoft.com/en-us/library/aa287535(v=vs.71).aspx
int counter = 0;
string line;
// Read the file and display it line by line.
System.IO.StreamReader file =
new System.IO.StreamReader("c:\\test.txt");
while((line = file.ReadLine()) != null)
{
Console.WriteLine (line);
counter++;
}
file.Close();

How to access a text file in c# that is being used by another process

I have text file which is being been used by modscan to write data into the file. At a particular time I have to read the data and save in database. In offline mode ie; without modscan using it I can read the data and very well save in database. however as it online with modscan it gives exception
Cannot access file as it been used by other process.
My code:
using System.IO;
string path = dt.Rows[i][11].ToString();
string[] lines = System.IO.File.ReadAllLines(#path);
path has "E:\Metertxt\02.txt"
So what changes I need to make in order to read it without interfering with modscan.
I googled and I found this which might work, however I am not sure how to use it
FileShare.ReadWrite
You can use a FileStream to open a file that is already open in another application. Then you'll need a StreamReader if you want to read it line by line. This works, assuming a file encoding of UTF8:
using (var stream = new FileStream(#"c:\tmp\locked.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
using (var reader = new StreamReader(stream, Encoding.UTF8))
{
string line;
while ((line = reader.ReadLine()) != null)
{
// Do something with line, e.g. add to a list or whatever.
Console.WriteLine(line);
}
}
}
Alternative in case you really need a string[]:
var lines = new List<string>();
using (var stream = new FileStream(#"c:\tmp\locked.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
using (var reader = new StreamReader(stream, Encoding.UTF8))
{
string line;
while ((line = reader.ReadLine()) != null)
{
lines.Add(line);
}
}
}
// Now you have a List<string>, which can be converted to a string[] if you really need one.
var stringArray = lines.ToArray();
FileStream fstream = new FileStream("#path", FileMode.Open,FileAccess.Read, FileShare.ReadWrite);
StreamReader sreader = new StreamReader(fstream);
List<string> lines = new List<string>();
string line;
while((line = sreader.ReadeLine()) != null)
lines.Add(line);
//do something with the lines
//if you need all lines at once,
string allLines = sreader.ReadToEnd();

Split large XML file after string found

What I have:
A large XML file # nearly 1 million lines worth of content. Example of content:
<etc35yh3 etc="numbers" etc234="a" etc345="date"><something><some more something></some more something></something></etc123>
<etc123 etc="numbers" etc234="a" etc345="date"><something><some more something></some more something></something></etc123>
<etc15y etc="numbers" etc234="a" etc345="date"><something><some more something></some more something></something></etc123>
^ repeat that by 900k or so lines (content changing of course)
What I need:
Search the XML file for "<etc123". Once found move (write) that line along with all lines below it to a separate XML file.
Would it be advisable to use a method such as File.ReadAllLines for the search portion? What would you all recommend for the writing portion. Line by line is not an option as far as I can tell as it would take much too long.
To quite literaly discard the content above your search string, I would not use File.ReadAllLines, as it would load the entire file into memory. Try File.Open and wrap it in a StreamReader. Loop on StreamReader.ReadLine, then start writing to a new StreamWriter, or do a byte copy on the underlying filestream.
An example of how to do so with StreamWriter/StreamReader alone is listed below.
//load the input file
//open with read and sharing
using (FileStream fsInput = new FileStream("input.txt",
FileMode.Open, FileAccess.Read, FileShare.Read))
{
//use streamreader to search for start
var srInput = new StreamReader(fsInput);
string searchString = "two";
string cSearch = null;
bool found = false;
while ((cSearch = srInput.ReadLine()) != null)
{
if (cSearch.StartsWith(searchString, StringComparison.CurrentCultureIgnoreCase)
{
found = true;
break;
}
}
if (!found)
throw new Exception("Searched string not found.");
//we have the data, write to a new file
using (StreamWriter sw = new StreamWriter(
new FileStream("out.txt", FileMode.OpenOrCreate, //create or overwrite
FileAccess.Write, FileShare.None))) // write only, no sharing
{
//write the line that we found in the search
sw.WriteLine(cSearch);
string cline = null;
while ((cline = srInput.ReadLine()) != null)
sw.WriteLine(cline);
}
}
//both files are closed and complete
You can copy with LINQ2XML
XElement doc=XElement.Load("yourXML.xml");
XDocument newDoc=new XDocument();
foreach(XElement elm in doc.DescendantsAndSelf("etc123"))
{
newDoc.Add(elm);
}
newDoc.Save("yourOutputXML.xml");
You could do one line at a time... Would not use read to end if checking contents of each line.
FileInfo file = new FileInfo("MyHugeXML.xml");
FileInfo outFile = new FileInfo("ResultFile.xml");
using(FileStream write = outFile.Create())
using(StreamReader sr = file.OpenRead())
{
bool foundit = false;
string line;
while((line = sr.ReadLine()) != null)
{
if(foundit)
{
write.WriteLine(line);
}
else if (line.Contains("<etc123"))
{
foundit = true;
}
}
}
Please note, this method may not produce valid XML, given your requirements.

Categories

Resources