Files and Streams in ASP.NET

Files and Streams in ASP.NET

Overview

These notes explain how you can use the classes in .NET to read and change file system information and even build a simple file browser. You’ll also learn how to create simple text and binary files of your own. Finally, you’ll consider how you can allow users to upload their own files to your web server.?

Traditional file access is generally much less useful in a web application than it is in a desktop program. Databases, on the other hand, are designed from the ground up to support a large number of simultaneous users with speed, safety, and efficiency.?However, File access is so easy and straightforward in .NET that it may be perfect for simple, small-scale solutions that don’t need a full-fledged database product like SQL Server.

Contents

  • System.IO Quick Reference???
  • System.IO Classes > Common Methods & Examples???

Tutorial

  • Files and Web Applications
  • File Paths in Strings?
  • Reading and Writing with Streams
  • Text Files
  • Binary Files
  • The FileUpload Control???
  • The Maximum Size of a File Upload?



  • The System.IO Namespace contains types that allow reading and writing to files and data streams, and types that provide basic file and directory support.
  • The Directory and File classes provide static methods that allow you to retrieve information about any files and directories visible from your server .
  • The DirectoryInfo and FileInfo classes mirror the functionality in the Directory and File classes.?They use similar instance methods and properties to retrieve the same sort of information.
  • The DriveInfo class provides static methods that allow you to retrieve information about a drive and the amount of free space it provides.?
  • The Path class provides a few static methods that are useful when manipulating strings that contain file and directory paths.?
  • The StreamWriter and StreamReader classes are used for reading / writing data to / from a text file.
  • Note: With the file access classes, static methods are more convenient to use because they don’t require you to create an instance of the class. That means you can use a quick one-line code statement to perform a simple task such as checking whether a file exists. On the other hand, if you need to retrieve several pieces of information from the same file or directory, it’s easier to use the instance members. That way, you don’t need to keep specifying the name of the directory or file each time you call a method. The instance approach is also a bit faster in this situation. That’s because the FileInfo and DirectoryInfo classes perform their?security checks once — when you create the object instance. The Directory and File classes perform a security check every time you invoke a method, which adds more overhead.?
  • Note: Basic usage of text file access opens a file in single-user mode. If a second user tries to access the same file at the same time, an exception will occur . You can reduce this problem when opening files using the more generic four-parameter version of the File.Open() method instead of File.OpenText() (or File.OpenRead). You must specify FileShare.Read for the final parameter. Unlike the OpenText() method, the Open() method returns a FileStream object, and you must manually create a StreamReader that wraps it.?
  • Tip: The Server.MapPath method maps the specified relative or virtual path to the corresponding physical directory on the server.

string guestBookName = Server.MapPath("~/App_Data/GuestBook");        

Reference


System.IO Classes > Common Methods & Examples

Key System.IO Namespace Classes

  • Directory
  • File
  • DirectoryInfo
  • FileInfo
  • DriveInfo
  • Path
  • StreamWriter
  • StreamReader
  • FileStream
  • BinaryReader
  • BinaryWriter


Directory

Examples > Directory

// Retrieve the list (array) of files
string[] fileList = Directory.GetFiles(ftpDirectory);        


// Get Parent Directory?
if (Directory.GetParent(strCurrentDir) != null)
{
	// i.e. Browse 'Up One Level'
	string newDir = Directory.GetParent(strCurrentDir).FullName;?
	// ShowFilesIn(newDir);
	// ShowDirectoriesIn(newDir);
}	        


File

  • Copy()
  • Delete()
  • Exists()
  • GetAttributes() and SetAttributes()
  • GetCreationTime(), GetLastAccessTime(), and GetLastWriteTime()?
  • Move()
  • CreateText()?
  • ReadAllText() - Returns it as a single string.
  • RealAllLines() - Returns it as an array of strings.
  • ReadAllBytes() - Returns an array of bytes.
  • WriteAllText() - Creates a file, writes a suppied string to the file, and closes it.?
  • WriteAllLines() - Creates a file, write a supplied array of strings to a file (seperating each line with a hard return), and close the file.?
  • WriteAllBytes() - Creates a file, writes a supplied byte array to the file, and closes it.

Examples > File

