26、文件与 HTML 操作全解析:创建、写入与格式化技巧

文件与 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 时,要及时关闭资源,避免资源泄漏。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值