Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Visual CSharp 2005 Recipes (2006) [eng]

.pdf
Скачиваний:
48
Добавлен:
16.08.2013
Размер:
4.04 Mб
Скачать

178 C H A P T E R 5 F I L E S, D I R E C TO R I E S, A N D I / O

static void Main()

{

// Configure the FileSystemWatcher.

using (FileSystemWatcher watch = new FileSystemWatcher())

{

watch.Path = Application.StartupPath; watch.Filter = "*.*"; watch.IncludeSubdirectories = true;

// Attach the event handler.

watch.Created += new FileSystemEventHandler(OnCreatedOrDeleted); watch.Deleted += new FileSystemEventHandler(OnCreatedOrDeleted); watch.EnableRaisingEvents = true;

Console.WriteLine("Press Enter to create a file.");

Console.ReadLine();

if (File.Exists("test.bin"))

{

File.Delete("test.bin");

}

// Create test.bin.

using (FileStream fs = new FileStream("test.bin", FileMode.Create))

{

// Do something.

}

Console.WriteLine("Press Enter to terminate the application."); Console.ReadLine();

}

// Wait to continue. Console.WriteLine(Environment.NewLine); Console.WriteLine("Main method complete. Press Enter."); Console.ReadLine();

}

// Fires when a new file is created in the directory being monitored. private static void OnCreatedOrDeleted(object sender,

FileSystemEventArgs e)

{

// Display the notification information. Console.WriteLine("\tNOTIFICATION: " + e.FullPath +

"' was " + e.ChangeType.ToString()); Console.WriteLine();

}

}

}

C H A P T E R 5 F I L E S, D I R E C TO R I E S, A N D I / O

179

5-20. Access a COM Port

Problem

You need to send data directly to a serial port.

Solution

Use the System.IO.Ports.SerialPort class. This class represents a serial port resource and defines methods that enable communication through it.

How It Works

.NET Framework 2.0 defines a System.IO.Ports namespace that contains several classes. The central class is SerialPort. A SerialPort instance represents a serial port resource and provides methods that let you communicate through it. The SerialPort class also exposes properties that let you specify the port, baud rate, parity, and other information.

The Code

The following example demonstrates a simple console application that writes a string into the COM1 port.

using System;

using System.IO.Ports;

namespace Apress.VisualCSharpRecipes.Chapter05

{

static class Recipe05_20

{

static void Main(string[] args)

{

using (SerialPort port = new SerialPort("COM1"))

{

//Set the properties. port.BaudRate = 9600; port.Parity = Parity.None; port.ReadTimeout = 10; port.StopBits = StopBits.One;

//Write a message into the port. port.Open();

port.Write("Hello world!");

Console.WriteLine("Wrote to the port.");

}

// Wait to continue. Console.WriteLine(Environment.NewLine); Console.WriteLine("Main method complete. Press Enter."); Console.ReadLine();

}

}

}

180 C H A P T E R 5 F I L E S, D I R E C TO R I E S, A N D I / O

5-21. Get a Random Filename

Problem

You need to get a random name for creating a folder or a file.

Solution

Use the Path.GetRandomFileName method, which returns a random name.

How It Works

The System.IO.Path class includes a new GetRandomFileName method, which generates a random string. You could use this string for creating a new file or folder.

The difference between GetRandomFileName and GetTempFileName (discussed in recipe 5-15) of the Path class is that GetRandomFileName just returns a random string and does not create a file, whereas GetTempFileName creates a new 0-byte temporary file and returns the path to the file.

5-22. Manipulate the Access Control Lists of a File or Directory

Problem

You want to modify the access control list (ACL) of a file or directory in the computer.

Solution

Use the GetAccessControl and SetAccessControl methods of the File or Directory class.

How It Works

.NET Framework 2.0 now includes support for ACLs for resources like I/O, registry, and threading classes. You can retrieve and apply the ACL for a resource by using the GetAccessControl and SetAccessControl methods defined in the corresponding resource classes. For example, the File and Directory classes define both these methods, which let you manipulate the ACLs for a file or directory.

To add or remove an ACL-associated right of a file or directory, you need to first retrieve the

FileSecurity or DirectorySecurity object currently applied to the resource using the GetAccessControl method. Once you retrieve this object, you need to perform the required modification of the rights, and then apply the ACL back to the resource using the SetAccessControl method. Access rights are updated using any of the add and remove methods provided in the security class.

The Code

The following example demonstrates the effect of denying Everyone Read access to a temporary file, using a console application. An attempt to read the file after a change in the ACL triggers a security exception.

C H A P T E R 5 F I L E S, D I R E C TO R I E S, A N D I / O

181

using System; using System.IO;

using System.Security.AccessControl;

namespace Apress.VisualCSharpRecipes.Chapter05

