Reading A Fixed Format Text File - c#

Its been years since I have had to attempt to read a file using either Microsoft Text ODBC Driver or Microsoft Jet OLE DB 4.0 Provider.
So I have the following code
public void Example()
{
string CVS = Application.StartupPath;
string SQL = "SELECT * FROM [MyFile.txt]";
string Connection = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source="+CVS+";"+"Extended Properties='text;HDR=Yes;FMT=Fixed;";
OleDbDataAdapter OLE = new OleDbDataAdapter(SQL,Connection);
DataTable Table = new DataTable();
OLE.Fill(Table);
}
When I run the above code I get an "Unexpected Error", I know I am missing something, I am not sure what exactly.
Sources:
http://www.connectionstrings.com/textfile
http://www.connectionstrings.com/Providers/net-framework-data-provider-for-ole-db
http://www.aspdotnetcodes.com/Importing_CSV_Database_Schema.ini.aspx
Any direction would be appreciated.
Let us assume the Schema.ini file is correct.

Remove ' (just prior to 'text;) from the connection string.
In order to resolve the "Could not find installable ISAM", run the following command:
Regsvr32 c:\winnt\system32\mstext40.dll
* Make sure that file is in that folder first. And change WINNT to whatever your windows directory is.

I know this is not a real answer to your question, but i would really rethink about using this architecture to read in a file.
I would really prefer something like CSV Reader, cause it gives you much more power about how the data will be interpreted. Alternative you could also take a look into the FileHelpers.

Related

C# OleDb Connection to mdb File with changed character set to UTF8

i have a problem to change Character set to UTF8 when i ma connecting to my mdb file.
I can connect to this, the only problem is it has some š,ž,č etc. characters in it. So i wanted to change character set in my connectionString to UTF8.
My connectionString looks like this:
string conectionString = "Provider=Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\mydatabase.mdb;";
This connection string will connect me just fine. But when i add this:
string conectionString = "Provider=Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\mydatabase.mdb;Extended properties='Character set=UTF8;'";
it will throw an error : Could not find installable isam. I was trying to find more about it but only thig that i found was about single quotes.
I know there is a lot of questions about this but I go through a lot of them.
Thanks for any help.
I Know that this is too late, but for the people that want to know the answer.
I'm using some more for the Extend Properties, I rescue it from ChatGPT but I add the knowledge that I got.
For your location, has to be the folder that contains your file, after you can do a query like "SELECT * FROM [/Name of your file with extention/]"
The correct format to the connection would be Provider=Microsoft.Jet.OLEDB.4.0;Data Source=/*Your location*/;Extend Properties="text;HDR=Yes;FMT=Delimited;'CharacterSet=65001'"
In your string variable, you can use:
string connectionString= $#"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={/*Your location*/};Extended Properties=""text;HDR=Yes;FMT=Delimited;'CharacterSet=65001'""";
I'm using the template string and the # for get the scape of '"'

I cant open sqlite database