// Display file information?
File.GetCreationTime(fileName);
File.GetLastAccessTime(fileName);        


// File.Delete
File.Delete(fileName);        


// FileAttributes - Access attribute information:?
FileAttributes attributes = File.GetAttributes(fileName);
if ((attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly) // or .Hidden
{
	// This is a read-only file
}        


// File.WriteAllLines() - Write the file in one shot
string[] lines = new string[]{"This is the first line of the file.",?
? "This is the second line of the file.",?
? "This is the third line of the file."};?


File.WriteAllLines(@"c:\testfile.txt", lines);         


// File.ReadAllLines()?- Read the file in one shot?
string content = File.ReadAllLines(@"c:\testfile.txt");         

?

DirectoryInfo

Tip: You can use methods such as DirectoryInfo.GetFiles() and DirectoryInfo.GetDirectories() to create a simple file browser.?

Examples > DirectoryInfo

// Create a new directory:
DirectoryInfo myDirectory = new DirectoryInfo(@"c:\Temp\Test");?
myDirectory.Create();        


DirectoryInfo dirInfo = new DirectoryInfo(dir);

// Show Files in Directory?
foreach (FileInfo fileItem in dirInfo.GetFiles())
{
	FilesList.Add(fileItem.Name);
}

// Show Sub-Directories in Directory?
foreach (DirectoryInfo dirItem in dirInfo.GetDirectories())
{
	DirectoryList.Add(dirItem.Name);

}        


string guestBookData = Server.MapPath("~/App_Data/GuestBook");
DirectoryInfo guestBookDir = new DirectoryInfo(guestBookData);


foreach (FileInfo fileItem in guestBookDir.GetFiles())
{
	// process fileItem (each file within ~/App_Data/GuestBook)

}        

Tip: When putting data files in the App_Data folder, the web application ensures that the user can’t access any of the files directly, because the web server won’ t allow it.


FileInfo

Examples > File Info

// Create a new file:?
FileInfo myFile = new FileInfo(@"c:\Temp\Test\readme.txt");?
myFile.Create();        


FileInfo = selectedFile = new FileInfo(fileName);
StringBuilder info = new StringBuilder();
info.Append("File: ");
info.Append(selectedFile.Name);
info.Append("| Size: ");
info.Append(selectedFile.Length);
info.Append("| Created: ");
info.Append(selectedFile.CreationTime.ToString());
info.Append("| Last Accessed: ");

info.Append(selectedFile.LastAccessTime.ToString());        


DriveInfo

  • TotalSize
  • TotalFreeSpace
  • AvailableFreeSpace
  • DriveFormat
  • DriveType
  • IsReady
  • Name
  • VolumeLabel
  • RootDirectory
  • GetDrives()


Path

Examples > Path

// Path.Combine?
// Fuse together the path of a folder with a sub-folder or file.?
string ftpDirectory = Path.Combine(Request.PhysicalApplicationPath,"FTP");
string newDir = Path.Combine(strCurrentDir, strSelectedDir);
string fileName = Path.Combine(strCurrentDir,strSelectedFile);

// Combine Application path with sub-folder path:
string absolutePath = @"c:\Users\MyDocuments";?
string subPath = @"Sarah\worksheet.xls";
string combined = Path.Combine(absolutePath, subPath);?


// Path.GetFileName
string fileName2 = 
Path.GetFileName(@"c:\Documents\Upload\Users\JamesX\resume.doc");        


StreamWriter

// StreamWriter (designed for writing text files).?
StreamWriter w = File.CreateText(@"c:\myfile.txt");?// Create the file
w.WriteLine("This file generated by ASP.NET");? // Write a string 
w.WriteLine(42);? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? // Write a number 
w.Close();?
        


FileInfo newFile = new FileInfo(@"c:\Temp\data.txt");?
StreamWriter w = newFile.CreateText();

// Write the information to the file.
w.WriteLine(DateTime.Now().ToString());
w.WriteLine(strMessage);
w.Flush();

w.Close();        


StreamReader

// StreamReader?
StreamReader r = File.OpenText(@"c:\myfile.txt");?
string inputString;?
inputString = r.ReadLine();? ? // = "This file generated by ASP.NET"?
inputString = r.ReadLine();? ? // = "42" 	


// StreamReader - Entire File	
StreamReader r = File.OpenText(@"c:\myfile.txt");?
string line;?
do?
{?
	line = r.ReadLine();?
	if (line != null)?
	{?
		// (Process the line here.)?
	}?
} while (line != null); 	

r.Close();        


// Parse Data from File?
FileInfo entryFile = new FileInfo(@"c:\Temp\data.txt");?
StreamReader r = entryFile.OpenText();
string Submitted = DateTime.Parse(r.ReadLine());
string Message = r.ReadLine();

r.Close();        


FileStream

  • .Length

Examples > FileStream

// FileStream & StreamReader - multiuser-friendly?
FileStream fs = File.Open(@"c:\myfile.txt", FileMode.Open, 
                          FileAccess.Read, FileShare.Read);?
StreamReader r = new StreamReader(fs);?        


BinaryReader

  • ReadString()
  • ReadInt32()
  • BaseStream.Length

Examples > BinaryReader

// BinaryReader
BinaryReader r = new BinaryReader(File.OpenRead(@"c:\binaryfile.bin"));?
string str;?
int integer;?
str = r.ReadString();?
integer = r.ReadInt32();?
r.Close();?        


// BinaryReader - multiuser-friendly?
FileStream fs = File.Open(@"c:\binaryfile.bin", FileMode.Open, 
                          FileAccess.Read, FileShare.Read);?
BinaryReader r = new BinaryReader(fs); 	        


BinaryWriter

  • Write()

Examples > BinaryWriter

// BinaryWriter
FileStream fs = File.OpenWrite(@"c:\binaryfile.bin");?
BinaryWriter w = new BinaryWriter(fs); 		
string str = "ASP.NET Binary File Test";?
int integer = 42;?
w.Write(str);?
w.Write(integer);?
w.Close();?        

Reference


Files and Web Applications

There are several limitations to files:

  • File-naming limitations: You can't have the same name as an existing file in the same directory.?
  • Multi-user limitations - Although you can allow multiple users to read a file at once, it's almost impossible to let multiple users update the same file at the same time without issues.
  • Scalability problems: File operations suffer from some overhead. In a simple scenario, file access may be faster than connecting to a database and performing a query. But the cumulative effect in a large web application is very different. When multiple users are working with files at the same time, your web server may slow down dramatically.?
  • Security risks: If you allow the user to specify a file or path name, the user could devise a way to trick your application into accessing or overwriting a protected system file. Even without this ability, a malicious or careless user might use an ASP.NET page that creates or uploads files to fill up your web server hard drive and cause it to stop working. All of these problems are preventable, but they require a bit more work than a database-backed solution.?

File Paths in Strings?

  • In C#, you need to take special care when creating strings that hold file paths or directory paths. That’s because in C#, the directory separation character (\) also has another meaning — it indicates the start of a special character sequence. To indicate that you really want a backward slash and not a special character sequence, you need two slashes, as shown here:?

string myDirectory = "c:\\Temp\\MyFiles";        

  • Another option is to precede your string with the “at” sign (@). This tells C# to interpret the string exactly as written. Here’s an example of this syntax:?

string myDirectory = @"c:\Temp\MyFiles";?        

  • The approach you use is entirely up to you, although the @ syntax makes it easier to read long paths (and easier to avoid typos).?

Tips

  • You can get the current web application directory via the Request.PhysicalApplicationPath property.
  • Do not use string concatenation to join strings together, because every time code adds a piece of text to a string, .NET creates an entirely new string object behind the scenes.?Instead use the System.Text.StringBuilder class for optimum performance.?
  • When using any external resource, including files, it's essential that you defend your code from runtime errors with a try/catch block.?This way you can deal with unpredictable occurrences that are beyond your control - for example, if the file isn't accessible because it's already open in another program, or the account running the code doesn't have the required permissions.

Reading and Writing with Streams

  • The .NET Framework makes it easy to create simple "flat" files in text or binary format. Unlike a database, these files don’t have any internal structure (that’s why they’re called flat). Instead, these files are really just a list of whatever information you want to store.

Text Files

  • You can write to a file and read from a file using a StreamWriter and a StreamReader — dedicated classes that abstract away the process of file interaction.
  • When you call the CreateText() method, you create the file and receive the StreamWriter object. At this point, the file is open and ready to receive your content. You need to write your data to the file and then close it as soon as possible.
  • When you finish with the file, you must make sure to close it by calling the Close() or Dispose() method. Otherwise, the changes may not be properly written to disk, and the file could be locked open.??
  • ReadLine() returns a null reference when there is no more data in the file.?
  • Basic usage of text file access opens a file in single-user mode. If a second user tries to access the same file at the same time, an exception will?occur . You can reduce this problem when opening files using the more generic four-parameter version of the File.Open() method instead of File.OpenText(). You must specify FileShare.Read for the final parameter. Unlike the OpenText() method, the Open() method returns a FileStream object, and you must manually create a StreamReader that wraps it.?
  • .NET includes functionality for turbo-charging your file writing and reading. This functionality comes from several static methods in the File class that let you read or write an entire file in a single line of code.
  • The quick file access methods are certainly convenient for creating small files. They also ensure a file is kept only for as short a time as possible, which is always the best approach to minimize concurrency problems. But are they really practical? It all depends on the size of the file. If you have a large file (say, one that’s several megabytes), reading the entire content into memory at once is a terrible idea. It’s much better to read one piece of data at a time and process the information bit by bit. Even if you’re dealing with medium-sized files (say, several hundreds of kilobytes), you might want to steer clear of the quick file access methods. That’s because in a popular website you might have multiple requests dealing with files at the same time, and the combined overhead of keeping every user’s file data in memory might reduce the performance of your application.

Binary Files

  • To open a file for binary writing, you need to create a new BinaryWriter object. The constructor accepts a stream, which you can retrieve using the File.OpenWrite() method.
  • You can write binary data to any type of stream, whether it represents a file or some other type of storage location, using the same code.?
  • Writing to a binary file is almost the same as writing to a text file.?
  • Reading data from a binary file is easy, but not quite as easy as reading data from a text file. The problem is that you need to know the data type of the data you want to retrieve. To retrieve a string, you use the ReadString() method. To retrieve an integer, you must use ReadInt32().
  • If you want to use file sharing, you need to use File.Open() instead of File.OpenRead().?
  • Note: You have no easy way to jump to a location in a text or binary file without reading through all the information in order. Although you can use methods such as Seek() on the underlying stream, you need to specify an offset in bytes, which involves some fairly involved calculations based on data type sizes. If you need to store a large amount of information and move through it quickly, you need a dedicated database, not a binary file.?


The FileUpload Control

  • ASP.NET includes a control that allows website users to upload files to the web server. Once the web server receives the posted file data, it’s up to your application to examine it, ignore it, or save it to a back-end database or a file on the web server. The FileUpload control does this work, and it represents the <input type="file"> HTML tag. Declaring the FileUpload control is easy:?

<asp:FileUpload ID="Uploader" runat="server" />?        

  • The <input type="file"> tag doesn’t give you much choice as far as user interface is concerned (it’s limited to a text box that contains a file name and a Browse button). When the user clicks Browse, the browser presents an Open dialog box and allows the user to choose a file. This part is hardwired into the browser, and you can’t change this behavior. Once the user selects a file, the file name is filled into the corresponding text box. However, the file isn’t uploaded yet—that happens later, when the page is posted back. At this point, all the data from all input controls (including the file data) is sent to the server. For that reason, it’s common to add a button to post back the page.?
  • To get information about the posted file content, you can access the FileUpload.PostedFile object. You can save the content by calling the PostedFile.SaveAs() method:?

Uploader.PostedFile.SaveAs(@"c:\Uploads\newfile");?        

  • The FileUpload.PostedFile object contains only a few properties. One interesting property is ContentLength, which returns the size of the file in bytes. You could examine this setting and use it to prevent a user from uploading excessively large files.?

Examples > FileUpload Control

// To get information about the posted file content,?
// you can access the FileUpload.PostedFile object.?

// ASPX Controls:?
// Choose an image to upload: <br />
// <asp:FileUpload ID="Uploader" runat="server" />&nbsp;?
// <asp:Button ID="cmdUpload" runat="server" OnClick        ="cmdUpload_Click" Text="Upload" /><br />
// <br />
// <asp:Label ID="lblInfo" runat="server" EnableViewState="False" Font-Bold="True"></asp:Label>

protected void cmdUpload_Click(object sender, EventArgs e)
{
	string uploadDirectory = Path.Combine(Request.PhysicalApplicationPath, "Uploads");
	
	// Check that a file is actually being submitted.
	if (Uploader.PostedFile.FileName == "")
	{
		lblInfo.Text = "No file specified.";
	}
	else
	{
		// Check the extension.
		string extension = Path.GetExtension(Uploader.PostedFile.FileName);
		switch (extension.ToLower())
		{
			case ".bmp":
			case ".gif":
			case ".jpg":
				break;
			default:
				lblInfo.Text = "This file type is not allowed.";
				return;
		}
		// Using this code, the saved file will retain its original
		// file name, but be stored in the current server
		// application directory.
		string serverFileName = Path.GetFileName(Uploader.PostedFile.FileName);
		string fullUploadPath = Path.Combine(uploadDirectory, serverFileName);

		try
		{
			// This overwrites any existing file with the same name.
			// Use File.Exists() to check first if this is a concern.
			Uploader.PostedFile.SaveAs(fullUploadPath);

			lblInfo.Text = "File " + serverFileName;
			lblInfo.Text += " uploaded successfully to ";
			lblInfo.Text += fullUploadPath;
		}
		catch (Exception err)
		{
			lblInfo.Text = err.Message;
		}
	}
}        


The Maximum Size of a File Upload?

  • By default, ASP.NET will reject a request that’s larger than 4MB. However, you can alter this maximum by modifying the maxRequestLength setting in the web.config file. This sets the largest allowed file in kilobytes. The web server will refuse to process larger requests.?
  • The following sample setting configures the server to accept files up to 8MB:?

<?xml version="1.0" encoding="utf-8" ?>?
<configuration>?
? <system.web>?
	<!-- Other settings omitted for clarity. -->?
	<httpRuntime maxRequestLength="8192" />?
? </system.web>?
</configuration>?        


要查看或添加评论,请登录

Richard Harris的更多文章

  • Using Linux on Windows via WSL

    Using Linux on Windows via WSL

    Contents Overview of Windows Subsystem for Linux Setup (including Windows PowerShell Commands for WSL & Linux Shell…

  • Cloud Computing QuickStart Guide

    Cloud Computing QuickStart Guide

    Overview Cloud computing is on-demand access (via the internet) to computing resources — applications, servers…

    2 条评论
  • Software Development & Technology News (01/08/2021 - 25/11/2021 )

    Software Development & Technology News (01/08/2021 - 25/11/2021 )

    Googling for Software Development- What Developers Search For and What They Find · It Will Never Work in Theory Why…

    1 条评论
  • Software Development & Technology News (09/02/2021 - 31/07/2021)

    Software Development & Technology News (09/02/2021 - 31/07/2021)

    Do business leaders know how to evaluate developer success- - ZDNet Will Artificial Intelligence Be the End of Web…

  • Azure Infrastructure | IaaS Day Recap

    Azure Infrastructure | IaaS Day Recap

    Today (17/11/2021) I attended Microsoft's Azure IaaS Day, which was delivered in partnership with Intel. In case you…

  • Microsoft SQL Server

    Microsoft SQL Server

    Introduction MS SQL Server is a Relational Database Management System (RDBMS) developed by Microsoft. It provides GUI…

    1 条评论
  • Custom Software Development: Project Initiation

    Custom Software Development: Project Initiation

    Need a custom app built? I can make your vision a reality! We'd begin with Requirements Gathering, Planning, and…

  • Software Development Life Cycle (SDLC)

    Software Development Life Cycle (SDLC)

    Overview The Software Development Life Cycle (SDLC) is a systematic process that development teams use to produce…

    2 条评论
  • LinkedIn Learning Paths: Computer Science

    LinkedIn Learning Paths: Computer Science

    In my past article Best of LinkedIn Learning: Computer Science, I reviewed the Courses offered by LinkedIn Learning…

  • Glossary of Database Terms

    Glossary of Database Terms

    Use the terms and definitions below to better understand Relational Database concepts. Actors: An actor is a model…

    1 条评论

社区洞察

其他会员也浏览了