Joining two files in C#, split options - c#

I am currently trying to work on files, joining multiple of them and having problem because the last work from file 1 is linked with first word from file 2. For example:
File 1:John has got new haircut
File 2: Mike has got new haircut
and it prints me "haircutMike".
The code I am using to split words:
input.Split(' ').ToList().ForEach(n =>{});
I am also making one big file from multiple ones like so:
string[] files = { "f1.txt", "f2.txt" };
FileStream outputFile = new FileStream("new.txt", FileMode.Create);
using (StreamWriter ws = new StreamWriter(outputFile))
{
foreach (string file in files)
{
ws.Write(System.IO.File.ReadAllText(file) + " ");
}
}
#EDIT
Changed some code, of course I meant to use stream not binary,also I am using split because I want to count the number of each word in files so I have to split spaces, dots etc.
You mentioned to use + " " option, although it works, but it added me 1 letter to the total count.

EDIT: for multiple input files:
string[] files = { "f1.txt", "f2.txt" };
var allLines = files.SelectMany(i => System.IO.File.ReadAllLines(i));
System.IO.File.WriteAllLines("new.txt", allLines.ToArray());

Related

How to randomly generate a word in a CSV file [duplicate]

This question already has answers here:
How do I generate a random integer in C#?
(31 answers)
Closed 3 years ago.
I have a csv file in my file explorer windows 10. This file contains a list of rows e.g.:
John, 5656, Phil, Simon,,Jude, Helen, Andy
Conor, 5656, Phil, Simon,,Jude, Helen, Andy
I am an automated tester using C#, selenium and visual studio. In the application I am testing, there is an upload button which imports the csv file.
How do I randomly change the second number automatically so the update would be 1234 on the first row, 4444 on the second row(just append randomly). I think I would need a random generator for this.
Any advice or snippets of code would be appreciated.
Do you want to append the CSV file before its uploaded to the program or after? Either way it would look something like this:
public File updateFile(string filePath){
List<string> modifiedNames;
using (StreamReader sr = File.OpenText(path))
{
string s;
while ((s = sr.ReadLine()) != null)
{
s = s + randomlyGeneratedSuffix();
newEntries.add(s)
}
}
using (StreamWriter sw = new StreamWriter("names.txt")) {
foreach (string s in modifiedNames) {
sw.WriteLine(s);
}
}
// return new file?
}
Reading the file before uploading, changing the numbers on the second position in csv and writing it again to disk should work. Here is a very simple approach, to help you get started:
var fileLines = File.ReadAllLines("file.csv");
var randomGenerator = new Random();
var newFileLines = new List<string>();
foreach (var fileLine in fileLines)
{
var lineValues = fileLine.Split(',');
lineValues[1] = randomGenerator.Next(1000, int.MaxValue).ToString();
var newLine = string.Join(",", lineValues);
newFileLines.Add(newLine);
}
File.WriteAllLines("file.csv", newFileLines);
Instead of updating an existing CSV file for testing I would generate a new one from code.
There are a lot of code examples online how to create a CSV file in C#, for example: Writing data into CSV file in C#
For random numbers you can use the random class: https://learn.microsoft.com/en-us/dotnet/api/system.random?view=netframework-4.7.2

Rename a set of files using the information present in a txt file

I have some doubts about how to approach a problem of renaming a set of pdf files according to the information present in a txt file. For example, imagine that in the txt file the following data are separated by tabs:
"2222" "_" "Z1" "001" "E" "07"
"2222" "_" "C1" "002" "F" "08"
"2222" "_" "D1" "003" "F" "09"
The number of pdf files in a given folder always corresponds to the number of lines in the txt file.
How to change the names of * pdf files using this information in the txt file that is in the same folder where the pdfs are, withou the quotes?
You could use the following code as a starting point, and make it more complex if necessary. I have comments to help follow along. Remember to include "using System.IO;".
class Program
{
static void Main(string[] args)
{
string directory = #"E:\TempFiles\"; //Name of directory containing text files and PDFs
//Get text file with names for PDFs...
string filenames = File.ReadAllText(directory + "names.txt");
//Removed quotes, but can be done differently, and split by space, which may not work for all your cases, but gets going in the right direction...
string[] listFilenames = filenames.Replace("\"", "").Split('\t');
int i = 0; //Used to access list of filnames...
foreach (string file in Directory.GetFiles(directory))
{
//Skip text file...
if (!file.EndsWith(".txt"))
{
//Rename file...
File.Move(file, directory + listFilenames[i] + ".pdf");
i++;
}
}
}
}

