c# Write DataTable Rows in txt File - c#

I have for like 40 rows on My DataTable Displayed in a DataGridView
i'm confused why my method Saves Only One Row in the TextFile :
private void SaveBtn_Click(object sender, EventArgs e)
{
String outputFile;
List<String> ListData = new List<String>();
using (SaveFileDialog sfd = new SaveFileDialog())
{
sfd.Filter = "Txt File|*.Txt";
if (sfd.ShowDialog() != DialogResult.OK)
return;
outputFile = sfd.FileName;
}
DataTable tb = pw.SavedInfo(User_info.UserID);
for (int i = 0; i < tb.Rows.Count; i++)
{
ListData.Add("Name==> " + tb.Rows[i][1].ToString() + " LastName ==> " + tb.Rows[i][2].ToString() + " Email ==> " + tb.Rows[i][3].ToString() );
}
foreach (String s in ListData)
{
using (TextWriter Tw = new StreamWriter(outputFile))
{
Tw.WriteLine(s);
}
}
}
Did i missed something ? cause it was a really long day to keep being focused

Use the same StreamWriter:
using (TextWriter Tw = new StreamWriter(outputFile))
{
foreach (String s in ListData)
{
Tw.WriteLine(s);
}
}
or use the constructor that takes a bool for "append":
foreach (String s in ListData)
{
using (TextWriter Tw = new StreamWriter(outputFile, true))
{
Tw.WriteLine(s);
}
}

File.WriteAllLines(outputFile, lisData);
Use this to write in the file. File.WriteAllLines Documentation

Related

StreamWriter: Starting and ending on a specific line number

