Error opening streamreader because file is used by another process - asp.net

I am developing an application to read an excel spreadsheet, validate the data and then map it to a sql table. The process is to read the file via a streamreader, validate the data, manually make corrections to the excel spreadsheet, validate again -- repeat this process until all data validates.
If the excel spreadsheet is open, then when I attempt to read the data via a streamreader I get an error, "The process cannot access the file ... because it is being used by another process." Is there a way to remove the lock or otherwise read the data into a streamreader without having to open and close excel each time?

When you call File.Open to get the stream are you using the overload that allows you to specify FileAccess?
http://msdn.microsoft.com/en-us/library/y973b725.aspx
Note the parameters:
public static FileStream Open(
string path,
FileMode mode,
FileAccess access,
FileShare share
)
You can pass FileAccess.Read to the third param to indicate you only need read-only access. You should also set FileShare.Read to allow others to open the file read-only instead of locking it yourself. Note that if MS Excel opens the file with FileShare.None, you probably wont be able to access it.

Related

Replacing SQLite database while accessing it

I am completely new to SQLite and I intend to use it in a M2M / client-server environment where a database is generated on the server, sent to the client as a file and used on the client for data lookup.
The question is: can I replace the whole database file while the client is using it at the same time?
The question may sound silly but the client is a Linux thin client and to replace the database file a temporary file would be renamed to the final file name. In Linux, a program which has still open the older version of the file will still access the older data since the old file is preserved by the OS until all file handles have been closed. Only new open()s will access the new version of the file.
So, in short:
client randomly accesses the SQLite database
a new version of the database is received from the server and written to a temporary file
the temporary file is renamed to the SQLite database file
I know it is a very specific question, but maybe someone can tell me if this would be a problem for SQLite or if there are similar methods to replace a database while the client is running. I do not want to send a bunch of SQL statements from the server to the client to update the database.
No, you cannot just replace an open SQLite3 DB file. SQLite will keep using the same file descriptor (or handle in Windows-speak), unless you close and re-open your database. More specifically:
Deleting and replacing an open file is either useless (Linux) or impossible (Windows). SQLite will never get to see the contents of the new file at all.
Overwriting an SQLite3 DB file is a recipe for data corruption. From the SQLite3 documentation:
Likewise, if a rogue process opens a
database file or journal and writes
malformed data into the middle of it,
then the database will become corrupt.
Arbitrarily overwriting the contents of the DB file can cause a whole pile of issues:
If you are very lucky it will just cause DB errors, forcing you to reopen the database anyway.
Depending on how you use the data, your application might just crash and burn.
Your application may try to apply an existing journal on the new file. Sounds painful? It is!
If you are really unlucky, the user will just get back invalid results from any queries.
The best way to deal with this would be a proper client-server implementation where the client DB file is updated from data coming from the server. In the long run that would allow for far more flexibility, while also reducing the bandwidth requirements by sending updates, rather than the whole file.
If that is not possible, you should update the client DB file in three discrete steps:
Send a message to the client application to close the DB. This allows the application to commit any changes, remove any journal files and clean-up its internal state.
Replace/Overwrite the file.
Send a message to the client application to re-open the DB. You would have to setup all prepared statements again, though.
If you do not want to close the DB file for some reason, then you should have your application - or even a separate process - update the original DB file using the new file as input. The SQLite3 backup API might be of interest to you in that case.

Lock on XDocument.Save for multiple ASP.NET pages

Is it possible to use a lock on one xml file that can potentially be written to from multiple aspx pages at the same time?
I'm asking because MSDN suggest that the lock statement should be used with a private static object instance as the expression, and since there are multiple pages involved i guess i can't use the same object on all the pages?
You can use the File.Open overload that takes a FileShare enum that is set to None. No other thread will be able to open the file until closed.
FileStream fs = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.None);
This piece of code will open the (existing) file specified in the path argument, for reading and without any sharing.

Audio Cutter in Silverlight

1.
I have created a audio player in silverlight.
within that player user is able to select a portion of song to save as ringtone.
but i got the time duration from .. but I have to cut the partial portion of stream or audio stream and save it to the server dick.
Plz suggest me how I can convert the selected audio time duration into the stream or byte array..?
-- Additional information on this question:
2.
I have created a ringtone audio player in silverlight. Within that user can select a portion which can be cut and save as a audio file.
I am unable to save the stream to the disk.. it is giving following errors:
Error 1. Attempt to access the method failed System IO FileInfo OpenWrite
Plz help
-- Additional information on this question:
3.
What are the use of MediaStreamSample & MediaStreamSource class in silverlight with respect to MediaElement?
Will it help in cutting a portion of audio file in order to create the ringtone out of a song?
If you need to save to the server, then you need to get that data to the server.
Just saving it (as answered) will try to save to the client's machine. What you need to do is upload the data to the server either via a WCF service or an ASHX handler or such. I've done something similar -- uploading MP3 files from a Silverlight client to a WCF service via a Stream, works well.
Next: You need to make sure that whatever splitting process you use accommodates the audio format-- ie you probably just can't split the binary file. What format are you using, mp3?
I've used something called mp3plt, before to split mp3s. You may be able to recompile the source into a Silverlight-compatible library, assuming it's written in something you can use, source here.
Or you can look into the mp3 specs to see if it is possible to just split the binary file, in which case taking the duration to cut (the one the user chose), and multiplying by the bitrate, (kb/s * seconds = kb) will give you the place in the file byte[] you can cut at.
Error 1. Attempt to access the method failed System IO FileInfo OpenWrit, you getting this error coz of security reasons. Before saving to disk you should promt SaveFileDialog to user, and then only save file to disk.