I am required to get sqlitedb in located here
C:\Users\xxx\AppData\Local\Mozilla\Firefox\Profiles\zxl8ocql.default.places.sqlite.
The following code works while accessing Google Chrome data:
private const string PathToChromeData = #"\Google\Chrome\User Data\Default\History";
private const string PathToFirefoxData = #"\Mozilla\Firefox\Profiles\zxl8ocql.default\places.sqlite";
string pathh = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), PathToFirefoxData);
using (SQLiteConnection connection = new SQLiteConnection("Data Source=" + pathh + ";Version=3;New=False;;"))
{
connection.Open();
SQLiteDataAdapter adapter = new SQLiteDataAdapter("Select * from moz_places", connection);
DataSet ds = new DataSet();
adapter.Fill(ds);
dataGridView1.DataSource = ds.Tables[0];
So I slightly changed it for getting Firefox data. However I am getting this exception:
unable to open database file
Then I have checked few similar threads on SO. And realized that Firefox locks this database while its running. And I closed the Firefox even changed the location of database. I checked the connection string, but it seems correct. What is wrong here?
You got a size of 0 KB, because you are searching the history file in the wrong directory.
Replace Local with Roaming and you will get the original places.sqlite file.
The new path would be
C:\Users\xxx\AppData\Roaming\Mozilla\Firefox\Profiles\zxl8ocql.default\places.sqli‌​te.
Why you found a db of 0 KB in Local?
When you try to open a db file with API, if file does not exist it will create a new empty file. That is why you found a 0 KB sqlite file in local.
Well I am also getting the same issue as described above.
I am looking in to it. I will post a solution if I got.
I am glad that I figured it out and fixed it.
The problem was with the sql version; db was created with a higher version and I was trying to open it with a lower version of sqlite.
It should be handled and at least they should display a proper message.
To open firefox db you require sqlite version 3.8.x.

Read Excel file with OleDB c#, when it is used by other process

I am trying to read an excel file every 2 seconds, This file is getting updated by other RTD application.
I am able to read this file by Oledb connection, but problem comes when i am trying to read it every 2 seconds. Out of 10 attempts it is able to read 4-5 times only and at other attempts ,it throws exception.
Connection String
Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\nids\shes.xlsm;Extended Properties="Excel 12.0 Macro;HDR=Yes;IMEX=1"
Code
//opening connection to excel file
using (OleDbConnection connection = new OleDbConnection(constr))//constr = connection string
{
try
{
connection.Open();
isconopen = true;
}
catch
{
dispatcherTimer2.Start();
connection.Close();
isconopen = false;
}
// If connection is ok , then query sheet
if (isconopen == true)
{
strcon = "SELECT * FROM [" + dsheet + "]";
using (OleDbDataAdapter adapter = new OleDbDataAdapter(strcon, connection))
{
try
{
adapter.Fill(result);
isread = true;
adapter.Dispose();
connection.Close();
}
catch
{
isread = false;
dispatcherTimer2.Start();
adapter.Dispose();
connection.Close();
}
}
}
//if able to retrieve data then call some other function
if (isread == true)
{
converToCSV(0);// for further processing
}
Please help me , i am trying this from last 1 month. Please please please please help me out
Sadly OleDB driver by default will open file exclusively then you can't open it when it's in use by someone else, even just for reading.
Two considerations:
Other application may finalize its work with the file within milliseconds so it's good to try again
Driver will always open file locked for writing (so you can't open it twice via OleDB) but it's shared for reading (so you can copy it).
That said I suggest you should first try to open it after a short pause, if it's still in use (and you can't wait more) then you can make a copy and open that.
Let me assume you have your code in a HandlExcelFile() function:
void HandleExcelFile(string path)
{
try
{
// Function will perform actual work
HandleExcelFileCore(path);
}
catch (Exception) // Be more specific
{
Thread.Sleep(100); // Arbitrary
try
{
HandleExcelFileCore(path);
}
catch (Exception)
{
string tempPath = Path.GetTempFileName();
File.Copy(path, tempPath);
try
{
HandleExcelFileCore(tempPath);
}
finally
{
File.Delete(tempPath);
}
}
}
}
Code is little bit ugly so just consider it a starting point to write your own function.
Considerations:
Retry isn't such bad thing and it's a common way to solve this kind of problems. It's, for example, what Windows shell does (and it's even more normal with networks).
If application didn't close the file then you may copy (and read) old data. If you always need most up-to-date data then you have only one choice: wait. If you can assume that unsaved data belongs to the previous time frame (T - 1, as in digital electronic when signal edge is on clock edge) then just do it and live happy.
Untested solution:
I didn't try this so you have to do it by yourself. Actuallly (I was initially wrong) you can open a read-only connection (through extended properties). It's not documented if this apply to connection only or both file handle and connection. Anyway let's try to change your connection string to:
Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\nids\shes.xlsm;Extended Properties="Excel 12.0 Macro;HDR=Yes;IMEX=1;ReadOnly=true"
Just added a ReadOnly=true at the end of Extended Properties.
Other solutions:
The only alternative solution that comes to my mind is to...manually read Excel file (so you can open it just for reading). That said even in this case the other application may have not written new data (so you'll read old one).
Don't use a timer at all. Change your design to use a FileSystemWatcher, you'll read the file only when notified it has been changed.
When applicable...just do not use a shared file as IPC mechanism! Well, you may not be able to change 2nd application so this may not be your case.
Do not use OleDB to read Microsoft Excel files, there are many 3rd part free libraries that don't open file with exclusive lock, for example this one.
Do not read data directly from files, if Microsoft Excel instance is always running you can use COM interop to get notifications. Check this general article about COM add-ins and this to see how you can attach your C# application with Office Interop to an existing Microsoft Excel instance.
Not sure , why do you want to read the excel the way you are doing.
You can try LinqToExcel for excel reading , its a nice little library for reading excel files also if you need to create excel then try to EPPLUS library. These library i personally found really effective when working with Excels
I had similar problem. Below fixes worked for me
1) Don't hold your connection to sheet. Instead open connection read data and close the connection immediately.
2) If you are using managed code in the unmanaged application then consider using object of managed type instead of pointer(using gcnew) and use Stack Semantics to make sure that memory is cleaned up when object goes out of scope.

OledDbDataAdapter "Syntax error in FROM clause" exception

