I've got a page where by intervals of around 10 minutes a csv file is uploaded to a folder (received by an http link). This csv file has to be uploaded to sql. I've managed to get the csv files and save them in the folder, but the problem that I've got is that when I try and read the data it shows that the file is empty (but it is not)... It doesn't throw any errors, but when I run it with a debug, it shows an "Object reference not set to an instance of an object".
This is my code...
Method of what has to happen for this entire process:
private void RunCSVGetToSqlOrder()
{
DAL d = new DAL();
GetGeoLocations();
string geoLocPath = Server.MapPath("~\\GeoLocations\\GeoLocation.csv");
string assetListPath = Server.MapPath("~\\GeoLocations\\AssetList.csv");
d.InsertAssetGeoLocation(ImportGeoLocations(geoLocPath));
d.InsertAssetList(ImportAssetList(assetListPath));
DeleteFileFromFolder();
}
Getting the csv and saving into a folder (working):
private void GetGeoLocations()
{
string linkGeoLoc = "http://app03.gpsts.co.za/io/api/asset_group/APIAssetGroupLocation.class?zqcEK60SxfoP4fVppcLoCXFWUfVRVkKS#auth_token#auth_token";
string filepathGeoLoc = Server.MapPath("~\\GeoLocations\\GeoLocation.csv");
using (WebClient wc = new WebClient())
{
wc.DownloadFileAsync(new System.Uri(linkGeoLoc), filepathGeoLoc);
}
}
Read csv file and import to sql:
private static DataTable ImportGeoLocations(string csvFilePath)
{
DataTable csvData = new DataTable();
try
{
using (TextFieldParser csvReader = new TextFieldParser(csvFilePath))
{
// csvReader.TextFieldType = FieldType.Delimited;
csvReader.SetDelimiters(new string[] { "," });
csvReader.HasFieldsEnclosedInQuotes = true;
csvReader.TrimWhiteSpace = true;
string[] colFields = csvReader.ReadFields();
foreach (string column in colFields)
{
DataColumn datecolumn = new DataColumn(column);
datecolumn.AllowDBNull = true;
csvData.Columns.Add(datecolumn);
}
while (!csvReader.EndOfData)
{
string[] fieldData = csvReader.ReadFields();
//Making empty value as null
for (int i = 0; i < fieldData.Length; i++)
{
if (fieldData[i] == "")
{
fieldData[i] = null;
}
}
csvData.Rows.Add(fieldData);
}
}
}
catch (Exception ex)
{
}
return csvData;
}
The above code gives the error of "Object reference not set to an instance of an object" on the line, but this is most probably due because it's reading the csv as empty(null)...
string[] colFields = csvReader.ReadFields();
I'm not sure what I'm doing wrong... Any advice would be greatly appreciated...
------------ EDIT --------------
The csv file after the download looks as follows:
-------- Solution ------------
Below is the solution:
private void RunCSVGetToSqlOrder()
{
GetGeoLocations();
DeleteFileFromFolder();
}
private void GetGeoLocations()
{
string linkGeoLoc = "http://app03.gpsts.co.za/io/api/asset_group/APIAssetGroupLocation.class?zqcEK60SxfoP4fVppcLoCXFWUfVRVkKS#auth_token#auth_token";
string filepathGeoLoc = Server.MapPath("~\\GeoLocations\\GeoLocation.csv");
using (WebClient wc = new WebClient())
{
wc.DownloadFileAsync(new System.Uri(linkGeoLoc), filepathGeoLoc);
wc.DownloadFileCompleted += new AsyncCompletedEventHandler(wc_DownloadFileCompletedGeoLoc);
}
string linkAssetList = "http://app03.gpsts.co.za/io/api/asset_group/APIAssetGroupLocation.class?zqcEK60SxfoP4fVppcLoCXFWUfVRVkKS#auth_token#auth_token";
string filepathAssetList = Server.MapPath("~\\GeoLocations\\AssetList.csv");
using (WebClient wc = new WebClient())
{
wc.DownloadFileAsync(new System.Uri(linkAssetList), filepathAssetList);
wc.DownloadFileCompleted += new AsyncCompletedEventHandler(wc_DownloadFileCompletedAssetList);
}
}
void wc_DownloadFileCompletedGeoLoc(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
{
DAL d = new DAL();
string geoLocPath = Server.MapPath("~\\GeoLocations\\GeoLocation.csv");
d.InsertAssetGeoLocation(ImportGeoLocations(geoLocPath));
}
void wc_DownloadFileCompletedAssetList(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
{
DAL d = new DAL();
string assetListPath = Server.MapPath("~\\GeoLocations\\AssetList.csv");
d.InsertAssetList(ImportAssetList(assetListPath));
}
The call to wc.DownloadFileAsync returns a Task object and the downloaded file is only complete after the Task is completed.
This issue is hard to catch with the debugger, because the task will have enough time to complete when a breakpoint is reached or the file is manually inspected later. However, when the code runs without break point, the call d.InsertAssetGeoLocation(ImportGeoLocations(geoLocPath)) will be reached before the download is complete and therefore the csv file will be empty.
Possible solutions:
Redesign the code with async / await
Use wd.DownloadFileCompleted event for continuation
Use the synchronous wd.DownloadFile method
... just to name a few.
From the screenshot, it looks like the CSV file is not read properly on your computer. Depending on the language and region settings, the .CSV sometimes has ";" as seperators instead of ",".
Could you try manually replacing all "," with ";" and see if it solves the issue?
Related
Im trying to process a set of files, i have a given number of txt files, which im currently joining into 1 txt file to apply filters to. The creation of the 1 file from multiple works great. But i have 2 questions and 1 error i cant seem to get around.
1 - Im getting an error when i try to read the newly created file so i can apply the filters. "The process cannot access the file because it is being used by another process."
2 - Am i approaching this the correct or more efficient way? by that i mean can the reading and filtering be applied before creating the concatenated file? I mean i still need to create a new file, but it would be nice to be able to apply everything before creating so that the file is already cleaned and ready for use outside the application.
Here is the current code that is having the issue and the 1 commented line that was my other attempt at releasing the file
private DataTable processFileData(string fname, string locs2 = "0", string effDate = "0", string items = "0")
{
DataTable dt = new DataTable();
string fullPath = fname;
try
{
using (StreamReader sr = new StreamReader(File.OpenRead(fullPath)))
//using (StreamReader sr = new StreamReader(File.Open(fullPath,FileMode.Open,FileAccess.Read, FileShare.Read)))
{
while (!sr.EndOfStream)
{
string line = sr.ReadLine();
if (!String.IsNullOrWhiteSpace(line))
{
string[] headers = line.ToUpper().Split('|');
while (dt.Columns.Count < headers.Length)
{
dt.Columns.Add();
}
string[] rows = line.ToUpper().Split('|');
DataRow dr = dt.NewRow();
for (int i = 0; i < rows.Count(); i++)
{
dr[i] = rows[i];
}
dt.Rows.Add(dr);
}
}
//sr.Close();
sr.Dispose();
}
string cls = String.Format("Column6 NOT LIKE ('{0}')", String.Join("','", returnClass()));
dt.DefaultView.RowFilter = cls;
return dt;
}
catch (IOException ex)
{
Console.WriteLine(ex.Message);
return dt;
}
Here is the concatenation method:
private void Consolidate(string fileType)
{
string sourceFolder = #"H:\Merchant\Strategy\Signs\BACKUP TAG DATA\Wave 6\" + sfld;
string destinationFile = #"H:\Merchant\Strategy\Signs\BACKUP TAG DATA\Wave 6\" + sfld + #"\"+ sfld + #"_consolidation.txt";
// Specify wildcard search to match TXT files that will be combined
string[] filePaths = Directory.GetFiles(sourceFolder, fileType);
StreamWriter fileDest = new StreamWriter(destinationFile, true);
int i;
for (i = 0; i < filePaths.Length; i++)
{
string file = filePaths[i];
string[] lines = File.ReadAllLines(file);
if (i > 0)
{
lines = lines.Skip(1).ToArray(); // Skip header row for all but first file
}
foreach (string line in lines)
{
fileDest.WriteLine(line);
}
}
if (sfld == "CLR")
{
clrFilter(destinationFile);
}
if (sfld == "UPL")
{
uplFilter(destinationFile);
}
if (sfld == "HD")
{
hdFilter(destinationFile);
}
if (sfld == "PD")
{
pdFilter(destinationFile);
}
fileDest.Close();
fileDest.Dispose();
}
What im trying to accomplish is reading min(2 or 3 txt files and as much as 13 txt files) and applying some filtering. But im getting this error:
"The process cannot access the file because it is being used by another process."
You're disposing the stream reader with the following line
sr.Dispose();
Using a 'Using' statement will dispose after the stream goes out of context. So remove the Dispose line (if it wasn't clear below)
I wrote this .NET Windows Service application that is basically a file watcher. The service will monitor incoming .csv files, parse data from them, and add the data to spreadsheets. I installed the service on a server and tried to start it. I was given the warning, "The service started and then stopped. Some services stop automatically if they are not in use by other services or programs." In a debug attempt, I removed all the code and just had a bare service and it started/stopped fine. So I added the file watcher object and it popped the warning again. Next I changed the service to run with a local administrative account instead of the "LocalService" account then it worked. I added the rest of my code and it worked for awhile. I finished development and added the EventLog object and I was right back to the warning. I removed the EventLog object but still got the warning. I just do not know what is causing this to not start. Here is my service:
using System;
using System.IO;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using OfficeOpenXml;
using System.Linq;
using System.ServiceProcess;
using System.Text;
namespace COD_Automation
{
public partial class COD_AUTO : ServiceBase
{
FileSystemWatcher eWatcher;
String remoteSrc;
public static String filePath;
public static String fileName;
public static Boolean fileCheck;
public static String modifiedDT;
public static String remodifiedDT;
public static String SampNum;
public static String SampDate;
public static String AnalysisInitials;
public static int SampResult;
public static double Dilution;
public static FileInfo efile;
public int rowIndex = 8;
public int filterID = 1;
public COD_AUTO()
{
InitializeComponent();
if (!System.Diagnostics.EventLog.SourceExists("COD_Automation"))
{
System.Diagnostics.EventLog.CreateEventSource(
"COD_Automation", "COD Automation Log");
}
serviceLog.Source = "COD_Automation";
serviceLog.Log = "COD Automation Log";
}
protected override void OnStart(string[] args)
{
serviceLog.WriteEntry("COD Automation Service has started.");
//Define the remote folder location to watch
remoteSrc = "\\\\mkfiler01\\ops\\Envcom\\EXEC\\ENVCOM\\LAB\\COD\\Exports\\DataLog";
//Create a new FileSystemWatcher and set its properties
eWatcher = new FileSystemWatcher(remoteSrc, "*.csv");
//Add event handler
eWatcher.Created += new FileSystemEventHandler(eWatcher_Created);
//Begin watching
eWatcher.EnableRaisingEvents = true;
}
protected override void OnStop()
{
serviceLog.WriteEntry("COD Automation Service has stopped.");
eWatcher.EnableRaisingEvents = false;
}
private void eWatcher_Created(object source, FileSystemEventArgs e)
{
filePath = e.FullPath;
fileName = e.Name;
ParseData(filePath);
FileCheck(fileName);
CreateExcelFile(fileCheck);
AddSample(SampNum, SampDate, AnalysisInitials, SampResult, Dilution);
}
public void ParseData(String filePath)
{
//Create a dictionary collections with int keys (rowNums) and String values (each line of Strings)
Dictionary<int, String> eachCSVLine = new Dictionary<int, string>();
//String array that holds the contents of the specified row
String[] lineContent;
int rowNum = 1;
foreach (string line in File.ReadLines(filePath))
{
eachCSVLine.Add(rowNum, line);
rowNum++;
}
//Get the required line and split it by "," into an array
String reqLine = eachCSVLine[5];
lineContent = reqLine.Split(',');
//Get the required values(index 2 for parsed Operator ID, index 4 for parsed Sample Number, index 11 for Sample Result)
AnalysisInitials = lineContent.GetValue(2).ToString();
SampNum = lineContent.GetValue(3).ToString(); //sample number
String result = lineContent.GetValue(11).ToString();
String dilute = lineContent.GetValue(8).ToString();
Dilution = Double.Parse(dilute);
SampResult = Int32.Parse(result); //sample result
}
public void AddSample(String SampleNum, String SampleDate, String AnalysisInitials, int SampleResult, double Diluted)
{
try
{
using (ExcelPackage excelPackage = new ExcelPackage(efile))
{
ExcelWorksheet worksheet = excelPackage.Workbook.Worksheets[1];
var cell = worksheet.Cells;
//check to see if this is the first sample added --if true, add the first sample --if false, increment rowindex & filterID then add the sample to next available row
if (cell["A8"].Value == null)
{
cell["B5"].Value = SampleDate;
cell["B6"].Value = AnalysisInitials;
cell[rowIndex, 1].Value = filterID; //Filter ID
cell[rowIndex, 2].Value = SampleNum; //Sample Number
cell[rowIndex, 3].Value = Dilution; //Dilution
cell[rowIndex, 4].Value = SampleResult; //Meter Reading
}
else
{
while (!(cell["A8"].Value == null))
{
rowIndex++;
filterID++;
if (cell[rowIndex, 1].Value == null) //ensures that the new row is blank so the loop can break to continue adding the sample
{ break; }
}
//add the sample to the next empty row
cell[rowIndex, 1].Value = filterID; //Filter ID
cell[rowIndex, 2].Value = SampleNum; //Sample Number
cell[rowIndex, 3].Value = Dilution; //Dilution
cell[rowIndex, 4].Value = SampleResult; //Meter Reading
}
excelPackage.Save();
}
}
catch (Exception e)
{
serviceLog.WriteEntry("Sample could not be added to the spreadsheet because of the following error: " + e.Message + ".");
}
}
public Boolean FileCheck(String fileName)
{
//Get the date of the .csv file
String[] fNames = fileName.Split('_');
String fDate = fNames.ElementAt(3);
DateTime dt = Convert.ToDateTime(fDate);
//format the file date into the proper format and convert to a string
modifiedDT = dt.ToString("MMddyy");
//modify the "modifiedDT to get the sample date to insert into spreadsheet
String mdate = modifiedDT.Insert(2, "/");
remodifiedDT = mdate.Insert(5, "/");
SampDate = remodifiedDT; //sample date
//assign an excel filename
String exFile = #"\\mkfiler01\ops\Envcom\EXEC\ENVCOM\LAB\COD\Imports\" + modifiedDT + "COD-" + AnalysisInitials + ".xlsx";
//check for file existence
if (File.Exists(exFile))
{ fileCheck = true; }
else
{ fileCheck = false; }
return fileCheck;
}
public void CreateExcelFile(Boolean fileCheck)
{
if (fileCheck)
{
efile = new FileInfo(#"\\mkfiler01\ops\Envcom\EXEC\ENVCOM\LAB\COD\Imports\" + modifiedDT + "COD-" + AnalysisInitials + ".xlsx");
using (ExcelPackage excelPackage = new ExcelPackage(efile))
{
//Read the existing file to see if the Analysis Initials match the AnalysisInitial variable value
ExcelWorksheet worksheet = excelPackage.Workbook.Worksheets[1];
String initials = worksheet.Cells["B6"].Value.ToString();
//If initials = AnalysisIntials then assign the existing file the WB variable, else create a new file for the different AnalysisInitials
if (initials.Equals(AnalysisInitials))
{
excelPackage.Save();
}
else
{
try
{
//Excel COD Template to use to create new Excel spreadsheet
FileInfo template = new FileInfo(#"\\mkfiler01\ops\Envcom\EXEC\ENVCOM\LAB\COD\COD TEMPLATE.xlsx");
//The new Excel spreadsheet filename
FileInfo newFile = new FileInfo(#"\\mkfiler01\ops\Envcom\EXEC\ENVCOM\LAB\COD\Imports\" + modifiedDT + "COD-" + AnalysisInitials + ".xlsx");
// Using the template to create the newfile
using (ExcelPackage excelPackage1 = new ExcelPackage(newFile, template))
{
// save the new Excel spreadsheet
excelPackage1.Save();
}
}
catch (Exception ex)
{
serviceLog.WriteEntry("Excel file could not be created because " + ex.Message);
}
}
}
}
else
{
try
{
efile = new FileInfo(#"\\mkfiler01\ops\Envcom\EXEC\ENVCOM\LAB\COD\Imports\" + modifiedDT + "COD-" + AnalysisInitials + ".xlsx");
//Excel COD Template to use to create new Excel spreadsheet
FileInfo template = new FileInfo(#"\\mkfiler01\ops\Envcom\EXEC\ENVCOM\LAB\COD\COD TEMPLATE.xlsx");
//The new Excel spreadsheet filename
FileInfo newFile = new FileInfo(#"\\mkfiler01\ops\Envcom\EXEC\ENVCOM\LAB\COD\Imports\" + modifiedDT + "COD-" + AnalysisInitials + ".xlsx");
// Using the template to create the newfile
using (ExcelPackage excelPackage = new ExcelPackage(newFile, template))
{
// save the new Excel spreadsheet
excelPackage.Save();
}
}
catch (Exception ex)
{
serviceLog.WriteEntry("Excel file could not be created because " + ex.Message);
}
}
}
}
}
My EventViewer was showing details of an ArgumentException in regards to the Source and Log properties of the EventLog object. I changed the following code:
if (!System.Diagnostics.EventLog.SourceExists("COD_Automation"))
{
System.Diagnostics.EventLog.CreateEventSource(
"COD_Automation", "COD Automation Log");
}
serviceLog.Source = "COD_Automation";
serviceLog.Log = "COD Automation Log";
into the following code:
if (!EventLog.SourceExists("COD_Automation"))
{
EventLog.CreateEventSource("COD_Automation", "Application");
}
serviceLog.Source = "COD_Automation";
serviceLog.Log = "Application";
This fixed my problem. I was initially trying to register the COD_Automation source in the COD_Automation Log which doesn't exist. So I set the Log property to the correct log of "Application".
The LocalService account will not have access to a UNC share like \\mkfiler01. My guess is that you are getting an access denied error when trying to access that file share.
Set the service to run under a domain account that has access to that share.
I have 300 csv files that each file contain 18000 rows and 27 columns.
Now, I want to make a windows form application which import them and show in a datagridview and do some mathematical operation later.
But, my performance is very inefficiently...
After search this problem by google, I found a solution "A Fast CSV Reader".
(http://www.codeproject.com/Articles/9258/A-Fast-CSV-Reader)
I'm follow the code step by step, but my datagridview still empty.
I don't know how to solve this problem.
Could anyone tell me how to do or give me another better way to read csv efficiently.
Here is my code...
using System.IO;
using LumenWorks.Framework.IO.Csv;
private void Form1_Load(object sender, EventArgs e)
{
ReadCsv();
}
void ReadCsv()
{
// open the file "data.csv" which is a CSV file with headers
using (CachedCsvReader csv = new
CachedCsvReader(new StreamReader("data.csv"), true))
{
// Field headers will automatically be used as column names
dataGridView1.DataSource = csv;
}
}
Here is my input data:
https://dl.dropboxusercontent.com/u/28540219/20130102.csv
Thanks...
The data you provide contains no headers (first line is a data line). So I got an ArgumentException (item with same key added) when I tried to add the csv reader to the DataSource. Setting the hasHeaders parameter in the CachCsvReader constructor did the trick and it added the data to the DataGridView (very fast).
using (CachedCsvReader csv = new CachedCsvReader(new StreamReader("data.csv"), false))
{
dataGridView.DataSource = csv;
}
Hope this helps!
You can also do like
private void ReadCsv()
{
string filePath = #"C:\..\20130102.csv";
FileStream fileStream = null;
try
{
fileStream = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
}
catch (Exception ex)
{
return;
}
DataTable table = new DataTable();
bool isColumnCreated = false;
using (StringReader reader = new StringReader(new StreamReader(fileStream, Encoding.Default).ReadToEnd()))
{
while (reader.Peek() != -1)
{
string line = reader.ReadLine();
if (line == null || line.Length == 0)
continue;
string[] values = line.Split(',');
if(!isColumnCreated)
{
for(int i=0; i < values.Count(); i++)
{
table.Columns.Add("Column" + i);
}
isColumnCreated = true;
}
DataRow row = table.NewRow();
for(int i=0; i < values.Count(); i++)
{
row[i] = values[i];
}
table.Rows.Add(row);
}
}
dataGridView1.DataSource = table;
}
Based on you performance requirement, this code can be improvised. It is just a working sample for your reference.
I hope this will give some idea.
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)));
}
Hi I have a text file with table schema and data when user checks not schema required then i need to delete schema and leave the data . I am using StreamReader to read the file and checking one condition and it should delete all the lines in the file till it satisfies my condition .
Let say if i am checking
using (StreamReader tsr = new StreamReader(targetFilePath))
{
do
{
string textLine = tsr.ReadLine() + "\r\n";
{
if (textLine.StartsWith("INSERT INTO"))
{
// It should leave these lines
// and no need to delete lines
}
else
{
// it should delete the lines
}
}
}
while (tsr.Peek() != -1);
tsr.Close();
Please suggest me how to delete lines and note if textline finds "InsertInto" it should not delete any content from there .
Use a second file where to put only required lines, and, at the end of the process, remove original file and rename new one to target file.
using (StreamReader tsr = new StreamReader(targetFilePath))
{
using (StreamWriter tsw = File.CreateText(targetFilePath+"_temp"))
{
string currentLine;
while((currentLine = tsr.ReadLine()) != null)
{
if(currentLine.StartsWith("A long time ago, in a far far away galaxy ..."))
{
tsw.WriteLine(currentLine);
}
}
}
}
File.Delete(targetFilePath);
File.Move(targetFilePath+"_temp",targetFilePath);
You could use Linq:
File.WriteAllLines(targetFilePath, File.ReadAllLines(targetFilePath).Where(x => x.StartsWith("INSERT INTO")));
You read in the file just the same way you were doing. However, if the line doesn't contain what you are looking for, you simply skip it. In the end, whatever data you are left over with you then write to a new text file.
private void button1_Click(object sender, EventArgs e)
{
StringBuilder newText = new StringBuilder();
using (StreamReader tsr = new StreamReader(targetFilePath))
{
do
{
string textLine = tsr.ReadLine() + "\r\n";
{
if (textLine.StartsWith("INSERT INTO"))
{
newText.Append(textLine + Environment.NewLine);
}
}
}
while (tsr.Peek() != -1);
tsr.Close();
}
System.IO.TextWriter w = new System.IO.StreamWriter(#"C:\newFile.txt");
w.Write(newText.ToString());
w.Flush();
w.Close();
}