I am currently trying to make an .exe in c# that I can drag and drop a .txt file onto to remove lines of text that contain the keywords "CM" and/or "Filling". It must be able to overwrite the existing data so there are no new files created. The filename is different every time except for the extension. The data is tab delimited if that has any bearing. I'm aware that there are similar questions to this but I haven't managed to adapt them to suit my needs. Also, I'm very new to this and I've been trying for about a week with no luck.
if (args.Length == 0)
return; // return if no file was dragged onto exe
string text = File.ReadAllText("*.txt");
text = text.Replace("cm", "");
string path = Path.GetDirectoryName(args[0])
+ Path.DirectorySeparatorChar
+ Path.GetFileNameWithoutExtension(args[0])
+ "_unwrapped" + Path.GetExtension(args[0]);
File.WriteAllText("*.txt", text);
\\attempt 1
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Text.RegularExpressions;
namespace ConsoleApp4
{
class Program
{
static void Main(string[] args)
{
string concrete = "CM";
string line;
using (StreamReader reader = new StreamReader(#"C:\\Users\drocc_000\Desktop\1611AN24T99-041805221704.txt"))
{
using (StreamWriter writer = new StreamWriter(#"C:\\Users\drocc_000\Desktop\1611AN24T99-041805221704NEW.txt"))
{
while ((line = reader.ReadLine()) != null)
{
// if (String.Compare(line, yourName) == 0)
// continue;
writer.WriteLine(line.Replace(concrete, ""));
}
}
}
\\attempt 2
Thanks for your time.
Regards,
Danny
You can create a console application with the code below and then drag and drop your text file into the .exe file without opening it.
class Program
{
static void Main(string[] args)
{
if (args.Length > 0 && File.Exists(args[0]))
{
string path = args[0];
EditFile(new List<string>() { "CM", "Filling" }, path);
}
Console.Read();
}
public static void EditFile(List<string> keyWords, string filename)
{
List<string> lines = new List<string>();
using (StreamReader sr = new StreamReader(filename))
{
while (sr.Peek() >= 0)
{
lines.Add(sr.ReadLine());
}
sr.Close();
}
int removedLinesCount = 0;
bool writeline;
using (StreamWriter sw = new StreamWriter(filename))
{
foreach (var line in lines)
{
writeline = true;
foreach (var str in keyWords)
{
if (line.Contains(str))
{
writeline = false;
removedLinesCount++;
break;
}
}
if (writeline)
sw.WriteLine(line);
}
Console.WriteLine(removedLinesCount + " lines removed from the file " + filename);
sw.Close();
}
}
}
Something like this?
using System;
using System.IO;
using System.Linq;
namespace ConsoleApp1
{
internal static class Program
{
private static void Main(string[] args)
{
try
{
// Get the filename from the applications arguments
string filename = args[0];
// Read in all lines in the file.
var linesInFile = File.ReadLines(filename);
// Filter out the lines we don't need.
var linesToKeep = linesInFile.Where(line => !line.Contains("CM") && !line.Contains("Filling")).ToArray();
// Overwrite the file.
File.WriteAllLines(filename, linesToKeep);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
}
Related
I want to read csv file and save to list or array or anything, but CsvHelper demands to save it as collection of specific type. Problem is my csv has so many columns, that mapping it to custom class will take a few weeks.
How can I just read it without saving as specific type? Accessing specific values with thing like row[1][2] is more than enough for me.
Add it to a datatable
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Data;
namespace ConsoleApplication23
{
class Program
{
const string FILENAME = #"c:\temp\test.csv";
static void Main(string[] args)
{
StreamReader reader = new StreamReader(FILENAME);
string line = "";
DataTable dt = new DataTable();
int rowCount = 0;
while((line = reader.ReadLine()) != null)
{
line = line.Trim();
if (line.Length > 0)
{
string[] splitArray = line.Split(new char[] { ',' });
if (rowCount == 0)
{
foreach (string col in splitArray)
{
dt.Columns.Add(col, typeof(string));
}
}
else
{
dt.Rows.Add(splitArray);
}
}
}
}
}
}
I have a homework assignment to create a C# console program. It should create a text file with 2 phrases:
Hello, World!
Goodbye, Cruel World!
Then I also must create a program to read the 2 phrases from the file.
After two hours this is what I have. It works, but I want to rewrite the program to be more efficient. I am mainly struggling on how to output the file into a .cs file capable of running.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace ConsoleApplication3
{
class Program
{
static void Main(string[] args)
{
//structure.txt contains the program we will enter our values into.
String filePath = "Structure.txt";
WriteToFile(filePath);
}
public static void WriteToFile(string filePath)
{
//create a string array to gather our text file information.
StreamReader reader = new StreamReader(filePath);
StreamReader info = new StreamReader("Structure.txt");
StreamWriter writer = new StreamWriter("Hello.cs", true);
String temp = String.Empty;
while (!info.EndOfStream)
{
String tempstring = String.Empty;
tempstring = reader.ReadLine();
while (!reader.EndOfStream)
{
temp = reader.ReadLine();
writer.WriteLine(temp);
if (temp == "//break")
{
writer.WriteLine("String1 = {}", tempstring);
}
}
}
reader.Close();
info.Close();
writer.Close();
}
}
}
More efficient? sure
// write
string[] lines = new [] {"Hello, World!", "Goodbye, Cruel World!"};
File.WriteAllLines("c:\\myFile.txt", lines);
// read
string[] lines = File.ReadAllLines("c:\\myFile.txt");
This is all. . .
I am working on a CSV parser using C# TextFieldParser class.
My CSV data is deliminated by , and the string is enclosed by a " character.
However, sometimes the data row cell can also have a " which appears to be making the parser throw an exception.
This is my C# code so far:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Microsoft.VisualBasic.FileIO;
namespace CSV_Parser
{
class Program
{
static void Main(string[] args)
{
// Init
string CSV_File = "test.csv";
// Proceed If File Is Found
if (File.Exists(CSV_File))
{
// Test
Parse_CSV(CSV_File);
}
// Finished
Console.WriteLine("Press any to exit ...");
Console.ReadKey();
}
static void Parse_CSV(String Filename)
{
using (TextFieldParser parser = new TextFieldParser(Filename))
{
parser.TextFieldType = FieldType.Delimited;
parser.SetDelimiters(",");
parser.TrimWhiteSpace = true;
while (!parser.EndOfData)
{
string[] fieldRow = parser.ReadFields();
foreach (string fieldRowCell in fieldRow)
{
// todo
}
}
}
}
}
}
This is the content of my test.csv file:
" dummy test"s data", b , c
d,e,f
gh,ij
What is the best way to deal with " in my row cell data?
UPDATE
Based on Tim Schmelter's answer, I have modified my code to the following:
static void Parse_CSV(String Filename)
{
using (TextFieldParser parser = new TextFieldParser(Filename))
{
parser.TextFieldType = FieldType.Delimited;
parser.SetDelimiters(",");
parser.HasFieldsEnclosedInQuotes = false;
parser.TrimWhiteSpace = true;
while (parser.PeekChars(1) != null)
{
var cleanFieldRowCells = parser.ReadFields().Select(
f => f.Trim(new[] { ' ', '"' }));
Console.WriteLine(String.Join(" | ", cleanFieldRowCells));
}
}
}
Which appears to produce the following (correctly):
Is this is the best way to deal with string enclosed by quotes, having quotes?
Could you omit the quoting-character by setting HasFieldsEnclosedInQuotes to false?
using (var parser = new TextFieldParser(#"Path"))
{
parser.HasFieldsEnclosedInQuotes = false;
parser.Delimiters = new[]{","};
while(parser.PeekChars(1) != null)
{
string[] fields = parser.ReadFields();
}
}
You can remove the quotes manually:
var cleanFields = fields.Select(f => f.Trim(new[]{ ' ', '"' }));
Firstly, i'd just like to mention that I've only started learning C# a few days ago so my knowledge of it is limited.
I'm trying to create a program that will parse text files for certain phrases input by the user and then output them into a new text document.
At the moment, i have it the program searching the original input file and gathering the selected text input by the user, coping those lines out, creating new text files and then merging them together and also deleting them afterwards.
I'm guessing that this is not the most efficient way of creating this but i just created it and had it work in a logical manor for me to understand as a novice.
The code is as follows;
private void TextInput1()
{
using (StreamReader fileOpen = new StreamReader(txtInput.Text))
{
using (StreamWriter fileWrite = new StreamWriter(#"*DIRECTORY*\FIRSTFILE.txt"))
{
string file;
while ((file = fileOpen.ReadLine()) != null)
{
if (file.Contains(txtFind.Text))
{
fileWrite.Write(file + "\r\n");
}
}
}
}
}
private void TextInput2()
{
using (StreamReader fileOpen = new StreamReader(txtInput.Text))
{
using (StreamWriter fileWrite = new StreamWriter(#"*DIRECTORY*\SECONDFILE.txt"))
{
string file;
while ((file = fileOpen.ReadLine()) != null)
{
if (file.Contains(txtFind2.Text))
{
fileWrite.Write("\r\n" + file);
}
}
}
}
}
private static void Combination()
{
ArrayList fileArray = new ArrayList();
using (StreamWriter writer = File.CreateText(#"*DIRECTORY*\FINALOUTPUT.txt"))
{
using (StreamReader reader = File.OpenText(#"*DIRECTORY*\FIRSTFILE.txt"))
{
writer.Write(reader.ReadToEnd());
}
using (StreamReader reader = File.OpenText(#"*DIRECTORY*\SECONDFILE.txt"))
{
writer.Write(reader.ReadToEnd());
}
}
}
private static void Delete()
{
if (File.Exists(#"*DIRECTORY*\FIRSTFILE.txt"))
{
File.Delete(#"*DIRECTORY*\FIRSTFILE.txt");
}
if (File.Exists(#"*DIRECTORY*\SECONDFILE.txt"))
{
File.Delete(#"*DIRECTORY*\SECONDFILE.txt");
}
}
The output file that is being created is simply outputting the first text input followed by the second. I am wondering if it is possible to be able to merge them into 1 file, 1 line at a time as it is a consecutive file meaning have the information from Input 1 followed 2 is needed rather than all of 1 then all of 2.
Thanks, Neil.
To combine the two files content in an one merged file line by line you could substitute your Combination() code with this
string[] file1 = File.ReadAllLines("*DIRECTORY*\FIRSTFILE.txt");
string[] file2 = File.ReadAllLines("*DIRECTORY*\SECONDFILE.txt");
using (StreamWriter writer = File.CreateText(#"*DIRECTORY*\FINALOUTPUT.txt"))
{
int lineNum = 0;
while(lineNum < file1.Length || lineNum < file2.Length)
{
if(lineNum < file1.Length)
writer.WriteLine(file1[lineNum]);
if(lineNum < file2.Length)
writer.WriteLine(file2[lineNum]);
lineNum++;
}
}
This assumes that the two files don't contains the same number of lines.
try this method. You can receive three paths. File 1, File 2 and File output.
public void MergeFiles(string pathFile1, string pathFile2, string pathResult)
{
File.WriteAllText(pathResult, File.ReadAllText(pathFile1) + File.ReadAllText(pathFile2));
}
If the pathResult file exists, the WriteAllText method will overwrite it. Remember to include System.IO namespace.
Important: It is not recommended for large files! Use another options available on this thread.
If your input files are quite large and you run out of memory, you could also try wrapping the two readers like this:
using (StreamWriter writer = File.CreateText(#"*DIRECTORY*\FINALOUTPUT.txt"))
{
using (StreamReader reader1 = File.OpenText(#"*DIRECTORY*\FIRSTFILE.txt"))
{
using (StreamReader reader2 = File.OpenText(#"*DIRECTORY*\SECONDFILE.txt"))
{
string line1 = null;
string line2 = null;
while ((line1 = reader1.ReadLine()) != null)
{
writer.WriteLine(line1);
line2 = reader2.ReadLine();
if(line2 != null)
{
writer.WriteLine(line2);
}
}
}
}
}
Still, you have to have an idea how many lines you have in your input files, but I think it gives you the general idea to proceed.
Using a FileInfo extension you could merge one or more files by doing the following:
public static class FileInfoExtensions
{
public static void MergeFiles(this FileInfo fi, string strOutputPath , params string[] filesToMerge)
{
var fiLines = File.ReadAllLines(fi.FullName).ToList();
fiLines.AddRange(filesToMerge.SelectMany(file => File.ReadAllLines(file)));
File.WriteAllLines(strOutputPath, fiLines.ToArray());
}
}
Usage
FileInfo fi = new FileInfo("input");
fi.MergeFiles("output", "File2", "File3");
I appreciate this question is almost old enough to (up)vote (itself), but for an extensible approach:
const string FileMergeDivider = "\n\n";
public void MergeFiles(string outputPath, params string[] inputPaths)
{
if (!inputPaths.Any())
throw new ArgumentException(nameof(inputPaths) + " required");
if (inputPaths.Any(string.IsNullOrWhiteSpace) || !inputPaths.All(File.Exists))
throw new ArgumentNullException(nameof(inputPaths), "contains invalid path(s)");
File.WriteAllText(outputPath, string.Join(FileMergeDivider, inputPaths.Select(File.ReadAllText)));
}
I'm new with C#. I've written code to open a CSV file from my documents on my local machine. It works well and the data parsing works. Trouble is when I change the code to open the file from an internet site I cannot get it to work. I am able to open this file using VBA but I now want to use C# ADO.NET. I cannot find the answer by searching with Google. Can anyone help with the code and/or point me to a website with a good tutorial. All help much appreciated. Code attached, I'm sure the problem is with lines 24 - 26;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
//
// Read in a file line-by-line, and store it all in a List.
//
int i = 0;
DateTime dte;
List<string> list = new List<string>();
float[] Prices = new float[4];
WebClient wc = new WebClient();
byte[] data = wc.DownloadData("http://www.datasource.com/apps/qt/csv/pricehistory.ac?section=yearly_price_download&code=XXX");
using (StreamReader reader = new StreamReader(wc))
{
string line;
while ((line = reader.ReadLine()) != null)
{
//list.Add(line); // Add to list.
Console.WriteLine(line); // Write to console.
string[] parts = line.Split(',');
int DateSetter = 1;
int DateDone = 0;
int CountFloat = 0;
int PricesDone = 0;
Double Volume = 0;
foreach (string part in parts)
{
Console.WriteLine("{0} : {1}", i, part);
if (DateSetter == 1)
{
dte = DateTime.Parse(part);
DateSetter = 2;
Console.WriteLine(dte);
}
if (DateDone == 1)
{
if (DateSetter < 6)
{
Prices[CountFloat] = float.Parse(part);
CountFloat++;
DateSetter++;
Console.WriteLine(Prices[3]);
}
}
DateDone = 1;
if (PricesDone == 1)
{
Volume = double.Parse(part);
Console.WriteLine(Volume);
}
if (DateSetter == 6)
{
PricesDone = 1;
}
}
}
}
Console.ReadLine();
}
}
}
Your code as pasted would not compile. You can however use the WebClient to download to a string, then split the string into lines:
string content;
using(WebClient wc = new WebClient())
content = wc.DownloadString("http://www.datasource.com/apps/qt/csv/pricehistory.ac?section=yearly_price_download&code=XXX");
foreach(var line in content.Split(new string [] {Environment.NewLine}, StringSplitOptions.None))
{
//...
}
Another option is to download data as you're doing, and then wrap it with a MemoryStream:
WebClient wc = new WebClient();
byte[] data = wc.DownloadData(
"http://www.datasource.com/apps/qt/csv/pricehistory.ac?section=yearly_price_download&code=XXX");
using (var ms = new MemoryStream(data))
{
using (var reader = new StreamReader(ms))
{
string line;
while ((line = reader.ReadLine()) != null)
{
// do whatever
}
}
}
The advantage of this over splitting the string is that it uses considerably less memory.