I'm using OleDB to import data into grid from text file with extension ".K$$".
Here's some example code:
FileInfo file = new FileInfo(filename);
string connectionString = "";
OleDbDataAdapter adapter;
OleDbConnection con;
connectionString = "Provider=Microsoft.Jet.OleDb.4.0;Data Source=" + file.DirectoryName + ";Extended Properties=\"Text;Format=TabDelimited;\"";
con = new OleDbConnection(connectionString);
con.Open();
adapter = new OleDbDataAdapter(String.Format("SELECT * FROM {0} ", file.Name), con);
adapter.Fill(MyDataTable);
when executing the Fill method it throws the exception. What's wrong with the FROM clause? Thanks
EDIT:
Ok, after some tests I found out that the problem is with the "$" symbols. Maybe it's some reserved symbol ?
Also, if I rename the extension to ".txt" the file got loaded into the grid but it only have 1 column , which means it can't see that there're tabs in the rows.
Another issue is that when I change the file extension to something different than ".txt" (for ex. ".tx") the Fill method throws exception "Cannot update. Database or object is read-only".
OK, I just tried creating an example.K$$, and then tried to connect to it using the same provider as stated through Server Explorer in Visual Studio 2010. Its an Unrecognised format.
I don't think this will ever work.
You may need to look at connecting via a different provider or method.
I think You should look at this link :-
EDIT :
http://www.codeproject.com/Articles/6737/Fill-a-DataSet-from-delimited-text-files
It will allow you to read your txt file into a datable correctly.
Try checking the path of the filename if its correct
Check that neither the directory, nor the filename, contain spaces. If they do, you'll need to escape/quote them.
You'll also need to quote the filename if it contains an extension since the . is not a valid character in the FROM clause. Try FROM [{0}] (though this may not be the correct quoting character for the OleDbDataAdapter).

Can a .csv file be used as a data source in Visual Studio 2008?

I'm pretty new to C# and Visual Studio. I'm writing a small program that will read a .csv file and then write the records read to a SQL Server database table.
I can manually parse the .csv file, but I was wondering if it is possible to somehow "describe" the .csv file to Visual Studio so that I can use it as a data source? I should mention that the first two lines in the .csv file contain header information and the following lines are the actual comma-delimited data.
Also, I should mention that this program is a stand-alone console program with no user interface.
This is a great example of using the power of LINQ. Here's a quick reference with an example of how to do it.
The run down is this. You can read in your CSV to a string array, then use LINQ to query against that collection. As Reed points out though, you'll have to code around your header line, as it will throw off your query.
You can also use the TextFieldParser too to handle escaping commas. Here's an example on thinqlinq that uses the TextFieldParser to parse the file, and a LINQ query to get the results. It even has a unit test to make sure escaped commas are handled.
If you have a 2 line header, it's not a standard CSV file.
In this case, the automatic tools won't work, and you'll have to revert to parsing the file manually.
If you want to remove one of the header lines, you might be able to use this technique of parsing CSV files into an ADO.NET DataTable.
If not, however, the TextFieldParser in the Microsoft.VisualBasic.dll assembly (usable from C# too) makes parsing CSV files very simple.
To parse it manually is very simple, and you could have a program that parses it, strips out the first two unnecessary lines and then feeds it directly to SSIS.
Here is a link for using LINQ to read it in:
http://blogs.msdn.com/wriju/archive/2009/05/24/linq-to-csv-getting-data-the-way-you-want.aspx
Using The Built In OLEDB CSV Parser via C# in order to parse a CVS file.
You can find a sample here
It basically lets you treat the csv file like a database table.
The link in Development 4.0's post has dissapeared. The code in that link was the following:
class CSVParser
{
public static DataTable ParseCSV(string path)
{
if (!File.Exists(path))
return null;
string full = Path.GetFullPath(path);
string file = Path.GetFileName(full);
string dir = Path.GetDirectoryName(full);
//create the "database" connection string
string connString = "Provider=Microsoft.Jet.OLEDB.4.0;"
+ "Data Source=\"" + dir + "\\\";"
+ "Extended Properties=\"text;HDR=No;FMT=Delimited\"";
//create the database query
string query = "SELECT * FROM " + file;
//create a DataTable to hold the query results
DataTable dTable = new DataTable();
//create an OleDbDataAdapter to execute the query
OleDbDataAdapter dAdapter = new OleDbDataAdapter(query, connString);
try
{
//fill the DataTable
dAdapter.Fill(dTable);
}
catch (InvalidOperationException /*e*/)
{ }
dAdapter.Dispose();
return dTable;
}
}
}

Categories