{

static class Recipe05_22

{

static void Main(string[] args)

{

FileStream stream; string fileName;

// Create a new file and assign full control to 'Everyone'. Console.WriteLine("Press any key to write a new file..."); Console.ReadKey(true);

fileName = Path.GetRandomFileName();

using (stream = new FileStream(fileName, FileMode.Create))

{

// Do something.

}

Console.WriteLine("Created a new file " + fileName + "."); Console.WriteLine();

//Deny 'Everyone' access to the file Console.WriteLine("Press any key to deny 'Everyone' " +

"access to the file..."); Console.ReadKey(true); SetRule(fileName, "Everyone",

FileSystemRights.Read, AccessControlType.Deny); Console.WriteLine("Removed access rights of 'Everyone'."); Console.WriteLine();

//Attempt to access file.

Console.WriteLine("Press any key to attempt " + "access to the file...");

Console.ReadKey(true);

try

{

stream = new FileStream(fileName, FileMode.Create);

}

catch (Exception ex)

{

Console.WriteLine("Exception thrown: "); Console.WriteLine(ex.ToString());

}

finally

{

stream.Close();

stream.Dispose();

}

182 C H A P T E R 5 F I L E S, D I R E C TO R I E S, A N D I / O

// Wait to continue. Console.WriteLine(Environment.NewLine); Console.WriteLine("Main method complete. Press Enter."); Console.ReadLine();

}

static void AddRule(string filePath, string account, FileSystemRights rights, AccessControlType controlType)

{

//Get a FileSecurity object that represents the

//current security settings.

FileSecurity fSecurity = File.GetAccessControl(filePath);

//Add the FileSystemAccessRule to the security settings. fSecurity.AddAccessRule(new FileSystemAccessRule(account,

rights, controlType));

//Set the new access settings. File.SetAccessControl(filePath, fSecurity);

}

static void SetRule(string filePath, string account, FileSystemRights rights, AccessControlType controlType)

{

//Get a FileSecurity object that represents the

//current security settings.

FileSecurity fSecurity = File.GetAccessControl(filePath);

//Add the FileSystemAccessRule to the security settings. fSecurity.ResetAccessRule(new FileSystemAccessRule(account,

rights, controlType));

//Set the new access settings. File.SetAccessControl(filePath, fSecurity);

}

}

}

C H A P T E R 6

■ ■ ■

XML Processing

One of the most remarkable aspects of the Microsoft .NET Framework is its deep integration with XML. In many .NET applications, you won’t even be aware you’re using XML technologies—they’ll just be used behind the scenes when you serialize a Microsoft ADO.NET DataSet, call a Web service, or read application settings from a Web.config configuration file. In other cases, you’ll want to work directly with the System.Xml namespaces to manipulate Extensible Markup Language (XML) data. Common XML tasks don’t just include parsing an XML file but also include validating it against a schema, applying an XSL transform to create a new document or Hypertext Markup Language (HTML) page, and searching intelligently with XPath. The recipes in this chapter describe how to do the following:

Read, parse, and manipulate XML data (recipes 6-1, 6-2, 6-3, and 6-7)

Search an XML document for specific nodes, either by name (recipe 6-4), by namespace (recipe 6-5), or by using XPath (recipe 6-6)

Validate an XML document with an XML schema (recipe 6-8)

Serialize an object to XML (recipe 6-9), create an XML schema for a class (recipe 6-10), and generate the source code for a class based on an XML schema (recipe 6-11)

Transform an XML document to another document using an XSL Transformations (XSLT) stylesheet (recipe 6-12)

6-1. Show the Structure of an XML Document in a TreeView

Problem

You need to display the structure and content of an XML document in a Windows-based application.

Solution

Load the XML document using the System.Xml.XmlDocument class. Create a re-entrant method that converts a single XmlNode into a System.Windows.Forms.TreeNode, and call it recursively to walk through the entire document.

183

184 C H A P T E R 6 X M L P R O C E S S I N G

How It Works

The .NET Framework provides several different ways to process XML documents. The one you use depends in part upon your programming task. One of the most fully featured classes is XmlDocument, which provides an in-memory representation of an XML document that conforms to the W3C Document Object Model (DOM). The XmlDocument class allows you to browse through the nodes in any direction, insert and remove nodes, and change the structure on the fly. For details of the DOM specification, go to http://www.w3c.org.

Note The XmlDocument class is not scalable for very large XML documents, because it holds the entire XML content in memory at once. If you want a more memory-efficient alternative, and you can afford to read and process the XML piece by piece, consider the XmlReader and XmlWriter classes described in recipe 6-7.

To use the XmlDocument class, simply create a new instance of the class, and call the Load method with a filename, a Stream, a TextReader, or an XmlReader object. It is also possible to read the XML from a simple string with the LoadXML method. You can even supply a string with a URL that points to an XML document on the Web using the Load method. The XmlDocument instance will be populated with the tree of elements, or nodes, from the source document. The entry point for accessing these nodes is the root element, which is provided through the XmlDocument.DocumentElement property. DocumentElement is an XmlElement object that can contain one or more nested XmlNode objects, which in turn can contain more XmlNode objects, and so on. An XmlNode is the basic ingredient of an XML file. Common XML nodes include elements, attributes, comments, and contained text.