Writing huge amount of physical file names into text files c#

I have developed a small tool that will be used to display data discrepancy in c#, what I do is explained point wise below,
fetch data from database and write list of file names in text file based on date criteria -output 1
take dir of path 1 and write into text file- output2
take dir of path2, path3 and path4 similarly and write into text files separately for each path- output 3/4/5
compare option: compare output1 and 2 and write down the difference in text file, this difference is then compared to output3 and again the difference is written in another file, and so on...
my issue is : my last path has more than 2.5 million records of files, whenever I try writing it in text file it hangs the application and it never provides output, I did try filtering it with date criteria but even for a single day where records could be around 30 thousands it hangs
I have searched many sites but did not get solution that I can understand or able to implement it. Below is my attempted code.
if (!txtpath3.Text.Equals(String.Empty) && System.IO.Directory.GetFiles(txtpath3.Text).Length > 0)
{
var directory = txtpath3.Text;
var from_dt = this.dtpickerstart.Value;
var end_dt = this.dtpickerend.Value;
DateTime from_date = from_dt;
DateTime to_date = end_dt;
DirectoryInfo di = new DirectoryInfo(directory);
FileSystemInfo[] files = di.GetFileSystemInfos();
var op = di.GetFiles()
.Where(file => file.LastWriteTime >= from_date && file.LastWriteTime <= to_date);
foreach (string file in System.IO.Directory.GetFiles(txtpath3.Text, "*.*"))
{
TextWriter tw = new StreamWriter(dirfile3, true);
tw.WriteLine("" + file + "");
tw.Close();
}
}
else
{
}
Your foreach-loop opens and closes the file for all lines. You should open and close the file outside of the loop.
using(var tw = new StreamWriter(dirfile3, true))
{
foreach (string file in System.IO.Directory.GetFiles(txtpath3.Text, "*.*"))
{
tw.WriteLine("" + file + "");
}
}
Even easier would be using the already existing functions to do this:
File.AppendAllLines(dirfile3, System.IO.Directory.GetFiles(txtpath3.Text, "*.*"));
As 2.5 million filesnames are a lot to keep in RAM at the same time, you might be better off with just enumerating them:
File.AppendAllLines(dirfile3, System.IO.Directory.EnumerateFiles(txtpath3.Text, "*.*"));
I think that the problem is in the foreach
foreach (string file in System.IO.Directory.GetFiles(txtpath3.Text, "*.*"))
{
TextWriter tw = new StreamWriter(dirfile3, true);
tw.WriteLine("" + file + "");
tw.Close();
}
For each and every one of the many, many files, you are opening a file, appending a line, and closing the file, only to open it again, write another line, etc, etc...
You should just prepare everything in a string first, and then just insert all the text in one go, something like:
StringBuilder sb = new StringBuilder();
foreach (string file in System.IO.Directory.GetFiles(txtpath3.Text, "*.*"))
{
sb.AppendLine(file);
}
File.WriteAllText(dirfile3, sb.ToString());

read only given last x lines in txt file [duplicate]

