In C# why output of this 2 code is different from each other ?
StreamReader test = new StreamReader(#"C:\a.txt");
while (test.ReadLine() != null)
{
Console.WriteLine(test.ReadLine());
}
And this code :
StreamReader test = new StreamReader(#"C:\a.txt");
string line = "";
while ((line = test.ReadLine()) != null)
{
Console.WriteLine(line);
}
Each time you call test.ReadLine() you read one new line, so the first code skippes a half of them.
In your first example, use this code instead:
while(!test.EndOfStream)
{
Console.WriteLine(test.ReadLine());
}
Both the code works same with little magic ,becuase of the reason:
test.ReadLine():
return: The next line from the input stream, or null if the end of the input stream is reached.
// So,Let's say your a.txt contain the following cases:
case 1:"Hello World"
while (test.ReadLine() != null)
{
Console.WriteLine("HI" + test.ReadLine());
}
// since,we have only one line ,so next line is null and finally it reached the EOD.
case 2:"Hello World"
"I am a coder"
while (test.ReadLine() != null)
{
Console.WriteLine("HI" + test.ReadLine());
}
// since,we have two line so ,next line is "I am a coder".
//It returns:Hi I am a coder.
// And in the below code we are reading and assigning to string variable
StreamReader test1 = new StreamReader(#"D:\a.txt");
string line = "";
while ((line = test1.ReadLine()) != null)
{
Console.WriteLine(line);
}
Related
i want to display the third line after searhing the initial line with a keyword from a text :
and i want to sperate all the variable in the third line in textboxs.
the keyword is [Ref 1]
{ // string motcledm = "code:A14";
string line;
string motcletest = SEARCH.Text;
using (System.IO.StreamReader file = new System.IO.StreamReader(#"D:\\TEST.txt"))
{
while ((line = file.ReadLine()) != null)
{
if ((line.Contains(motcletest)))
{
richTextBox1.Text = line.ToString();
}
}
The output i need
As you told, you have extracted the Third Line, Split on ',' to get an array of strings
String thirdLine = "F8,F9,...";
String[] strArray = thirdLine.Split(',');
foreach(string _val in strArray){
//do your stuff
}
string line;
string motcletest = SEARCH.Text;
using (System.IO.StreamReader file = new System.IO.StreamReader(#"D:\\TEST.txt"))
{
while ((line = file.ReadLine()) != null)
{
if ((line.Contains(motcletest)))
{
richTextBox1.Text = line.ToString();
file.ReadLine();//read first line after matching line
file.ReadLine();//read second line after matching line
line = file.ReadLine(); //third line that you are looking for
foreach(var value in line.Split(','))//split by ,
{
//Add the value the controls(textbox)
//if the count is not fixed, you might need to create a control and add it to a panel
}
}
}
I am using this code so far - it writes the file but doesn't remove the line specified.. any help would be nice...
if (textBox1.Text == "")
{
MessageBox.Show("Please select a file");
}
else
{
string line = null;
StringBuilder sb = new StringBuilder();
string lineDelete = "hi";
// Read the file and display it line by line.
using (System.IO.StreamReader file = new System.IO.StreamReader(textBox1.Text)){
using (System.IO.StreamWriter writer = new System.IO.StreamWriter("C:\\test3.txt"))
{
while ((line = file.ReadLine()) != null)
{
if (String.Compare (line, lineDelete) == 0)
continue;
writer.WriteLine(line);
}
MessageBox.Show("Formatting Complete");
// Suspend the screen.
}
}
"It doesn't remove the line specified" is somewhat misleading, isn't it? You are writing lines from file1 to file2, lines which are "hi" will be omitted. So you are ignoring, not deleting those lines. Is that what you want? Also, note that C# is case sensitive and that there also might be special characters which you can't see directly like white-spaces.
So you could use Trim to remove white-spaces from the start and end of the line and you can use String.Equals to compare case-insensitive:
while ((line = file.ReadLine()) != null)
{
line = line.Trim();
if(line.Equals(lineDelete, StringComparison.CurrentCultureIgnoreCase));
continue;
else
writer.WriteLine(line);
}
Im creating a text file and the last line is ""
private void lastRunDate()
{
String lastLine = readLastDate();
String[] date = lastLine.Split('/');
DateTime dt = new DateTime(Int32.Parse(date[2]), Int32.Parse(date[0]), Int32.Parse(date[1]));
DateTime currentDT = DateTime.Now;
argValue = 1;
if ((dt.Month == currentDT.Month) && (argValue == 0))
{
MessageBox.Show("This application has already been run this month");
this.Close();
}
}
private void AddRecordToFile()
{
DateTime now = DateTime.Now;
prepareToEmail();
string path = filepath;
bool dirtyData = true;
// This text is added only once to the file.
if (!File.Exists(path))
{
// Create a file to write to.
using (StreamWriter sw = File.CreateText(path))
{
sw.Write(now.ToShortDateString());
}
dirtyData = false;
}
if (dirtyData)
{
// This text is always added, making the file longer over time
// if it is not deleted.
using (StreamWriter sw = File.AppendText(path))
{
sw.Write(now.ToShortDateString());
}
}
}
private String readLastDate()
{
using (StreamReader sr = new StreamReader(filepath))
{
// Initialize to null so we are not stuck in loop forever in case there is nothing in the file to read
String line = null;
do
{
line = sr.ReadLine();
// Is this the end of the file?
if (line == null)
{
// Yes, so bail out of loop
return "01/01/1900"; // I had to put something
}
// Is the line empty?
if (line == String.Empty)
{
// Yes, so skip it
continue;
}
// Here you process the non-empty line
return line;
} while (true);
}
}
is what I am using to create the file (or append it)
now is a DateTime object
I used your (Karl) code to create a method called "readLastDate()"
I get the 1st date instead.
I'm probably being way to pragmatic and simple, but skip all the stream stuff and use File class directly like this...
string newLine = "";
if (!isFirstLine)
newLine = Environment.NewLine;
File.AppendAllText(
filePath,
string.Format("{0}{1}", newLine, DateTime.Now.ToString()));
You could use a sw.Write and PRE-pend a linefeed. Unfortunately that will give you an empty line at the start of the file.
Have you tried using the command .Trimend ('\n')?
http://msdn.microsoft.com/en-us/library/system.string.trimend.aspx
Do this:
sw.Write(now.ToShortDateString());
Here is the MSDN documentation for StreamWriter.WriteLine.
Here is the MSDN documentation for StreamWriter.Write.
UPDATE:
Keep using the WriteLine, but change the way you read your values in from the file:
using (StreamReader sr = new StreamReader(path))
{
// Initialize to null so we are not stuck in loop forever in case there is nothing in the file to read
String line = null;
do
{
line = sr.ReadLine();
// Is this the end of the file?
if (line == null)
{
// Yes, so bail out of loop
return;
}
// Is the line empty?
if (line == String.Empty)
{
// Yes, so skip it
continue;
}
// Here you process the non-empty line
} while (true);
}
Adding a record should be a simple matter of calling File.AppendAllText, as pointed out in another answer. Although I would recommend:
File.AppendAllText(filePath, DateTime.Now.ToString() + Environment.NewLine);
To read the last date from the file is also very easy:
string lastGoodLine = "01/01/1900";
using (StringReader sr = new StringReader(filePath))
{
while (!sr.EndOfStream)
{
string line = sr.ReadLine();
if (!string.IsNullOrEmpty(line))
lastGoodLine = line;
}
}
return lastGoodLine;
I have an application that reads information from a text file and then categorizes them and puts them onto a Database. For one category, I need to check the line that comes right after the current line and look for a certain keyword?
How do i get to read this line? This should happen when the streamreader has the current line already open....
I'm using c# on VS2010.
Edit:
All of the code below is in a while (!sReader.EndOfStream) loop
string line = sReader.ReadLine(); //Note: this is used way above and lots of things are done before we come to this loop
for (int i = 0; i < filter_length; i++)
{
if (searchpattern_queries[i].IsMatch(line) == true)
{
logmessagtype = selected_queries[i];
//*Here i need to add a if condition to check if the type is "RESTARTS" and i need to get the next line to do more classification. I need to get that line only to classify the current one. So, I'd want it to be open independently *
hit = 1;
if (logmessagtype == "AL-UNDEF")
{
string alid = AlarmID_Search(line);
string query = "SELECT Severity from Alarms WHERE ALID like '" +alid +"'";
OleDbCommand cmdo = new OleDbCommand(query, conn);
OleDbDataReader reader;
reader = cmdo.ExecuteReader();
while (reader.Read())
{
if (reader.GetString(0).ToString() == null)
{ }
else
{
string severity = reader.GetString(0).ToString();
if (severity == "1")
//Keeps going on.....
Also, the .log files that are opened might go upto 50 Mb types... ! Which is why i dont really prefer reading all lines and keeping track!
Here is an idiom to process the current line you while having the next line already available:
public void ProcessFile(string filename)
{
string line = null;
string nextLine = null;
using (StreamReader reader = new StreamReader(filename))
{
line = reader.ReadLine();
nextLine = reader.ReadLine();
while (line != null)
{
// Process line (possibly using nextLine).
line = nextLine;
nextLine = reader.ReadLine();
}
}
}
This is basically a queue with a maximum of two items in it, or "one line read-ahead".
Edit: Simplified.
Simply use
string[] lines = File.ReadAllLines(filename);
and process the file with a for (int i = 0; i < lines.Length; i ++) loop.
For a big file, simply cache the 'previous line' or do an out-of-band ReadLine().
Can you not just call reader.ReadLine() again? Or is the problem that you then need to use the line in the next iteration of the loop?
If it's a reasonably small file, have you considered reading the whole file using File.ReadAllLines()? That would probably make it simpler, although obviously a little less clean in other ways, and more memory-hungry for large files.
EDIT: Here's some code as an alternative:
using (TextReader reader = File.OpenText(filename))
{
string line = null; // Need to read to start with
while (true)
{
if (line == null)
{
line = reader.ReadLine();
// Check for end of file...
if (line == null)
{
break;
}
}
if (line.Contains("Magic category"))
{
string lastLine = line;
line = reader.ReadLine(); // Won't read again next iteration
}
else
{
// Process line as normal...
line = null; // Need to read again next time
}
}
}
You could save the position of the stream then after calling ReadLine, seek back to that position. However this is pretty inefficient.
I would store the result of ReadLine into a "buffer", and when possible use that buffer as a source. When it is empty, use ReadLine.
I am not really a file IO expert... but why not do something like this:
Before you start reading lines declare two variables.
string currentLine = string.Empty
string previousLine = string.Empty
Then while you are reading...
previousLine = currentLine;
currentLine = reader.ReadLine();
I need to delete an exact line from a text file but I cannot for the life of me workout how to go about doing this.
Any suggestions or examples would be greatly appreciated?
Related Questions
Efficient way to delete a line from a text file (C#)
If the line you want to delete is based on the content of the line:
string line = null;
string line_to_delete = "the line i want to delete";
using (StreamReader reader = new StreamReader("C:\\input")) {
using (StreamWriter writer = new StreamWriter("C:\\output")) {
while ((line = reader.ReadLine()) != null) {
if (String.Compare(line, line_to_delete) == 0)
continue;
writer.WriteLine(line);
}
}
}
Or if it is based on line number:
string line = null;
int line_number = 0;
int line_to_delete = 12;
using (StreamReader reader = new StreamReader("C:\\input")) {
using (StreamWriter writer = new StreamWriter("C:\\output")) {
while ((line = reader.ReadLine()) != null) {
line_number++;
if (line_number == line_to_delete)
continue;
writer.WriteLine(line);
}
}
}
The best way to do this is to open the file in text mode, read each line with ReadLine(), and then write it to a new file with WriteLine(), skipping the one line you want to delete.
There is no generic delete-a-line-from-file function, as far as I know.
One way to do it if the file is not very big is to load all the lines into an array:
string[] lines = File.ReadAllLines("filename.txt");
string[] newLines = RemoveUnnecessaryLine(lines);
File.WriteAllLines("filename.txt", newLines);
Hope this simple and short code will help.
List linesList = File.ReadAllLines("myFile.txt").ToList();
linesList.RemoveAt(0);
File.WriteAllLines("myFile.txt"), linesList.ToArray());
OR use this
public void DeleteLinesFromFile(string strLineToDelete)
{
string strFilePath = "Provide the path of the text file";
string strSearchText = strLineToDelete;
string strOldText;
string n = "";
StreamReader sr = File.OpenText(strFilePath);
while ((strOldText = sr.ReadLine()) != null)
{
if (!strOldText.Contains(strSearchText))
{
n += strOldText + Environment.NewLine;
}
}
sr.Close();
File.WriteAllText(strFilePath, n);
}
You can actually use C# generics for this to make it real easy:
var file = new List<string>(System.IO.File.ReadAllLines("C:\\path"));
file.RemoveAt(12);
File.WriteAllLines("C:\\path", file.ToArray());
This can be done in three steps:
// 1. Read the content of the file
string[] readText = File.ReadAllLines(path);
// 2. Empty the file
File.WriteAllText(path, String.Empty);
// 3. Fill up again, but without the deleted line
using (StreamWriter writer = new StreamWriter(path))
{
foreach (string s in readText)
{
if (!s.Equals(lineToBeRemoved))
{
writer.WriteLine(s);
}
}
}
Read and remember each line
Identify the one you want to get rid
of
Forget that one
Write the rest back over the top of
the file
I cared about the file's original end line characters ("\n" or "\r\n") and wanted to maintain them in the output file (not overwrite them with what ever the current environment's char(s) are like the other answers appear to do). So I wrote my own method to read a line without removing the end line chars then used it in my DeleteLines method (I wanted the option to delete multiple lines, hence the use of a collection of line numbers to delete).
DeleteLines was implemented as a FileInfo extension and ReadLineKeepNewLineChars a StreamReader extension (but obviously you don't have to keep it that way).
public static class FileInfoExtensions
{
public static FileInfo DeleteLines(this FileInfo source, ICollection<int> lineNumbers, string targetFilePath)
{
var lineCount = 1;
using (var streamReader = new StreamReader(source.FullName))
{
using (var streamWriter = new StreamWriter(targetFilePath))
{
string line;
while ((line = streamReader.ReadLineKeepNewLineChars()) != null)
{
if (!lineNumbers.Contains(lineCount))
{
streamWriter.Write(line);
}
lineCount++;
}
}
}
return new FileInfo(targetFilePath);
}
}
public static class StreamReaderExtensions
{
private const char EndOfFile = '\uffff';
/// <summary>
/// Reads a line, similar to ReadLine method, but keeps any
/// new line characters (e.g. "\r\n" or "\n").
/// </summary>
public static string ReadLineKeepNewLineChars(this StreamReader source)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
char ch = (char)source.Read();
if (ch == EndOfFile)
return null;
var sb = new StringBuilder();
while (ch != EndOfFile)
{
sb.Append(ch);
if (ch == '\n')
break;
ch = (char)source.Read();
}
return sb.ToString();
}
}
Are you on a Unix operating system?
You can do this with the "sed" stream editor. Read the man page for "sed"
What?
Use file open, seek position then stream erase line using null.
Gotch it? Simple,stream,no array that eat memory,fast.
This work on vb.. Example search line culture=id where culture are namevalue and id are value and we want to change it to culture=en
Fileopen(1, "text.ini")
dim line as string
dim currentpos as long
while true
line = lineinput(1)
dim namevalue() as string = split(line, "=")
if namevalue(0) = "line name value that i want to edit" then
currentpos = seek(1)
fileclose()
dim fs as filestream("test.ini", filemode.open)
dim sw as streamwriter(fs)
fs.seek(currentpos, seekorigin.begin)
sw.write(null)
sw.write(namevalue + "=" + newvalue)
sw.close()
fs.close()
exit while
end if
msgbox("org ternate jua bisa, no line found")
end while
that's all..use #d