Accessing files in c#

  • Thread starter Thread starter FerrisUML
  • Start date Start date
F

FerrisUML

Im writing a small web application and what I'd like to do is open a
file, read the contents into memory and then close the file as fast as
I can to free up the file for the next user. Once the file is loaded
into memory and subsequently closed, i would use the contents of the
file (now loaded into memory) to perform some quick processing. Any
idea how best to do this?

Thanks in advance for your help!
 
Im writing a small web application and what I'd like to do is open a
file, read the contents into memory and then close the file as fast as
I can to free up the file for the next user. Once the file is loaded
into memory and subsequently closed, i would use the contents of the
file (now loaded into memory) to perform some quick processing. Any
idea how best to do this?

Assuming your files are small enough to easily fit in memory, it seems to
me that you could just check the file size, allocate a byte array long
enough to hold the data, then open the file with FileStream, read the
entire file into the byte array in a single call to FileStream.Read(), and
then close the file.

Caveat: a FileStream implementation is not actually required to read as
many bytes as you ask it to. So you should put the call to Read() into a
loop, iteratively reading whatever it will allow you to until it's all
done. For example:

byte[] rgb = ...;

using (FileStream stream = ...)
{
int cbLeft = stream.Length;

while (cbLeft > 0)
{
cbLeft -= stream.Read(rgb, stream.Length - cbLeft, cbLeft);
}
}

In most cases, I believe that Read() will only be called once and it will
read the entire file in one shot. But this will handle those cases when,
for whatever reason, you don't get all the data the first call to Read()..

Depending on how you're going to use the data, you can then optionally
instantiate a MemoryStream from the byte array, so that you still have
stream-based access to the data (which you could then pass to a
StreamReader, for example, if you wanted to process text).

Pete
 
Hi FerrisUML,

Opening, closing files are done using System.IO.File. Storing the content
in memory can be done in any number of ways, like string, byte[] or
MemoryStream.

As for doing this in web applications you need to be aware of restrictions
for accessing the file system, which by default is limited to the web
application root folder and its subfolders.

If you need to access other folders, either open up for this folder/file by
adding read/write permissions to aspnet, or change the account used to run
the web application to something that has access to the file
 
Peter Duniho said:
Caveat: a FileStream implementation is not actually required to read as
many bytes as you ask it to. So you should put the call to Read() into a
loop, iteratively reading whatever it will allow you to until it's all
done. For example:

byte[] rgb = ...;

using (FileStream stream = ...)
{
int cbLeft = stream.Length;

while (cbLeft > 0)
{
cbLeft -= stream.Read(rgb, stream.Length - cbLeft, cbLeft);
}
}

I'd go beyond that - I'd keep reading regardless of the file's original
length:

http://pobox.com/~skeet/csharp/readbinary.html
 
Im writing a small web application and what I'd like to do is open a
file, read the contents into memory and then close the file as fast as
I can to free up the file for the next user. Once the file is loaded
into memory and subsequently closed, i would use the contents of the
file (now loaded into memory) to perform some quick processing. Any
idea how best to do this?

Assuming your files are small enough to easily fit in memory, it seems to
me that you could just check the file size, allocate a byte array long
enough to hold the data, then open the file with FileStream, read the
entire file into the byte array in a single call to FileStream.Read(), and
then close the file.

Caveat: a FileStream implementation is not actually required to read as
many bytes as you ask it to. So you should put the call to Read() into a
loop, iteratively reading whatever it will allow you to until it's all
done. For example:

byte[] rgb = ...;

using (FileStream stream = ...)
{
int cbLeft = stream.Length;

while (cbLeft > 0)
{
cbLeft -= stream.Read(rgb, stream.Length - cbLeft, cbLeft);
}
}

In most cases, I believe that Read() will only be called once and it will
read the entire file in one shot. But this will handle those cases when,
for whatever reason, you don't get all the data the first call to Read().

Depending on how you're going to use the data, you can then optionally
instantiate a MemoryStream from the byte array, so that you still have
stream-based access to the data (which you could then pass to a
StreamReader, for example, if you wanted to process text).

Pete


Using a filestream has another advantage, you can open it
readonly/share-read so that other processes can also open it the same way,
making the locking issue completely go away.

Mike.
 
I'd go beyond that - I'd keep reading regardless of the file's original
length:

http://pobox.com/~skeet/csharp/readbinary.html

I don't know about that. The OP suggested he wants to read the file as
fast as possible. To me, this means not performing any allocations or
other "optional" work while the file is actually open. Making the code
flexible enough to deal with an indetermine file length means introducing
potential overhead.

There is also the implication, though he doesn't state it explicitly, that
the files have been completely written as of the moment he wants to
process them. So coding that flexibility might not be needed in any case.

Pete
 
Using a filestream has another advantage, you can open it
readonly/share-read so that other processes can also open it the same
way, making the locking issue completely go away.

Agreed. I took it as implied that for some reason the OP needed sole
access to the file at the moment he's reading/processing it. But yes, if
you can change the original problem definition, there are better ways to
deal with this than reading the whole file into memory all at once.

Pete
 
I first want to thank everyone for responding. Second, after reading
this I realize that my assumption that opening a file using a
FileStream does not necessarily obtain an exclusive lock on the file
and prevent another thread in my web application from accessing the
file. Im going to try out the FileStream with Fileshare property as
Mike suggested. Thanks again everyone!
 
Back
Top