I had a webservice that reads .txt files using StreamReader and sends back responses to the user. If multiple people call my webservice, will the .txt files be "locked" and thus only be able to handle processing one request at a time?
Thanks.
Files are not locked during reads using streamreader.
I think this depends. Are any changes being made to the text file? If not, then the file should not be locked, because once it is opened, it should be read into the stream using a stremreader object, and then closed. Refer to
How do I open an already opened file with a .net StreamReader?
and
http://msdn.microsoft.com/en-us/library/db5x7c0d.aspx
This code creates a StreamReader that points to MyFile.txt through a
call to File.OpenText. StreamReader.ReadLine returns each line as a
string. When there are no more characters to read, a message is
displayed to that effect, and the stream is closed.
Related
I want to read the content of a file which is opened (and locked?) by a other process.
I tried it with File.ReadAllText() and with new StreamReader(new FileStream(path, FileMode.Open, FileAccess.Read)) but both methods trigger a IOException.
For example I can open the file with Notepad++ and the content is shown so I think it must be possible too with c#.
You need to use the FileStream constructor overload that takes a FileShare argument. And pass FileShare.ReadWrite. You can only open the file if you permit write access since the other program already acquired that right. Otherwise the reason that your attempts failed so far, they used FileShare.Read. Can't work, you cannot deny write access because the other program already got that.
Dealing with the program writing to the file while you are reading it is entirely up to you. Results can be quite random. Anything is possible, but in general for a log file you'll get a partially written last line that's trailing behind the actual output of the program, some of which is still in the program's file buffer. A buffer size of 4096 bytes is a common choice.
We have a very old file delivery application(IPGear, if you have heard about it, written in tcl). We upload our IP files there and our customers download it from the system.
When you upload a file to this application, it adds .RCA extension to uploaded file and add some metadata to file. if we view the content of any file in a text editor(Usually tgz, pdf and text files), we see some metadata added to the top of the file by the application(5-10 lines, readable).
If you download a file from the system, they somehow strip this metadata from the file and returns as TGZ file which works fine(we can extract it)
if we find that RCA file on the storage where this application keeps files and edit the metadata they have added via text editor, we are able to extract the file without any problem., which fine too. But we need to do this process for 22K files, therefore we need to script it.
We are able to find the bits the application adds by opening via StreamReader, and strip the metadata and write file to the disk via StreamWriter. However, the file we write to the system is corrupted if it is TGZ file. if we do same thing for text files, they work.
the content of the tgz file looks below when we open in text editor
The bits on lines 29-38 are the metadata we strip.
it looks like the streamreader is not able to write this content back to disk even if we tried different encoding settings.
One another note about this is that the file we are trying to read and write is copied from a Solaris based server into local machine(Windows 7) via WinSCP.
So, my question is, what is the best way of reading TGZ file into memory(as text) so manipulation, and save back without corruption? is streamreader and streamwriter not good for this purpose?
I tried to give as much information as I can, please add comments if you need more clarification.
it looks like the streamreader is not able to write this content back to disk even if we tried different encoding settings.
Yes, because a tgz file isn't plain text. StreamReader and StreamWriter are for text content, not arbitrary binary content.
So, my question is, what is the best way of reading TGZ file into memory(as text)
You don't. You read it as binary data, because it is binary data.
If the TGZ archive contains text files, you'll need to decompress the TGZ to the TAR format, then extract the relevant data from that. Then you can work with it as text. Before that point, it's just binary data.
But it sounds like you actually may just want to read text information before the TGZ file... in which case you need to work out where that text information ends, and not read any of the TGZ file as text (because it's not). This is non-trivial, but if you know that the text is in ASCII it'll be a bit easier - you will need to work out how to detect the end of the text and the start of the real content though, and we can't really tell that from the screenshot you've given.
I have a program that logs it's progress and other data to an XML file. I want to be able to open this XML file without blocking out the writer program (not a .NET program, and I have no control over it), and to read the XML as it comes, waiting for more when it is all processed, until the EOF is received.
How can this be achieved in C#?
Note that there are 2 problems:
Keeping a reading stream open without blocking the other process.
Knowing when there is more input and waiting when there isn't.
If I needed to do this I would do something like the following:
Use a FileSystemWatcher to get notified when the file changes. Then just read the file and parse the XML as you require.
I would go down this route as it will be difficult to read the stream as and when the external application writes to the file.
I did soemthing similar in past yielding in an OS program called Tailf.
Just check the code if you want to do it yourself, or grab all from it, it should almost work for you as well, a part the fact I just care about text files.
You can open a file stream without locking it by passing in the following flags:
new FileStream(logFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
As far as waiting for the "EOF", if the other program is only writing data intermittently, you may have to put some sort of heuristics into your progress (ie. stop peeking for new data only if there's nothing new for X minutes).
How do i open a StreamReader with FILE_SHARE_READ, FILE_SHARE_WRITE, FILE_SHARE_DELETE?
Same question, slightly expanded
How do i open a StreamReader so that i can read an encoded text file, with sharing options so that another process can read the file?
How do i open a StreamReader so that i can read an encoded text file, with sharing options so that another process can modify the file while i'm reading it?
How do i open a StreamReader so that i can read an encoded text file, with sharing options so that another process can delete the file while i'm reading it?
Same question, slightly more expanded
In the .NET Framework class library there is a class called StreamReader. It is the only class designed to read "text", which is why it descends from the abstract base TextReader class. The TextReader/StreamReader allows you to specify the encoding used by the file you are trying to open, and can decode the file for you, returning Strings of text.
Once i've opened a file with the StreamReader:
var sr = new StreamReader(path);
The file is locked, with other processes unable to modify or delete the file. What i need is the equivalent of a FileStream class's FileShare enumeration:
None: Declines sharing of the current file. Any request to open the file (by this process or another process) will fail until the file is closed.
Read": Allows subsequent opening of the file for reading. If this flag is not specified, any request to open the file for reading (by this process or another process) will fail until the file is closed. However, even if this flag is specified, additional permissions might still be needed to access the file.
Write: Allows subsequent opening of the file for writing. If this flag is not specified, any request to open the file for writing (by this process or another process) will fail until the file is closed. However, even if this flag is specified, additional permissions might still be needed to access the file.
ReadWrite:Allows subsequent opening of the file for reading or writing. If this flag is not specified, any request to open the file for reading or writing (by this process or another process) will fail until the file is closed. However, even if this flag is specified, additional permissions might still be needed to access the file.
Delete: Allows subsequent deleting of a file.
Except that, for obvious reasons, i cannot use a FileStream - have to use a StreamReader.
How can i open a StreamReader with FileShare.ReadWrite | FileShare.Delete?
StreamReader has a constructor that can take a stream. So instead of using the constructor that takes a string path, first create a FileStream with the options that you want, then pass that FileStream to the StreamReader constructor.
How can i open a StreamReader with FileShare.ReadWrite | FileShare.Delete ?
When you have solved the problem for a Stream, the Reader is easy:
var fs = new FileStream(fileName, FileMode.Open, FileShare.ReadWrite|FileShare.Delete);
var sr = new StreamReader(fs);
And of course that should be wrapped in a using() { } block.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
how to delete a file?
My application first reads the fields in windows form and then creates a csv file and writes all the fields values in the csv format in it. Then my application reads the csv file and uses it for its further processing. My requirement is that after my application has read the csv file, the file should automatically get deleted(security reasons).
How can i do the above using c# code.
You can use System.IO.File.Delete(FilePath), where FilePath is the file you would like to delete.
Documentation on this
If you concerned about security, perhaps you should look into some alternatives to temporarily writing the data to a file on disk.
Call the System.IO.File.Delete() method, and specify the path to the CSV file as the parameter.
Did you try googling ".NET delete file"? It very quickly points you to System.IO.File.Delete.
Another options besides the System.IO.File.Delete method is to open the file with a special flag. Delete can fail if the file is still in use by another program (or your code, but let's hope not) that hasn't given FileShare.Delete permissions.
An example:
using(var fs = new FileStream(pathToFile, FileMode.Open,
FileAccess.Read, FileShare.None,
1024, FileOptions.DeleteOnClose))
{
// do stuff here
}
// file *may* be deleted here if there are no other
// handles to the file, otherwise it will be deleted
// when all other handles to it are closed, or on
// system restart
That should guarantee that the file gets deleted, if you're expecting other programs to hold handles to the file. If not, it's easier to just use File.Delete.