Using an encrypted file securely

I'm writing an application with a dBASE database file in Borland Delphi 7.
Note: I think this question is file-security related and you can forget the dBASE thing (consider it as a TXT file) in this question.
The database must be accessed just by the application. Then it must be encrypted. Unfortunately dBASE doesn't support any password mechanism and i had to encrypt the file by myself (and i also HAVE to use dBASE)
What approach do you suggest to secure the database file?
The simple one is:
Encrypting the database file and placing it near beside the application EXE file.
When the application runs, it should decrypt the file (with a hard-coded password) and copy the result to a temporary file that has DeleteOnClose and NoSharingPermission flags.
When Closing, application should encrypt the temp dBASE file and replaces the old encrypted file with the new one.
I think this is a fair secure approach. But it have two big problems:
With an undelete tool the user can restore and access to the deleted temp file.
Worse: When application is running, if the system rebooted suddenly the DeleteOnClose flag fails and the temp file remains on hard disk and user can access it.
Is there any solution for, at least, the second part?
Is there any other solution?
You could also try to create a TrueCrypt file-based containter, mount it, and then put the dBase file inside the mounted encrypted volume. TrueCrypt is free (in both senses) and it's accessible via command line parameters from your application (mount before start, unmount before quit).
Depending on what you're doing with the database, you may be able to get away with just decrypting the records you actually need. For example, you could build indexes based on hash codes (rather than real data); this would reduce seeks into the database to a smaller set of data. Each record in the subset would have to be decrypted, but this could be a lot better than decrypting the entire database.

storing files as byte array in db, security risk?

We have an asp.net application that allows users to upload files, the files are saved to temporary disk location and later attached to a record and saved in DB.
My question pertains to security and/or virus issues. Are there any security holes in this approach? Can a virus cause harm if it is never executed (file is saved, then opened using filestream, converted to byte array and saved to DB.
Later, when the file is needed we stream the file back to user.
The files are saved to a folder on the web server like this:
context.Request.Files[0].SaveAs(); (location is a folder under app_data/files)
later when the same user creates a record we grab the file from disk and store it in db like this:
FileStream fileStream = File.OpenRead(currentFilePath);
byte[] ba = new byte[fileStream.Length];
int len = fileStream.Read(ba, 0, ba.Length);
//ba saved to DB here as varbinary(max)
We limit the files that can be uploaded to this list:
List<string> supportedExtensions = new List<string>(10) {".txt", ".xls", ".xlsx", ".doc", ".docx", ".eps", ".jpg", ".jpeg", ".gif", ".png", ".bmp", ".rar", ".zip", ".rtf", ".csv", ".psd", ".pdf" };
The file is streamed back to user's web browser like this:
//emA = entity object loaded from DB
context.Response.AppendHeader("Content-Disposition", "inline; filename=\"" + emA.FileName + "\"");
context.Response.AddHeader("Content-Type", emA.ContentType);
context.Response.BinaryWrite(emA.FileContent);
There's always a security risk when accepting files from unknown users. Anyone could potentially write a virus in VBA (Visual Basic for Applications) in the office documents.
Your approach is no more or less of a security risk than saving them directly on the file system or directly in the database except for one concern...
If the files are saved to the disk, they can be scanned by traditional virus scanners. As far as I know most virus scanners don't scan files that are stored in a DB as a byte array.
If it were my server, I would be storing them on the file system for performance reasons, not security reasons, and you can bet I would have them scanned by a virus scanner if I were allowing potentially dangerous files, such as office documents, executables, etc.
Have your users create logins before allowing them to upload files. Unchecked access of this kind is unheard of... not saying that this is a solution in and of itself, but like all good security systems it can form an extra layer :-)
I can't see there being anymore security risk than saving the files to disk. The risks here are often not to do with where you store the data since as you've already pointed out the stored file doesn't get executred.
The risk is usually in how the data is transfered. Worms will exploit circumstances which allow what was just data on its way through the system to be treat as if it were code and start being executed. Such exploits do not require that any sense of "file" being transfered be present, in the past a specially formatted URL could suffice.
That said, I've never understood the desire to store large binary data in a SQL database. Why not just save the files on disk and store the file path in the DB. You can then use features such as WriteFile or URL re-writing to get IIS do what its good at.

Resources