I used to use csv file in my application
here is the original code
string csvFile = Directory.GetCurrentDirectory() + #"\data\" + Scheme + ".csv"
DataTable dt = ReadCSV(csvFile);
dgv.DataSource = dt;
now I want to put csv file as embedded resource
I tried this. but It does not work
string csvFile = System.Resources.MyFile; //This is error
DataTable dt = ReadCSV(csvFile);
dgv.DataSource = dt;
I wonder how to get the code running correctly?
Once the file has been added in the menu Project/Properties/Resources like #dr.null said, you have to click on the item's name in the solution explorer so that you can set Action property to "build-in resource".
Then, use something like that:
using System.Reflection;
var assembly = Assembly.GetExecutingAssembly();
var resourceName = "assembly_name.Resources.yourFile.csv";
var lines = ReadLines(() => Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName), Encoding.UTF8).ToList();
Where:
public IEnumerable<string> ReadLines(Func<Stream> streamProvider, Encoding encoding)
{
using (var stream = streamProvider())
using (var reader = new StreamReader(stream, encoding))
{
string line;
while ((line = reader.ReadLine()) != null)
{
yield return line;
}
}
}
You'll have the variable lines containing your csv data.
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)
Using .net core & c# here.
I have a UI from which user can upload the Excel or CSV files. Once they upload this goes to my web api which handles the reading of the data from these files and returns json.
My Api code as:
[HttpPost("upload")]
public async Task<IActionResult> FileUpload(IFormFile file)
{
JArray data = new JArray();
using (ExcelPackage package = new ExcelPackage(file.OpenReadStream()))
{
ExcelWorksheet worksheet = package.Workbook.Worksheets[1];
//Process, read from excel here and populate jarray
}
return Ok(data );
}
In my above code I am using EPPlus for reading the excel file. For excel file it works all fine but it cannot read csv file which is the limitation of EPPlus.
I searched and found another library CSVHelper: https://joshclose.github.io/CsvHelper/ The issue with this is it does vice versa and can read from CSV but not from Excel.
Is there any library available which supports reading from both.
Or would it be possible use EPPlus only but convert uploaded CSV to excel on the fly and then read. (please note I am not storing the excel file anywhere so cant use save as to save it as excel)
Any inputs please?
--Updated - Added code for reading data from excel---
int rowCount = worksheet.Dimension.End.Row;
int colCount = worksheet.Dimension.End.Column;
for (int row = 1; row <= rowCount; row++)
{
for (int col = 1; col <= colCount; col++)
{
var rowValue = worksheet.Cells[row, col].Value;
}
}
//With the code suggested in the answer rowcount is always 1
You can use EPPLus and a MemoryStream for opening csv files into an ExcelPackage without writing to a file. Below is an example. You may have to change some of the the parameters based on your CSV file specs.
[HttpPost("upload")]
public async Task<IActionResult> FileUpload(IFormFile file)
{
var result = string.Empty;
string worksheetsName = "data";
bool firstRowIsHeader = false;
var format = new ExcelTextFormat();
format.Delimiter = ',';
format.TextQualifier = '"';
using (var reader = new System.IO.StreamReader(file.OpenReadStream()))
using (ExcelPackage package = new ExcelPackage())
{
result = reader.ReadToEnd();
ExcelWorksheet worksheet =
package.Workbook.Worksheets.Add(worksheetsName);
worksheet.Cells["A1"].LoadFromText(result, format, OfficeOpenXml.Table.TableStyles.Medium27, firstRowIsHeader);
}
}
Here's using Aspose, which is unfortunately not free, but wow it works great. My API is using the streaming capability with Content-Type: multipart/form-data rather than the IFormFile implementation:
[HttpPut]
[DisableFormValueModelBinding]
public async Task<IActionResult> UploadSpreadsheet()
{
if (!MultipartRequestHelper.IsMultipartContentType(Request.ContentType))
{
return BadRequest($"Expected a multipart request, but got {Request.ContentType}");
}
var boundary = MultipartRequestHelper.GetBoundary(MediaTypeHeaderValue.Parse(Request.ContentType), _defaultFormOptions.MultipartBoundaryLengthLimit);
var reader = new MultipartReader(boundary, HttpContext.Request.Body);
var section = (await reader.ReadNextSectionAsync()).AsFileSection();
//If you're doing CSV, you add this line:
LoadOptions loadOptions = new LoadOptions(LoadFormat.CSV);
var workbook = new Workbook(section.FileStream, loadOptions);
Cells cells = workbook.Worksheets[0].Cells;
var rows = cells.Rows.Cast<Row>().Where(x => !x.IsBlank);
//Do whatever else you want here
Please try with below code
private string uploadCSV(FileUpload fl)
{
string fileName = "";
serverLocation = Request.PhysicalApplicationPath + "ExcelFiles\\";
fileName = fl.PostedFile.FileName;
int FileSize = fl.PostedFile.ContentLength;
string contentType = fl.PostedFile.ContentType;
fl.PostedFile.SaveAs(serverLocation + fileName);
string rpath = string.Empty, dir = string.Empty;
HttpContext context = HttpContext.Current;
string baseUrl = context.Request.Url.Scheme + "://" + context.Request.Url.Authority + context.Request.ApplicationPath.TrimEnd('/') + '/';
try
{
rpath = serverLocation + fileName;//Server.MapPath(dir + fileName);
using (Stream InputStream = fl.PostedFile.InputStream)
{
Object o = new object();
lock (o)
{
byte[] buffer = new byte[InputStream.Length];
InputStream.Read(buffer, 0, (int)InputStream.Length);
lock (o)
{
File.WriteAllBytes(rpath, buffer);
buffer = null;
}
InputStream.Close();
}
}
}
catch (Exception ex)
{
lblSOTargetVal.Text = ex.Message.ToString();
}
return rpath;
}
Use the Open XML SDK package and add insert working solution for it.
So I have lots of data but I'm not sure how I remove the corrupt data.
In the file the list is like this:
EMERIE,ESPARZA,166,57,34,BLUE,BLONDE
ADALINE,PARSONS,158,39,£$**),BROWN,GREY
The £$**) represents corrupted data but I don't know how to remove it, I have over 10,000 names and some of them are like this.
Assuming you want to completely remove the corrupted data rows rather than modify them, you could do something like the following:
public void RemoveCorruptData()
{
string path = #"C:\CSV.txt";
string newPath = #"C:\new-CSV.txt";
List<string> lines = new List<string>();
Regex corrupt = new Regex("£$**");
if (File.Exists(path))
{
using (StreamReader reader = new StreamReader(path))
{
string line;
while ((line = reader.ReadLine()) != null)
{
if (!corrupt.IsMatch(line))
{
lines.Add(line);
}
}
}
using (StreamWriter writer = new StreamWriter(newpath, false))
{
foreach (String line in lines)
writer.WriteLine(line);
}
}
}
I have a function which runs to insert a filename and a part number into a table. however the filename which gets inserted includes the whole directory e.g. c:\:folder\uploads\xml\file.xml
I would like just file.xml
string source = System.Web.HttpContext.Current.Server.MapPath("/uploads/xml/");
part retrun = null;
string[] fileEntries = Directory.GetFiles(source);
foreach (string fileName in fileEntries)
{
XmlSerializer serializer = new XmlSerializer(typeof(file));
Stream reader = new FileStream(fileName, FileMode.Open);
file f = (file)serializer.Deserialize(reader);
string part = "";
foreach (part p in f.#class.part)
{
part = p.tcpn.ToString();
XMLProductQueries.InsertIntoXMLProducts(context, fileName, part);
}
reader.Close();
}
help?
Use Path.GetFileName(fileName) to extract the file name from your path.
Path.GetFileName(#"c:\:folder\uploads\xml\file.xml") // => returns file.xml
I have a web page on which users can upload text files (but a text file, i.e. a file with the extension .txt, could be of many encodings, e.g. ASCII, UTF8, UNICODE .. etc), I'm trying to validate the contents in memory before I save the file to the disk, if the content is not valid, I don't save the file. I'm reading the content from the file upload control (fileUpload1.FileContent which returns a stream of bytes), is there an easy way in .NET to convert the content of the uploaded file to a string (i.e. the byte stream returned from fileUpload1.FileContent) or will I have to check the first bytes to detect the encoding first?
Thanks
I think you can do this:
StreamReader reader = new StreamReader(fileUpload1.FileContent);
string text = reader.ReadToEnd();
Example of text file format
Code#Name#Fathername#DOB#Location#MobileNo
1#XYZ#YYY#09-06-89#LKO#9999999999
protected void btnUpload_click(object sender, EventArgs e)
{
if (Page.IsValid)
{
bool logval = true;
if (logval == true)
{
if (fuUploadExcelName.HasFile)
{
String img_1 = fuUploadExcelName.PostedFile.FileName;
String img_2 = System.IO.Path.GetFileName(img_1);
string extn = System.IO.Path.GetExtension(img_1);
string frstfilenamepart = "Text" + DateTime.Now.ToString("ddMMyyyyhhmmss");/*Filename for storing in Desired path*/
UploadExcelName.Value = frstfilenamepart + extn;
fuUploadExcelName.SaveAs(Server.MapPath("~/Text/") + "/" + UploadExcelName.Value);/*Uploaded text file will be store at this path*/
string filename = UploadExcelName.Value;
string filePath = Server.MapPath("~/Text/" + filename);
StreamReader file = new StreamReader(filePath);
string[] ColumnNames = file.ReadLine().Split('#');/*read data from textfile*/
DataTable dt = new DataTable();
foreach (string Column in ColumnNames)
{
dt.Columns.Add(Column);/*adding the columns/
}
string NewLine;
while ((NewLine = file.ReadLine()) != null)
{
DataRow dr = dt.NewRow();
string[] values = NewLine.Split('#');
for (int i = 0; i < values.Length; i++)
{
dr[i] = values[i].TrimEnd();
}
dt.Rows.Add(dr);
}
file.Close();
grdview.DataSource = dt;/*make datasouce from text file*
grdview.DataBind();/*binding the grid*/
}
}
}
}