C# for loop to write line by line - c#

I am trying to write one line of text 75 times and increase the number by 1 till it hits the 75 condition. Starting at 2 for a reason.
Here's the code
class WriteTextFile
{
static void Main()
{
string path = "C:\\Users\\Writefile\\test.txt";
string line;
int i = 2;
while (i <= 75 )
{
line = "Error_Flag = 'FOR_IMPORT' and location_type = 'Home' and batch_num = " + i + "\n";
System.IO.File.WriteAllText(#path, line);
i++;
}
}
}
With this, it just writes one line with 75 at the end. I want it to write all 74 lines with the same thing, only the number goes up every time. Thanks.

System.IO.File.WriteAllText will overwrite the contents of the file each time.
What you probably should do is use a StreamWriter:
using (var sw = new System.IO.StreamWriter(path))
{
for (var i = 2; i <= 75; i++)
{
sw.WriteLine("Error_Flag = 'FOR_IMPORT' and location_type = 'Home' and batch_num = {0}", i);
}
}
This will automatically create the file, write all the lines, and then close it for you when it's done.

Don't use File.WriteAllText because this generates a new file every time.
Instead try something like this:
using (var writer = new StreamWriter("filename.txt"))
{
for(int x = 2; x <= 75; x++)
{
writer.WriteLine("Error_Flag = 'FOR_IMPORT' and location_type = 'Home' and batch_num = " + x);
}
}

You're overwriting the file on each new write operation. Consider appending to it.

Related

Remove a line from a System.IO.StringWriter

I have a piece of code that is adding lines of text to a System.IO.StringWriter.
When it gets above a certain size, I want to purge lines from the beginning.
How do I do that? Can it be done?
System.IO.StringWriter log = new System.IO.StringWriter();
log.WriteLine("some text");
log.WriteLine("more text");
// some how remove the first line ????
A possible solution to your problem involves the use of the Queue class. You can add your text to this object and when it reaches a certain size you start trimming away the initial data
For example
void Main()
{
int maxQueueSize = 50;
var lines = File.ReadAllLines(filePath);
Queue<string> q = new Queue<string>(lines);
// Here you should check for files bigger than your limit
....
// Trying to add too many elements
for (int x = 0; x < maxQueueSize * 2; x++)
{
// Remove the first if too many elements
if(q.Count == maxQueueSize)
q.Dequeue();
// as an example, add the x converted to string
q.Enqueue(x.ToString());
}
// Back to disk
File.WriteAllLines(filePath, q.ToList());
}
System.IO.StringWriter log = new System.IO.StringWriter();
log.WriteLine("some text");
log.WriteLine("more text");
// some how remove the first line ????
var sb = log.GetStringBuilder(); //get the underlying StringBuilder
var newLinePosition = sb.ToString().IndexOf(Environment.NewLine); //find the first newline
sb.Remove(0, newLinePosition + Environment.NewLine.Length); //remove from start to the newline... including the newline itself
You can, instead of writing to a stream write to a different data structure (such as a list) and use an iterator to loop over your lines and replace them if you hit a certain threshold.
List<string> log = new List<string>();
int idx = 0;
//...
if (idx > 10) // your max amount of messages
{
idx = 0;
}
if (log.Count < idx)
{
log.Add("more Text");
}
else
{
log[idx] = "more Text";
}
of course you should wrap this in a class for logging.

How to stop from.show() displaying multiple forms

I have an application that reads though a group of documents and displays a new form is a certain value is found. MY issue here is that all though the application is reading the files and is displaying how I would like I am getting multiple forms drawn as the application is just reading thought the directory.
What I am unable to find is how to stop this from moving onto the next file before the first form has been closed. I tried .ShowDialog() but this does not work with what I am trying.
My current code is as follow's:
foreach (FileInfo fi in rgFiles)
{
current++;
fileProcessBar.Value = current / count * 60 + 40;
string[] alllines = File.ReadAllLines(fi.FullName);
CreateForm CF = new CreateForm(fi.FullName);
for (int i = 0; i < alllines.Length; i++)
{
if (alllines[i].Contains("$"))
{
// prompt
int dollarIndex = alllines[i].IndexOf("--");
Regex regex = new Regex(#"(--.{1,100})");
var chars = regex.Match(alllines[i]).ToString();
string PromptText = chars.Replace("-", "");
CF.AddToCanvas(PromptText);
CF.Show();
}
}
}
I thought maybe adding another foreach loop but would not account for form2 close
So it seems you merely want to open one form per-file and block until that form is closed. Then in that case try
foreach (FileInfo fi in rgFiles)
{
current++;
fileProcessBar.Value = current / count * 60 + 40;
string[] alllines = File.ReadAllLines(fi.FullName);
// Ensure that resources are released.
using (CreateForm CF = new CreateForm(fi.FullName))
{
for (int i = 0; i < alllines.Length; i++)
{
if (alllines[i].Contains("$"))
{
int dollarIndex = alllines[i].IndexOf("--");
Regex regex = new Regex(#"(--.{1,100})");
var chars = regex.Match(alllines[i]).ToString();
string PromptText = chars.Replace("-", "");
CF.AddToCanvas(PromptText);
CF.ShowDialog(); // This should block until closed.
}
}
}
}
I hope this helps.

Prompt as me count all the rows from a file ? I understand that in a cycle but a verification clause should be?

1 option is already there, but need another
using (StreamReader str = new StreamReader(#"d:\alfa.txt", Encoding.Default))
{
for (int i = 0; i <= 4; i++)
{
Line = str.ReadLine();
}
}
You can use File.ReadLines method and simple linq
int count = File.ReadLines(#"d:\alfa.txt").Count();
Better I think to use file.Simple ReadLines method and linq in
int count = File.ReadLines(#"d:\alfa.txt").Count();
Until you reach the end of stream.
int count = 0;
using (StreamReader str = new StreamReader(#"d:\alfa.txt", Encoding.Default))
{
while(!str.EndOfStream)
{
Line = str.ReadLine();
count++:
}
}
If the string is the sentence :
if(mas[i] == '.') count++;
You must copy the file from all the characters in the mas and then check the condition .

c# How to run a application faster

I am creating a word list of possible uppercase letters to prove how insecure 8 digit passwords are this code will write aaaaaaaa to aaaaaaab to aaaaaaac etc. until zzzzzzzz using this code:
class Program
{
static string path;
static int file = 0;
static void Main(string[] args)
{
new_file();
var alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456789+-*_!$£^=<>§°ÖÄÜöäü.;:,?{}[]";
var q = alphabet.Select(x => x.ToString());
int size = 3;
int counter = 0;
for (int i = 0; i < size - 1; i++)
{
q = q.SelectMany(x => alphabet, (x, y) => x + y);
}
foreach (var item in q)
{
if (counter >= 20000000)
{
new_file();
counter = 0;
}
if (File.Exists(path))
{
using (StreamWriter sw = File.AppendText(path))
{
sw.WriteLine(item);
Console.WriteLine(item);
/*if (!(Regex.IsMatch(item, #"(.)\1")))
{
sw.WriteLine(item);
counter++;
}
else
{
Console.WriteLine(item);
}*/
}
}
else
{
new_file();
}
}
}
static void new_file()
{
path = #"C:\" + "list" + file + ".txt";
if (!File.Exists(path))
{
using (StreamWriter sw = File.CreateText(path))
{
}
}
file++;
}
}
The Code is working fine but it takes Weeks to run it. Does anyone know a way to speed it up or do I have to wait? If anyone has a idea please tell me.
Performance:
size 3: 0.02s
size 4: 1.61s
size 5: 144.76s
Hints:
removed LINQ for combination generation
removed Console.WriteLine for each password
removed StreamWriter
large buffer (128k) for file writing
const string alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456789+-*_!$£^=<>§°ÖÄÜöäü.;:,?{}[]";
var byteAlphabet = alphabet.Select(ch => (byte)ch).ToArray();
var alphabetLength = alphabet.Length;
var newLine = new[] { (byte)'\r', (byte)'\n' };
const int size = 4;
var number = new byte[size];
var password = Enumerable.Range(0, size).Select(i => byteAlphabet[0]).Concat(newLine).ToArray();
var watcher = new System.Diagnostics.Stopwatch();
watcher.Start();
var isRunning = true;
for (var counter = 0; isRunning; counter++)
{
Console.Write("{0}: ", counter);
Console.Write(password.Select(b => (char)b).ToArray());
using (var file = System.IO.File.Create(string.Format(#"list.{0:D5}.txt", counter), 2 << 16))
{
for (var i = 0; i < 2000000; ++i)
{
file.Write(password, 0, password.Length);
var j = size - 1;
for (; j >= 0; j--)
{
if (number[j] < alphabetLength - 1)
{
password[j] = byteAlphabet[++number[j]];
break;
}
else
{
number[j] = 0;
password[j] = byteAlphabet[0];
}
}
if (j < 0)
{
isRunning = false;
break;
}
}
}
}
watcher.Stop();
Console.WriteLine(watcher.Elapsed);
}
Try the following modified code. In LINQPad it runs in < 1 second. With your original code I gave up after 40 seconds. It removes the overhead of opening and closing the file for every WriteLine operation. You'll need to test and ensure it gives the same results because I'm not willing to run your original code for 24 hours to ensure the output is the same.
class Program
{
static string path;
static int file = 0;
static void Main(string[] args)
{
new_file();
var alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456789+-*_!$£^=<>§°ÖÄÜöäü.;:,?{}[]";
var q = alphabet.Select(x => x.ToString());
int size = 3;
int counter = 0;
for (int i = 0; i < size - 1; i++)
{
q = q.SelectMany(x => alphabet, (x, y) => x + y);
}
StreamWriter sw = File.AppendText(path);
try
{
foreach (var item in q)
{
if (counter >= 20000000)
{
sw.Dispose();
new_file();
counter = 0;
}
sw.WriteLine(item);
Console.WriteLine(item);
}
}
finally
{
if(sw != null)
{
sw.Dispose();
}
}
}
static void new_file()
{
path = #"C:\temp\list" + file + ".txt";
if (!File.Exists(path))
{
using (StreamWriter sw = File.CreateText(path))
{
}
}
file++;
}
}
your alphabet is missing 0
With that fixed there would be 89 chars in your set. Let's call it 100 for simplicity. The set you are looking for is all the 8 character length strings drawn from that set. There are 100^8 of these, i.e. 10,000,000,000,000,000.
The disk space they will take up depends on how you encode them, lets be generous - assume you use some 8 bit char set that contains the these characters, and you don't put in carriage returns, so one byte per char, so 10,000,000,000,000,000 bytes =~ 10 peta byes?
Do you have 10 petabytes of disk? (10000 TB)?
[EDIT] In response to 'this is not an answer':
The original motivation is to create the list? The shows how large the list would be. Its hard to see what could be DONE with the list if it was actualised, i.e. it would always be quicker to reproduce it than to load it. Surely whatever point could be made by producing the list can also be made by simply knowing it's size, which the above shows how to work it out.
There are LOTS of inefficiencies in you code, but if your questions is 'how can i quickly produce this list and write it to disk' the answer is 'you literally cannot'.
[/EDIT]

WriteLine to .txt for each line in richTextBox

Hello I have this line of code to write every line of richTextBox into my .txt file but at the final the txt file is empty but when debug it reads every line. May I know how this code should be improved to do what I want?
string Path = (#"C:\Users\x\Documents\Visual Studio 2012\Projects\MTest\txtCmdLog.txt");
StreamWriter sw = new StreamWriter(File.Open(Path, System.IO.FileMode.Append));
for (int i = 0; i <= txtCmdLog.Lines.Length; i++)
{
sw.WriteLine(txtCmdLog.Lines[i] + "\n");
}
sw.Close();
Thank you for your time.
Change your loop to:
for (int i = 0; i < txtCmdLog.Lines.Length; i++)
{
sw.WriteLine(txtCmdLog.Lines[i]);
}
Don't use <= in the loop's condition check. You also don't need to append a newline character in the call to WriteLine, since that method already writes a newline.
Points to remember:
1.you need to loop through 0 to lines.Length-1.so remove = in <= condition.
2.for disposing the StreamWriter object use using{} block so that you don't need to call close().
Diposal of StreamWriter object will be taken care by using {} block
string Path = (#"C:\Users\x\Documents\Visual Studio 2012\Projects\MTest\txtCmdLog.txt");
using(StreamWriter sw = new StreamWriter(File.Open(Path, System.IO.FileMode.Append)))
{
for (int i = 0; i < txtCmdLog.Lines.Length; i++)
{
sw.WriteLine(txtCmdLog.Lines[i] + "\n");
}
}
The easy way to do this is:
File.WriteAllLines(filename, arrayOfStrings);

Categories

Resources