文件与 HTML 操作全解析:创建、写入与格式化技巧
在开发过程中,文件和目录的创建、数据的写入以及 HTML 的格式化都是常见的操作。下面将详细介绍这些操作的相关知识和具体实现方法。
1. 创建文件和目录
在开发中,我们常常需要创建新的文件和目录。使用
DirectoryInfo
和
FileInfo
类,就能轻松实现这一需求。
1.1 页面计数器示例
假设要为页面创建一个计数器,记录页面的访问次数。为了让计数器数据在应用程序实例之间持久化,需要将数据存储在文件中。具体操作步骤如下:
1.
锁定应用程序对象
:确保在更新计数器时不会出现并发问题。
2.
从应用程序变量中获取计数器值
。
3.
将计数器值加 1
。
4.
将更新后的计数器值保存到应用程序变量中
。
5.
解锁应用程序
。
在
Global.asax.vb
文件中,需要重写
Global Init
事件并定义计数器变量:
Public Overrides Sub Init()
Application("pagecounter") = 0
End Sub
在 Web 表单中,获取计数器变量并进行递增操作:
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim pageCounter As Integer
Application.Lock()
pageCounter = Application("pageCounter")
pageCounter += 1
Application("pageCounter") = pageCounter
Application.UnLock()
lblCounter.Text = "Counter: " + pageCounter.ToString
End Sub
当应用程序启动时,需要创建
counters
子目录:
Public Sub Application_OnStart()
System.Diagnostics.EventLog.WriteEntry("VBNetWeb", "VBNetWeb Starting")
Dim di As DirectoryInfo
Try
di = New DirectoryInfo("c:\inetpub\wwwroot\VBNetWeb\ch10\counters")
If Not di.Exists Then
di.Create
System.Diagnostics.EventLog.WriteEntry("VBNetWeb", "counters folder created")
End If
Catch ex As Exception
System.Diagnostics.EventLog.WriteEntry("VBNetWeb", ex.Message)
System.Diagnostics.EventLog.WriteEntry("VBNetWeb", ex.StackTrace)
End Try
If Application("StartEventCount") Is Nothing Then
Application("StartEventCount") = 0
End If
End Sub
当应用程序结束时,将计数器值写入文件:
Public Sub Application_OnEnd()
System.Diagnostics.EventLog.WriteEntry("VBNetWeb", "VBNetWeb Ending")
Dim fi As FileInfo
Dim fs As FileStream
Dim counter As Integer
Try
fi = New FileInfo("c:\inetpub\wwwroot\VBNetWeb\ch10\counters\pagecounter.txt")
fs = fi.Open(FileMode.OpenOrCreate, FileAccess.Write, FileShare.None)
fs.Seek(0, SeekOrigin.Begin)
Dim bw As New BinaryWriter(fs)
counter = Application("pagecounter")
bw.Write(counter)
bw.Close()
fs.Close()
Catch ex As Exception
System.Diagnostics.EventLog.WriteEntry("VBNetWeb", ex.Message)
System.Diagnostics.EventLog.WriteEntry("VBNetWeb", ex.StackTrace)
End Try
End Sub
1.2
DirectoryInfo
和
FileInfo
类的特点
DirectoryInfo
类的
Create
方法非常强大,它可以在路径中一个或多个父目录不存在的情况下创建目录。例如,要创建路径
c:\test1\test2\test3\test4
,如果所有文件夹都不存在,使用
DirectoryInfo
对象的
Create
方法可以一次性完成创建。
然而,
FileInfo
类没有这种能力。如果绑定一个字符串到
FileInfo
对象并调用
Create
方法,一旦遇到缺失的目录就会引发错误。所以,在创建文件之前,必须确保文件所在的目录已经存在。
2. 写入文件
将数据写入文件有多种方式,下面介绍几种常见的方法。
2.1 使用
BinaryWriter
写入整数
在前面的页面计数器示例中,使用
BinaryWriter
将整数写入文件:
Dim fi As FileInfo
Dim fs As FileStream
Dim counter As Integer
fi = New FileInfo("c:\inetpub\wwwroot\VBNetWeb\ch10\counters\pagecounter.txt")
fs = fi.Open(FileMode.OpenOrCreate, FileAccess.Write, FileShare.None)
fs.Seek(0, SeekOrigin.Begin)
Dim bw As New BinaryWriter(fs)
counter = Application("pagecounter")
bw.Write(counter)
bw.Close()
fs.Close()
2.2 使用
StreamWriter
写入字符串
如果要将字符串写入文件,可以使用
StreamWriter
。具体步骤如下:
1. 创建
FileInfo
对象实例并以可写模式打开。
2. 创建
StreamWriter
对象。
3. 使用
StreamWriter
的
Write
方法写入字符串。
4. 关闭
StreamWriter
和
FileStream
。
示例代码如下:
Dim s As String = "Test"
Dim di As DirectoryInfo = New DirectoryInfo("c:\inetpub\wwwroot\vbnetweb\ch10\counters")
Dim fi As FileInfo = New FileInfo(di.FullName & "\pagecounter.txt")
Dim fs As FileStream = fi.OpenWrite
Dim sw As New StreamWriter(fs)
sw.Write(s)
sw.Close()
fs.Close()
2.3 写入文本文件的其他方式
-
使用
FileInfo的AppendText方法 :该方法返回一个StreamWriter,可以跳过创建FileStream的步骤。 -
使用
FileStream的构造函数 :FileStream类有一个重载的构造函数,接受文件路径、创建/打开选项和文件共享限制。 -
使用
StreamWriter的重载构造函数 :如果只想将文本追加到文件中,可以使用StreamWriter的重载构造函数。例如:
Dim sw As New StreamWriter(Server.MapPath("") & "\test.txt", True)
sw.WriteLine("This is a test")
sw.Close()
3. 读写二进制文件
StreamWriter
和
BinaryWriter
都可以用于写入文件,但它们有一些区别。
StreamWriter
继承自
TextWriter
类,它写入数据的字符串表示形式;而
BinaryWriter
写入数据的字节值。下面是它们的
Write
方法参数对比表:
| Write 方法参数 | StreamWriter | BinaryWriter |
| — | — | — |
| Boolean | X | X |
| Byte | X | |
| Byte() | X | |
| Byte(), Integer (start), Integer (length) | X | |
| Char | X | X |
| Char() | X | X |
| Char(), Integer (start), Integer (length) | X | |
| String | X | X |
| Decimal | X | X |
| Double | X | X |
| Short | X | |
| Integer | X | X |
| Long | X | X |
| Sbyte | X | |
| Single | X | |
| Object | X | |
| UInt16 | X | |
| UInt32 | X | X |
| UInt64 | X | X |
| String, Object | X | |
| String, ParamArray(Object) | X | |
| String, Object, Object | X | |
| String, Object, Object, Object | X | |
需要注意的是,公共语言系统(CLS)不支持写入无符号类型,如果希望代码符合 CLS 规范,应避免使用。另外,当使用
StreamWriter
写入对象时,它会调用对象的
ToString
方法并写入结果字符串,不会序列化对象。如果需要序列化对象,可以使用
BinaryFormatter.Serialize
方法。
4. 向内存写入数据
在 .NET 中,向内存缓冲区写入数据与向文件写入数据非常相似。可以创建一个
MemoryStream
,将数据写入其中,然后将缓冲区保存到磁盘。示例代码如下:
Dim b(25) As Byte
Dim i As Integer
Dim ms As New MemoryStream()
For i = 0 To 25
b(i) = i + 65
Next
ms.Write(b, 0, b.Length)
ms.WriteTo(Response.OutputStream)
MemoryStream
与其他流的主要区别在于它有一个
WriteTo
方法。此外,还可以使用
StringWriter
或
StringBuilder
将文本写入内存。
5. 写入 HTML
当需要编写格式良好的 HTML 时,.NET 框架提供了
HtmlTextWriter
类来帮助正确格式化数据。下面通过两个示例来展示手动编写 HTML 和使用
HtmlTextWriter
编写 HTML 的区别。
5.1 示例代码
Imports System.Web.UI
Imports System.text
Imports System.io
Public Class ch10_7
Inherits System.Web.UI.Page
#Region " Web Form Designer Generated Code "
'This call is required by the Web Form Designer.
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
End Sub
Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
'CODEGEN: This method call is required by the Web Form Designer
'Do not modify it using the code editor.
InitializeComponent()
End Sub
#End Region
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim arrData As Object = getRandomData()
Call showTable1(arrData)
Call showTable2(arrData)
End Sub
Function getRandomData() As Object(,)
Dim strings() As String = {"Row 1", "Row 2", "Row 3", "Row 4", "Row 5"}
Dim values(4, 4) As Object
Dim aValue As Integer
Dim rand As New Random()
Dim i, j As Integer
For i = 0 To 4
For j = 0 To 4
If j = 4 Then
values(i, j) = strings(i)
Else
aValue = rand.Next(-1000, 1000)
values(i, j) = aValue
End If
Next
Next
Return values
End Function
Sub showTable1(ByVal values(,) As Object)
Dim i, j As Integer
Dim cellValue As Integer
Response.Write("<h3>This table was written with HTML created by hand.</h3>")
Response.Write("<table align='center' border='1'>")
For i = 0 To values.GetUpperBound(0)
Response.Write("<tr>")
For j = 0 To values.GetUpperBound(1)
Select Case values(i, j).GetType.Name
Case "String"
Response.Write("<td style='color:blue; background: lightyellow'>" & values(i, j) & "</td>")
Case "Int32"
Select Case values(i, j)
Case Is < 0
Response.Write("<td style='color: red; background:lightyellow'>" & values(i, j) & "</td>")
Case Is >= 0
Response.Write("<td style='color: black'>" & values(i, j) & "</td>")
End Select
End Select
Next
Response.Write("<tr>")
Next
Response.Write("</table><br>")
End Sub
Sub showTable2(ByVal values(,) As Object)
Dim tbl As New HtmlTable()
Dim sb As New StringBuilder(3000)
Dim sw As New StringWriter(sb)
Dim htw As New HtmlTextWriter(sw)
Dim i, j As Integer
Dim row As HtmlTableRow
Dim cell As HtmlTableCell
tbl.Border = 1
tbl.Align = "center"
Response.Write("<h3>This table was written with HTML created by an HtmlTextWriter</h3>")
For i = 0 To values.GetUpperBound(0)
row = New HtmlTableRow()
tbl.Rows.Add(row)
For j = 0 To values.GetUpperBound(1)
cell = New HtmlTableCell()
Select Case values(i, j).GetType.Name
Case "String"
cell.Attributes.Add("style", "color:blue; background:lightYellow")
Case "Int32"
Select Case values(i, j)
Case Is < 0
cell.Attributes.Add("style", "color:red; background:lightYellow")
Case Is >= 0
cell.Attributes.Add("style", "color:black; background:white")
End Select
End Select
cell.InnerText = values(i, j).ToString
row.Cells.Add(cell)
Next
Next
tbl.RenderControl(New HtmlTextWriter(sw))
Response.Write(sb.ToString)
End Sub
End Class
5.2 对比分析
-
手动编写 HTML
:在
showTable1方法中,手动拼接 HTML 代码,代码较为复杂,维护起来比较困难。 -
使用
HtmlTextWriter:在showTable2方法中,使用HtmlTextWriter和 HTML 控件来生成 HTML,代码更加清晰,易于维护。
综上所述,在开发过程中,合理使用文件和目录的创建、数据的写入以及 HTML 的格式化方法,可以提高代码的可读性和可维护性。
6. 随机数据生成与表格创建
在上述示例中,我们使用了随机数据来填充表格。下面详细介绍随机数据的生成以及表格创建的相关内容。
6.1 随机数据生成
在 .NET 中,使用
Random
类可以方便地生成随机数据。
Random
类在创建新实例时会自动以基于时间的值作为种子,因此无需像早期 VB 版本那样使用
Randomize
。
以下是生成随机数据的具体步骤:
1. 创建
Random
对象实例。
2. 使用
Random
对象的
Next
方法获取随机数。
Next
方法有一个重载版本,可以返回指定范围内的随机数。
示例代码如下:
Function getRandomData() As Object(,)
Dim strings() As String = {"Row 1", "Row 2", "Row 3", "Row 4", "Row 5"}
Dim values(4, 4) As Object
Dim aValue As Integer
Dim rand As New Random()
Dim i, j As Integer
For i = 0 To 4
For j = 0 To 4
If j = 4 Then
values(i, j) = strings(i)
Else
aValue = rand.Next(-1000, 1000)
values(i, j) = aValue
End If
Next
Next
Return values
End Function
上述代码生成了一个二维对象数组,其中前四个元素为整数,每五个元素为字符串。
6.2 表格创建
我们通过两个方法
showTable1
和
showTable2
分别展示了手动编写 HTML 和使用
HtmlTextWriter
创建表格的方式。
-
手动编写 HTML 创建表格
:在
showTable1方法中,通过Response.Write方法手动拼接 HTML 代码来创建表格。代码如下:
Sub showTable1(ByVal values(,) As Object)
Dim i, j As Integer
Dim cellValue As Integer
Response.Write("<h3>This table was written with HTML created by hand.</h3>")
Response.Write("<table align='center' border='1'>")
For i = 0 To values.GetUpperBound(0)
Response.Write("<tr>")
For j = 0 To values.GetUpperBound(1)
Select Case values(i, j).GetType.Name
Case "String"
Response.Write("<td style='color:blue; background: lightyellow'>" & values(i, j) & "</td>")
Case "Int32"
Select Case values(i, j)
Case Is < 0
Response.Write("<td style='color: red; background:lightyellow'>" & values(i, j) & "</td>")
Case Is >= 0
Response.Write("<td style='color: black'>" & values(i, j) & "</td>")
End Select
End Select
Next
Response.Write("<tr>")
Next
Response.Write("</table><br>")
End Sub
这种方式代码较为复杂,需要手动处理 HTML 标签和样式,维护起来比较困难。
-
使用
HtmlTextWriter创建表格 :在showTable2方法中,使用HtmlTextWriter和 HTML 控件来生成表格。代码如下:
Sub showTable2(ByVal values(,) As Object)
Dim tbl As New HtmlTable()
Dim sb As New StringBuilder(3000)
Dim sw As New StringWriter(sb)
Dim htw As New HtmlTextWriter(sw)
Dim i, j As Integer
Dim row As HtmlTableRow
Dim cell As HtmlTableCell
tbl.Border = 1
tbl.Align = "center"
Response.Write("<h3>This table was written with HTML created by an HtmlTextWriter</h3>")
For i = 0 To values.GetUpperBound(0)
row = New HtmlTableRow()
tbl.Rows.Add(row)
For j = 0 To values.GetUpperBound(1)
cell = New HtmlTableCell()
Select Case values(i, j).GetType.Name
Case "String"
cell.Attributes.Add("style", "color:blue; background:lightYellow")
Case "Int32"
Select Case values(i, j)
Case Is < 0
cell.Attributes.Add("style", "color:red; background:lightYellow")
Case Is >= 0
cell.Attributes.Add("style", "color:black; background:white")
End Select
End Select
cell.InnerText = values(i, j).ToString
row.Cells.Add(cell)
Next
Next
tbl.RenderControl(New HtmlTextWriter(sw))
Response.Write(sb.ToString)
End Sub
这种方式使用了 HTML 控件和
HtmlTextWriter
,代码更加清晰,易于维护。通过设置控件的属性和方法,可以方便地对表格进行格式化和修改。
7. 整体流程梳理
为了更清晰地理解整个操作流程,下面通过一个 mermaid 流程图来展示从应用程序启动到创建表格并输出的过程。
graph TD;
A[应用程序启动] --> B[创建 counters 子目录];
B --> C[初始化页面计数器];
C --> D[页面请求];
D --> E[锁定应用程序对象];
E --> F[获取计数器值];
F --> G[计数器值加 1];
G --> H[保存更新后的计数器值];
H --> I[解锁应用程序];
I --> J[生成随机数据];
J --> K[创建表格];
K --> L[选择手动编写 HTML 或使用 HtmlTextWriter];
L --> M[输出表格到页面];
N[应用程序结束] --> O[将计数器值写入文件];
8. 总结与建议
通过以上内容的介绍,我们了解了文件和目录的创建、数据的写入、二进制文件的读写、内存数据的写入、HTML 的格式化以及随机数据生成和表格创建等操作。在实际开发中,我们可以根据具体需求选择合适的方法。
-
文件操作
:在创建文件时,要确保文件所在的目录已经存在,可使用
DirectoryInfo类的Create方法创建目录。写入文件时,根据数据类型选择BinaryWriter或StreamWriter。 -
HTML 格式化
:手动编写 HTML 代码在处理复杂表格时会变得繁琐,建议使用
HtmlTextWriter和 HTML 控件来生成 HTML,提高代码的可维护性。 -
随机数据生成
:使用
Random类可以方便地生成随机数据,根据需要设置随机数的范围。
总之,合理运用这些技术可以提高开发效率,使代码更加健壮和易于维护。在实际应用中,还需要注意错误处理和资源管理,确保程序的稳定性和可靠性。例如,在文件操作中,要捕获可能出现的异常并进行相应的处理;在使用
StreamWriter
和
FileStream
时,要及时关闭资源,避免资源泄漏。

被折叠的 条评论
为什么被折叠?