I would like to ask some tips and help on a reading/writing part of my C#.
Situation:
I have to read a CSV file; - OK
If the CSV file name starts with "Load_", I want to write on another CSV the data from line 2 to the last one;
If the CSV file name starts with "RO_", I want to write on 2 different CSVs, 1 with the line 1 to 4 and the other 4 to the last one;
What I have so far is:
public static void ProcessFile(string[] ProcessFile)
{
// Keeps track of your current position within a record
int wCurrLine = 0;
// Number of rows in the file that constitute a record
const int LINES_PER_ROW = 1;
int ctr = 0;
foreach (string filename in ProcessFile)
{
var sbText = new System.Text.StringBuilder(100000);
int stop_line = 0;
int start_line = 0;
// Used for the output name of the file
var dir = Path.GetDirectoryName(filename);
var fileName = Path.GetFileNameWithoutExtension(filename);
var ext = Path.GetExtension(filename);
var folderbefore = Path.GetFullPath(Path.Combine(dir, #"..\"));
var lineCount = File.ReadAllLines(#filename).Length;
string outputname = folderbefore + "output\\" + fileName;
using (StreamReader Reader = new StreamReader(#filename))
{
if (filename.Contains("RO_"))
{
start_line = 1;
stop_line = 5;
}
else
{
start_line = 2;
stop_line = lineCount;
}
ctr = 0;
while (!Reader.EndOfStream && ctr < stop_line)
{
// Add the text
sbText.Append(Reader.ReadLine());
// Increment our current record row counter
wCurrLine++;
// If we have read all of the rows for this record
if (wCurrLine == LINES_PER_ROW)
{
// Add a line to our buffer
sbText.AppendLine();
// And reset our record row count
wCurrLine = 0;
}
ctr++;
} // end of the while
}
int total_lenght = sbText.Length
// When all of the data has been loaded, write it to the text box in one fell swoop
using (StreamWriter Writer = new StreamWriter(dir + "\\" + "output\\" + fileName + "_out" + ext))
{
Writer.Write.(sbText.);
}
} // end of the foreach
} // end of ProcessFile
I was thinking about using the IF/ELSE: "using (StreamWriter Writer = new StreamWriter(dir + "\" + "output\" + fileName + "_out" + ext))" part. However, I am not sure how to pass, to StreamWriter, to only write from/to a specific line number.
Any Help is welcome! If I am missing some information, please, let me know (I am pretty new on stackoverflow).
Thank you.
Code is way too complicated
using System.Collections.ObjectModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace ConsoleApplication57
{
class Program
{
static void Main(string[] args)
{
}
public static void ProcessFile(string[] ProcessFile)
{
foreach (string filename in ProcessFile)
{
// Used for the output name of the file
var dir = Path.GetDirectoryName(filename);
var fileName = Path.GetFileNameWithoutExtension(filename);
var ext = Path.GetExtension(filename);
var folderbefore = Path.GetFullPath(Path.Combine(dir, #"..\"));
var lineCount = File.ReadAllLines(#filename).Length;
string outputname = folderbefore + "output\\" + fileName;
using (StreamWriter Writer = new StreamWriter(dir + "\\" + "output\\" + fileName + "_out" + ext))
{
int rowCount = 0;
using (StreamReader Reader = new StreamReader(#filename))
{
rowCount++;
string inputLine = "";
while ((inputLine = Reader.ReadLine()) != null)
{
if (filename.Contains("RO_"))
{
if (rowCount <= 4)
{
Writer.WriteLine(inputLine);
}
if (rowCount == 4) break;
}
else
{
if (rowCount >= 2)
{
Writer.WriteLine(inputLine);
}
}
} // end of the while
Writer.Flush();
}
}
} // end of the foreach
} // end of ProcessFile
}
}
You can use LINQ to Take and Skip lines.
public abstract class CsvProcessor
{
private readonly IEnumerable<string> processFiles;
public CsvProcessor(IEnumerable<string> processFiles)
{
this.processFiles = processFiles;
}
protected virtual IEnumerable<string> GetAllLinesFromFile(string fileName)
{
using(var stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
using(var reader = new StreamReader(stream))
{
var line = String.Empty;
while((line = reader.ReadLine()) != null)
{
yield return line;
}
}
}
protected virtual void ProcessFiles()
{
var sb1 = new StringBuilder();
var sb2 = new StringBuilder();
foreach(var file in this.processFiles)
{
var fileName = Path.GetFileNameWithoutExtension(file);
var lines = GetAllLinesFromFile(file);
if(fileName.StartsWith("RO_", StringComparison.InvariantCultureIgnoreCase))
{
sb1.AppendLine(lines.Take(4)); //take only the first four lines
sb2.AppendLine(lines.Skip(4).TakeWhile(s => !String.IsNullOrEmpty(s))); //skip the first four lines, take everything else
}
else if(fileName.StartsWith("Load_", StringComparison.InvariantCultureIgnoreCase)
{
sb2.AppendLine(lines.Skip(1).TakeWhile(s => !String.IsNullOrEmpty(s)));
}
}
// now write your StringBuilder objects to file...
}
protected virtual void WriteFile(StringBuilder sb1, StringBuilder sb2)
{
// ... etc..
}
}

How to edit a file, appending data at the beginning, without rewriting the whole file?

I have a csv file, and I need to add a unique ID based on the first two characters of the file. I have the following code:
using (StreamReader sr = new StreamReader(f))
{
string currentLine;
int id = 0;
while ((currentLine = sr.ReadLine()) != null)
{
string row = currentLine.ToString();
string FirstTwoCharacters = currentLine.Substring(0, 2);
if (FirstTwoCharacters == "01")
{
id = id + 1;
row += "*" + id.ToString();
using (StreamWriter files = File.AppendText(dir + newfilename))
{
files.WriteLine(row);
}
}
else
{
row += "*" + id.ToString();
using (StreamWriter files = File.AppendText(dir + newfilename))
{
files.WriteLine(row);
}
}
}
}
The csv files can be huge, 1Gb in size, around 6 million rows. Just wanted advice, if there is a quicker way to handling this, as it currently can take 3+ hours to process a file, and multiple files can be received in one go.
Instead of opening new file for appending line for each line of input file you can keep stream writer opened:
using (StreamReader sr = new StreamReader(f))
using (StreamWriter files = File.AppendText(dir + newfilename))
{
string currentLine;
int id = 0;
while ((currentLine = sr.ReadLine()) != null)
{
string firstTwoCharacters = currentLine.Substring(0, 2);
if (firstTwoCharacters == "01")
id++;
files.WriteLine(currentLine + "*" + id);
}
}
You can also use File.ReadLines to enumerate source lines:
using (StreamWriter writer = File.AppendText(dir + newfilename))
{
int id = 0;
foreach(var line in File.ReadLines(f))
{
if (line.Substring(0,2) == "01")
id++;
writer.WriteLine($"{line}*{id}");
}
}
Or even LINQ approach
int id = 0;
var newLines = from line in File.ReadLines(f)
let incrementId = line.Substring(0,2) == "01"
select $"{line}*{incrementId ? (++id) : id}";
File.WriteAllLines(dir + newfilename, newLines);
opening the (File.AppendText) inside the while loop is costly, move this to outside the while
using (StreamReader sr = new StreamReader(f))
{
string currentLine;
int id = 0;
using (StreamWriter files = File.AppendText(dir + newfilename))
{
while ((currentLine = sr.ReadLine()) != null)
{
string row = currentLine.ToString();
string FirstTwoCharacters = currentLine.Substring(0, 2);
if (FirstTwoCharacters == "01")
{
id = id + 1;
row += "*" + id.ToString();
files.WriteLine(row);
}
else
{
row += "*" + id.ToString();
files.WriteLine(row);
}
}
}
}

Dynamic Table Loader

I have some files which I receive and don't know how many columns and rows I have in those files.
How can I make a generic loader with a generic model where I can always load the file but get different content?
I wrote this but know I know its not always the same table...
public override List<Object> getFile(string ab) {
if (ab == "A") {
ab = A;
} else {
ab = B;
}
List<FundPriceModel> models = new List<FundPriceModel>();
FileStream filestream = new FileStream(ab, FileMode.Open, FileAccess.Read);
using (StreamReader reader = new StreamReader(filestream, Encoding.UTF8)) {
string line;
bool isHeader = true;
while ((line = reader.ReadLine()) != null) {
FundPriceModel model = new FundPriceModel();
if (isHeader) {
headers = line.Split(spliter[0]);
isHeader = false;
continue;
}
string[] attributes = line.Split(spliter);
model.LipperID = IfEmptyInt(attributes[0]);
model.PriceDate = IfEmptyDateTime(attributes[1]);
model.PriceCode = safeValue(attributes[2], v => v[0]);
model.PriceType = safeValue(attributes[3], v => v[0]);
model.PriceCurrency = safeValue(attributes[4], v => attributes[4]);
model.PriceValueLC = IfEmptyFloat(attributes[5]);
model.Estimate = safeValue(attributes[6], v => v[0]);
Console.WriteLine(model.LipperID + "\t" + model.PriceDate + "\t" + model.PriceCode + "\t" + model.PriceType +
"\t" + model.PriceCurrency + "\t" + model.PriceValueLC + "\t" + model.Estimate);
models.Add(model);
}
}
}
If a DataTable is generic enough you could use that, its not really a 'Model'. This code is not production worthy and only demonstrates how to load from a CSV.
private static void Main(string[] args)
{
string filePath = #"C:\temp\tesst.csv";
FileStream filestream = new FileStream(filePath, FileMode.Open, FileAccess.Read);
DataTable inputTable = new DataTable();
using (StreamReader reader = new StreamReader(filestream, Encoding.UTF8))
{
//Get headers and add columns
string headers = reader.ReadLine();
foreach (var s in headers.Split(','))
{
inputTable.Columns.Add(s, typeof (string));
}
//Add rows
string line;
while ((line = reader.ReadLine()) != null)
{
int colIndex = 0;
DataRow dr = inputTable.NewRow();
foreach (var s in line.Split(','))
{
dr[colIndex] = s;
colIndex++;
}
inputTable.Rows.Add(dr);
}
}
}

Open existing file, append a single line

I want to open a text file, append a single line to it, then close it.
You can use File.AppendAllText for that:
File.AppendAllText(#"c:\path\file.txt", "text content" + Environment.NewLine);
using (StreamWriter w = File.AppendText("myFile.txt"))
{
w.WriteLine("hello");
}
Choice one! But the first is very simple. The last maybe util for file manipulation:
//Method 1 (I like this)
File.AppendAllLines(
"FileAppendAllLines.txt",
new string[] { "line1", "line2", "line3" });
//Method 2
File.AppendAllText(
"FileAppendAllText.txt",
"line1" + Environment.NewLine +
"line2" + Environment.NewLine +
"line3" + Environment.NewLine);
//Method 3
using (StreamWriter stream = File.AppendText("FileAppendText.txt"))
{
stream.WriteLine("line1");
stream.WriteLine("line2");
stream.WriteLine("line3");
}
//Method 4
using (StreamWriter stream = new StreamWriter("StreamWriter.txt", true))
{
stream.WriteLine("line1");
stream.WriteLine("line2");
stream.WriteLine("line3");
}
//Method 5
using (StreamWriter stream = new FileInfo("FileInfo.txt").AppendText())
{
stream.WriteLine("line1");
stream.WriteLine("line2");
stream.WriteLine("line3");
}
Or you could use File.AppendAllLines(string, IEnumerable<string>)
File.AppendAllLines(#"C:\Path\file.txt", new[] { "my text content" });
Might want to check out the TextWriter class.
//Open File
TextWriter tw = new StreamWriter("file.txt");
//Write to file
tw.WriteLine("test info");
//Close File
tw.Close();
The technically best way is probably this here:
private static async Task AppendLineToFileAsync([NotNull] string path, string line)
{
if (string.IsNullOrWhiteSpace(path))
throw new ArgumentOutOfRangeException(nameof(path), path, "Was null or whitepsace.");
if (!File.Exists(path))
throw new FileNotFoundException("File not found.", nameof(path));
using (var file = File.Open(path, FileMode.Append, FileAccess.Write))
using (var writer = new StreamWriter(file))
{
await writer.WriteLineAsync(line);
await writer.FlushAsync();
}
}
File.AppendText will do it:
using (StreamWriter w = File.AppendText("textFile.txt"))
{
w.WriteLine ("-------HURRAY----------");
w.Flush();
}
//display sample reg form in notepad.txt
using (StreamWriter stream = new FileInfo("D:\\tt.txt").AppendText())//ur file location//.AppendText())
{
stream.WriteLine("Name :" + textBox1.Text);//display textbox data in notepad
stream.WriteLine("DOB : " + dateTimePicker1.Text);//display datepicker data in notepad
stream.WriteLine("DEP:" + comboBox1.SelectedItem.ToString());
stream.WriteLine("EXM :" + listBox1.SelectedItem.ToString());
}
We can use
public StreamWriter(string path, bool append);
while opening the file
string path="C:\\MyFolder\\Notes.txt"
StreamWriter writer = new StreamWriter(path, true);
First parameter is a string to hold a full file path
Second parameter is Append Mode, that in this case is made true
Writing to the file can be done with:
writer.Write(string)
or
writer.WriteLine(string)
Sample Code
private void WriteAndAppend()
{
string Path = Application.StartupPath + "\\notes.txt";
FileInfo fi = new FileInfo(Path);
StreamWriter SW;
StreamReader SR;
if (fi.Exists)
{
SR = new StreamReader(Path);
string Line = "";
while (!SR.EndOfStream) // Till the last line
{
Line = SR.ReadLine();
}
SR.Close();
int x = 0;
if (Line.Trim().Length <= 0)
{
x = 0;
}
else
{
x = Convert.ToInt32(Line.Substring(0, Line.IndexOf('.')));
}
x++;
SW = new StreamWriter(Path, true);
SW.WriteLine("-----"+string.Format("{0:dd-MMM-yyyy hh:mm:ss tt}", DateTime.Now));
SW.WriteLine(x.ToString() + "." + textBox1.Text);
}
else
{
SW = new StreamWriter(Path);
SW.WriteLine("-----" + string.Format("{0:dd-MMM-yyyy hh:mm:ss tt}", DateTime.Now));
SW.WriteLine("1." + textBox1.Text);
}
SW.Flush();
SW.Close();
}

Open a file and replace strings in C#

I'm trying to figure out the best way to open an existing file and replace all strings that match a declared string with a new string, save it then close.
Suggestions ?
Can be done in one line:
File.WriteAllText("Path", Regex.Replace(File.ReadAllText("Path"), "[Pattern]", "Replacement"));
If you're reading large files in, and your string for replacement may not appear broken across multiple lines, I'd suggest something like the following...
private static void ReplaceTextInFile(string originalFile, string outputFile, string searchTerm, string replaceTerm)
{
string tempLineValue;
using (FileStream inputStream = File.OpenRead(originalFile) )
{
using (StreamReader inputReader = new StreamReader(inputStream))
{
using (StreamWriter outputWriter = File.AppendText(outputFile))
{
while(null != (tempLineValue = inputReader.ReadLine()))
{
outputWriter.WriteLine(tempLineValue.Replace(searchTerm,replaceTerm));
}
}
}
}
}
Then you'd have to remove the original file, and rename the new one to the original name, but that's trivial - as is adding some basic error checking into the method.
Of course, if your replacement text could be across two or more lines, you'd have to do a little more work, but I'll leave that to you to figure out. :)
using System;
using System.IO;
using System.Text.RegularExpressions;
public static void ReplaceInFile(
string filePath, string searchText, string replaceText )
{
var content = string.Empty;
using (StreamReader reader = new StreamReader( filePath ))
{
content = reader.ReadToEnd();
reader.Close();
}
content = Regex.Replace( content, searchText, replaceText );
using (StreamWriter writer = new StreamWriter( filePath ))
{
writer.Write( content );
writer.Close();
}
}
Slight improvement on the accepted answer that doesn't require Regex, and which meets the requirements of the question:
File.WriteAllText("Path", File.ReadAllText("Path").Replace("SearchString", "Replacement"));
public partial class ReadAndChange : System.Web.UI.Page
{
ArrayList FolderList = new ArrayList();
ArrayList FolderListSearch = new ArrayList();
ArrayList FileList = new ArrayList();
protected void Page_Load(object sender, EventArgs e)
{
AllFolderList("D:\\BinodBackup\\Nilesh\\14.5.2013\\Source");
foreach (string Path in FolderList)
{
AllFileList(Path);
}
foreach (string Path in FileList)
{
ReplaceFile(Path, Path.Replace("Source", "EditedCode"));
}
//string SourcePath = "D:\\BinodBackup\\Nilesh\\14.5.2013\\Onesource\\Onesource\\UserManagement\\UserControls\\AddUserDetails.ascx.cs";
//string ReplacePath = "D:\\AddUserDetails.ascx.cs";
//ReplaceFile(SourcePath, ReplacePath);
}
private static void ReplaceFile(string SourcePath, string ReplacePath)
{
int counter = 1;
string line;
// Read the file and display it line by line.
System.IO.StreamReader file = new System.IO.StreamReader(SourcePath);
while ((line = file.ReadLine()) != null)
{
if (!(line.Contains("//")))
{
if (line.Contains(".LogException("))
{
//Console.WriteLine(counter.ToString() + ": " + line);
string[] arr = line.Split(',');
string stringToReplace = arr[0].Replace("LogException", "Publish") + " , " + arr[2].Trim() + " , " + arr[3].Replace(");", "").Trim() + " , " + arr[1].Trim() + ");";
//File.WriteAllText(currentPath, Regex.Replace(File.ReadAllText(currentPath), line, line + " Added"));
File.WriteAllText(ReplacePath, File.ReadAllText(ReplacePath).Replace(line, stringToReplace));
//ReplaceInFile(currentPath, line, stringToReplace);
}
}
counter++;
}
file.Close();
}
private void AllFileList(string FolderPath)
{
DirectoryInfo dir = new DirectoryInfo(FolderPath);
DirectoryInfo[] subdir = dir.GetDirectories();
if (subdir.Length > 0)
{
foreach (DirectoryInfo dr in subdir)
{
FileInfo[] files1 = dr.GetFiles();
foreach (FileInfo file in files1)
{
if(file.Name.EndsWith(".cs"))
CheckAndAdd((file.DirectoryName + "\\" + file.Name), FileList);
}
}
}
}
private void AllFolderList(string FolderPath)
{
string CurFolderPatgh = FolderPath;
Again:
AddToArrayList(CurFolderPatgh);
DirectoryInfo dir = new DirectoryInfo(CurFolderPatgh);
DirectoryInfo[] subdir = dir.GetDirectories();
if (subdir.Length > 0)
{
foreach (DirectoryInfo dr in subdir)
{
AddToArrayList(((System.IO.FileSystemInfo)(dir)).FullName + "\\" + dr.Name);
}
}
if (FolderListSearch.Count > 0)
{
foreach (string dr in FolderListSearch)
{
CurFolderPatgh = dr;
FolderListSearch.Remove(dr);
goto Again;
}
}
}
private void AddToArrayList(string FolderPath)
{
if (!(FolderList.Contains(FolderPath)))
{
CheckAndAdd(FolderPath, FolderList);
CheckAndAdd(FolderPath, FolderListSearch);
}
}
private void CheckAndAdd(string FolderPath,ArrayList ar)
{
if (!(ar.Contains(FolderPath)))
{
ar.Add(FolderPath);
}
}
public static void ReplaceInFile(
string filePath, string searchText, string replaceText)
{
var content = string.Empty;
using (StreamReader reader = new StreamReader(filePath))
{
content = reader.ReadToEnd();
reader.Close();
}
content = content.Replace(searchText, replaceText);
using (StreamWriter writer = new StreamWriter(filePath))
{
writer.Write(content);
writer.Close();
}
}
}
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
namespace DevExpressFileEditing
{
class Program
{
static List<FileInfo> _files;
private static Dictionary<string, string> _replaceList;
static void Main()
{
_files = new List<FileInfo>();
_replaceList = new Dictionary<string, string>();
Console.WriteLine("Dark directory searching");
SearchFilesInDirectories(new DirectoryInfo(#"C:\Sourcebank\Dark"));
Console.WriteLine("Light directory searching");
SearchFilesInDirectories(new DirectoryInfo(#"C:\Sourcebank\Light"));
Console.WriteLine("{0} files found", _files.Count.ToString(CultureInfo.InvariantCulture));
Console.WriteLine("Replace dictinary creating");
CreateReplaceList();
Console.WriteLine("{0} item added", _replaceList.Count.ToString(CultureInfo.InvariantCulture));
Console.Write("Replacement doing");
for (int i = 0; i < _files.Count; i++)
{
var fileInfo = _files[i];
Console.CursorLeft = 0;
Console.Write("{0} of {1}", i.ToString(CultureInfo.InvariantCulture), _files.Count.ToString(CultureInfo.InvariantCulture));
ReplaceInFile(fileInfo.FullName);
}
Console.CursorLeft = 0;
Console.Write("Replacement done");
}
private static void SearchFilesInDirectories(DirectoryInfo dir)
{
if (!dir.Exists) return;
foreach (DirectoryInfo subDirInfo in dir.GetDirectories())
SearchFilesInDirectories(subDirInfo);
foreach (var fileInfo in dir.GetFiles())
_files.Add(fileInfo);
}
private static void CreateReplaceList()
{
_replaceList.Add("Color=\"#FFF78A09\"", "Color=\"{DynamicResource AccentColor}\"");
_replaceList.Add("Color=\"{StaticResource ColorHot}\"", "Color=\"{DynamicResource AccentColor}\"");
_replaceList.Add("Color=\"#FFCC0000\"", "Color=\"{DynamicResource AccentColor}\"");
_replaceList.Add("To=\"#FFCC0000\"", "To=\"{DynamicResource AccentColor}\"");
_replaceList.Add("To=\"#FFF78A09\"", "To=\"{DynamicResource AccentColor}\"");
_replaceList.Add("Background=\"#FFF78A09\"", "Background=\"{DynamicResource Accent}\"");
_replaceList.Add("Foreground=\"#FFF78A09\"", "Foreground=\"{DynamicResource Accent}\"");
_replaceList.Add("BorderBrush=\"#FFF78A09\"", "BorderBrush=\"{DynamicResource Accent}\"");
_replaceList.Add("Value=\"#FFF78A09\"", "Value=\"{DynamicResource Accent}\"");
_replaceList.Add("Fill=\"#FFF78A09\"", "Fill=\"{DynamicResource Accent}\"");
}
public static void ReplaceInFile(string filePath)
{
string content;
using (var reader = new StreamReader(filePath))
{
content = reader.ReadToEnd();
reader.Close();
}
content = _replaceList.Aggregate(content, (current, item) => current.Replace(item.Key, item.Value));
using (var writer = new StreamWriter(filePath))
{
writer.Write(content);
writer.Close();
}
}
}
}

Categories

Resources