When dealing with an XmlNode or a class that derives from it (such as XmlElement or XmlAttribute), you can use the following basic properties:

ChildNodes is an XmlNodeList collection that contains the first level of nested nodes.

Name is the name of the node.

NodeType returns a member of the System.Xml.XmlNodeType enumeration that indicates the type of the node (element, attribute, text, and so on).

Value is the content of the node, if it’s a text or CDATA node.

Attributes provides a collection of node objects representing the attributes applied to the element.

InnerText retrieves a string with the concatenated value of the node and all nested nodes.

InnerXml retrieves a string with the concatenated XML markup for all nested nodes.

OuterXml retrieves a string with the concatenated XML markup for the current node and all nested nodes.

The Code

The following example walks through every element of an XmlDocument using the ChildNodes property and a recursive method. Each node is displayed in a TreeView control, with descriptive text that either identifies it or shows its content.

using System;

using System.Windows.Forms; using System.Xml;

using System.IO;

C H A P T E R 6 X M L P R O C E S S I N G

185

namespace Apress.VisualCSharpRecipes.Chapter06

{

public partial class Recipe06_01 : System.Windows.Forms.Form

{

private void cmdLoad_Click(object sender, System.EventArgs e)

{

//Clear the tree. treeXml.Nodes.Clear();

//Load the XML document. XmlDocument doc = new XmlDocument(); try

{

doc.Load(txtXmlFile.Text);

}

catch (Exception err)

{

MessageBox.Show(err.Message);

return;

}

//Populate the TreeView. ConvertXmlNodeToTreeNode(doc, treeXml.Nodes);

//Expand all nodes. treeXml.Nodes[0].ExpandAll();

}

private void ConvertXmlNodeToTreeNode(XmlNode xmlNode, TreeNodeCollection treeNodes)

{

//Add a TreeNode node that represents this XmlNode. TreeNode newTreeNode = treeNodes.Add(xmlNode.Name);

//Customize the TreeNode text based on the XmlNode

//type and content.

switch (xmlNode.NodeType)

{

case XmlNodeType.ProcessingInstruction: case XmlNodeType.XmlDeclaration:

newTreeNode.Text = "<?" + xmlNode.Name + " " + xmlNode.Value + "?>";

break;

case XmlNodeType.Element:

newTreeNode.Text = "<" + xmlNode.Name + ">"; break;

case XmlNodeType.Attribute:

newTreeNode.Text = "ATTRIBUTE: " + xmlNode.Name; break;

case XmlNodeType.Text: case XmlNodeType.CDATA:

newTreeNode.Text = xmlNode.Value; break;

case XmlNodeType.Comment:

newTreeNode.Text = "<!--" + xmlNode.Value + "-->"; break;

}

186C H A P T E R 6 X M L P R O C E S S I N G

//Call this routine recursively for each attribute.

//(XmlAttribute is a subclass of XmlNode.)

if (xmlNode.Attributes != null)

{

foreach (XmlAttribute attribute in xmlNode.Attributes)

{

ConvertXmlNodeToTreeNode(attribute, newTreeNode.Nodes);

}

}

//Call this routine recursively for each child node.

//Typically, this child node represents a nested element

//or element content.

foreach (XmlNode childNode in xmlNode.ChildNodes)

{

ConvertXmlNodeToTreeNode(childNode, newTreeNode.Nodes);

}

}

}

}

Usage

As an example, consider the following simple XML file (which is included with the sample code as the ProductCatalog.xml file):

<?xml version="1.0" ?> <productCatalog>

<catalogName>Jones and Jones Unique Catalog 2004</catalogName> <expiryDate>2005-01-01</expiryDate>

<products>

<product id="1001">

<productName>Gourmet Coffee</productName> <description>The finest beans from rare Chilean plantations.</description> <productPrice>0.99</productPrice> <inStock>true</inStock>

</product> <product id="1002">

<productName>Blue China Tea Pot</productName> <description>A trendy update for tea drinkers.</description> <productPrice>102.99</productPrice>

<inStock>true</inStock>

</product>

</products>

</productCatalog>

Figure 6-1 shows how this file will be rendered in the Recipe06_01 form.

C H A P T E R 6 X M L P R O C E S S I N G

187

Figure 6-1. The displayed structure of an XML document

6-2. Insert Nodes in an XML Document

Problem

You need to modify an XML document by inserting new data, or you want to create an entirely new XML document in memory.

Solution

Create the node using the appropriate XmlDocument method (such as CreateElement, CreateAttribute, CreateNode, and so on). Then insert it using the appropriate XmlNode method (such as InsertAfter,

InsertBefore, or AppendChild).

Соседние файлы в предмете Программирование на C++