This question already has answers here:
Get last 10 lines of very large text file > 10GB
(21 answers)
Closed 9 years ago.
Currently I'm reading file content using File.ReadAllText(), but now I need to read last x lines in my txt file. How can I do that?
content of myfile.txt
line1content
line2content
line3content
line4content
string contentOfLastTwoLines = ...
What about this
List <string> text = File.ReadLines("file.txt").Reverse().Take(2).ToList()
Use Queue<string> to store last X lines and replace the first one with currently read:
int x = 4; // number of lines you want to get
var buffor = new Queue<string>(x);
var file = new StreamReader("Input.txt");
while (!file.EndOfStream)
{
string line = file.ReadLine();
if (buffor.Count >= x)
buffor.Dequeue();
buffor.Enqueue(line);
}
string[] lastLines = buffor.ToArray();
string contentOfLastLines = String.Join(Environment.NewLine, lastLines);
You can use ReadLines to avoid reading the entire file into memory, like this:
const int neededLines = 5;
var lines = new List<String>();
foreach (var s in File.ReadLines("c:\\myfile.txt")) {
lines.Add(s);
if (lines.Count > neededLines) {
lines.RemoveAt(0);
}
}
Once the for loop is finished, the lines list contains up to the last neededLines of text from the file. Of course if the file does not contain as many lines as required, fewer lines will be placed in the lines list.
Read the lines into an array, then extract the last two:
string[] lines = File.ReadAllLines();
string last2 = lines[lines.Count-2] + Environment.NewLine + lines[lines.Count-1];
Assuming your file is reasonably small, it's easier to just read the whole thing and throw away what you don't need.
Since reading a file is done linearly, usually line-by-line. Simply read line-by-line and remember last two lines (you can use queue or something if you want... or just two string variables). When you get to EOF, you'll have your last two lines.
You want to read the file backwards using ReverseLineReader:
How to read a text file reversely with iterator in C#
Then run .Take(2) on it.
var lines = new ReverseLineReader(filename);
var last = lines.Take(2);
OR
Use a System.IO.StreamReader.
string line1, line2;
using(StreamReader reader = new StreamReader("myFile.txt")) {
line1 = reader.ReadLine();
line2 = reader.ReadLine();
}

Streamreader isn't returning the correct values from my text file, can't figure out how to properly read my text files C#

I'm running three counters, one to return the total amount of chars, one to return the number of '|' chars in my .txt file (total). And one to read how many separate lines are in my text file. I'm assuming my counters are wrong, I'm not sure. In my text file there are some extra '|' chars, but that is a bug I need to fix later...
The Message Boxes show
"Lines = 8"
"Entries = 8"
"Total Chars = 0"
Not sure if it helps but the .txt file is compiled using a streamwriter, and I have a datagridview saved to a string to create the output. Everything seems okay with those functions.
Here is a copy of the text file I'm reading
Matthew|Walker|MXW320|114282353|True|True|True
Audrey|Walker|AXW420|114282354|True|True|True
John|Doe|JXD020|111222333|True|True|False
||||||
And here is the code.
private void btnLoadList_Click(object sender, EventArgs e)
{
var loadDialog = new OpenFileDialog
{
InitialDirectory = Convert.ToString(Environment.SpecialFolder.MyDocuments),
Filter = "Text (*.txt)|*.txt",
FilterIndex = 1
};
if (loadDialog.ShowDialog() != DialogResult.OK) return;
using (new StreamReader(loadDialog.FileName))
{
var lines = File.ReadAllLines(loadDialog.FileName);//Array of all the lines in the text file
foreach (var assocStringer in lines)//For each assocStringer in lines (Runs 1 cycle for each line in the text file loaded)
{
var entries = assocStringer.Split('|'); // split the line into pieces (e.g. an array of "Matthew", "Walker", etc.)
var obj = (Associate) _bindingSource.AddNew();
if (obj == null) continue;
obj.FirstName = entries[0];
obj.LastName = entries[1];
obj.AssocId = entries[2];
obj.AssocRfid = entries[3];
obj.CanDoDiverts = entries[4];
obj.CanDoMhe = entries[5];
obj.CanDoLoading = entries[6];
}
}
}
Hope you guys find the bug(s) here. Sorry if the formatting is sloppy I'm self-taught, no classes. Any extra advice is welcomed, be as honest and harsh as need be, no feelings will be hurt.
In summary
Why is this program not reading the correct values from the text file I'm using?
Not totally sure I get exactly what you're trying to do, so correct me if I'm off, but if you're just trying to get the line count, pipe (|) count and character count for the file the following should get you that.
var lines = File.ReadAllLines(load_dialog.FileName);
int lineCount = lines.Count();
int totalChars = 0;
int totalPipes = 0; // number of "|" chars
foreach (var s in lines)
{
var entries = s.Split('|'); // split the line into pieces (e.g. an array of "Matthew", "Walker", etc.)
totalChars += s.Length; // add the number of chars on this line to the total
totalPipes = totalPipes + entries.Count() - 1; // there is always one more entry than pipes
}
All the Split() is doing is breaking the full line into an array of the individual fields in the string. Since you only seem to care about the number of pipes and not the fields, I'm not doing much with it other than determining the number of pipes by taking the number of fields and subtracting one (since you don't have a trailing pipe on each line).

Categories