Thursday, January 10, 2013

Read the first line from a text file in the current directory in either C# or VB.

OK, I want to put Sabrina Spielrein's two favorite hobbies in a paragraph on an ASP.NET web form. The copy will mostly come from a text file in the same folder as the ASP.NET web form. I used the word mostly because the hobbies themselves will be injected into the paragraph which will have a sentance in it like so: "Sabrina's favorite hobbies are {1} and {2}, in no particular order." allowing for a String.Format approach to injecting the values for the hobbies which will be driven from the web form's C# code behind which looks like this:

using System;
public partial class SomeFolder_Modern : System.Web.UI.Page
{
   protected void Page_Load(object sender, EventArgs e)
   {
      TemplateParser templateParser = new TemplateParser();
      Label1.Text = templateParser.CraftCopy("suicide", "interplanetary travel",
            
Server.MapPath(System.IO.Path.GetFileName(Request.ServerVariables
            ["SCRIPT_NAME"]
)));
   }
}

 
 

The copy above in black gets the file path to the filename handed to it and the copy in white within black gets the name of the web form itself (Modern.aspx). The real work is done from the TemplateParser class which looks like this:

using System;
using System.IO;
public class TemplateParser
{
   public string CraftCopy(string firstHobby, string secondHobby, string location)
   {
      string templateLocation = "";
      string[] pathParts = location.Split(Path.DirectorySeparatorChar);
      int counter = 0;
      foreach (string pathPart in pathParts)
      {
         counter++;
         if (counter < (pathParts.Length))
         {
            templateLocation = templateLocation + pathPart + Path.DirectorySeparatorChar;
         }
      }
      templateLocation = templateLocation + "HobbyTemplate.txt";
      using (var stream = new StreamReader(templateLocation))
      {
         return String.Format(
stream.ReadLine(), firstHobby, secondHobby);
      }
   }
}

 
 

Alright, in the copy above, before the using statement, we are basically taking the file path to Modern.aspx and trimming off "Modern.aspx" and replacing it with "HobbyTemplate.txt" which I mentioned sits in the same folder. Our cleaned up file path ends up in the templateLocation variable and allows us to create a StreamReader connection. The copy above in black will read the first line out of the file. As it is tied to the return statement (and yes, you can nest the return inside a using statement) it will be the only line read. That means that if there is a second line in the text file reading "Sabrina also likes being punished." that such a line will not make its way back to the web form's label.

The practial application of the read-one-line-but-not-the-other-thing is to use the first line of the text document as a content template and the second line for a note. A better note might denote who the author was or what the purpose of the text file was. I wrote some C# vaguely of this shape at work today as an excerise as I had to really write the code in VB script and I wanted to know how to do the same thing in C#. I know you probably don't care about the VB stuff, but here it is:

Partial Class SomeFolder_Whatever
   Inherits System.Web.UI.Page
   Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
               Handles Me.Load
      Dim templateParser As TemplateParser
      Label1.Text = templateParser.CraftCopy("suicide", "interplanetary travel",
                  Server.MapPath(System.IO.Path.GetFileName(Request.ServerVariables
                  ("SCRIPT_NAME"))))
   End Sub
End Class

 
 

In this version, TemplateParser is very different:

Imports System.IO
Imports Microsoft.VisualBasic
Public Class TemplateParser
   Public Shared Function CraftCopy(ByVal firstHobby As String, ByVal secondHobby
               As String, ByVal location As String) As String
      Dim templateLocation = ""
      Dim pathParts() As String = location.Split(Path.DirectorySeparatorChar)
      Dim counter As Int32 = 0
      For Each pathPart In pathParts
         counter = counter + 1
         If counter < (pathParts.Length) Then
            templateLocation = templateLocation + pathPart + Path.DirectorySeparatorChar
         End If
      Next
      templateLocation = templateLocation + "HobbyTemplate.txt"
      Dim stream = CreateObject("ADODB.Stream")
      stream.Open()
      stream.CharSet = "UTF-8"
      stream.LoadFromFile(templateLocation)
      Dim linesOfCopy As Object
      linesOfCopy = Split(stream.ReadText, vbCrLf)
      stream.Close()
      stream = Nothing
      Return String.Format(linesOfCopy(0), firstHobby, secondHobby)
   End Function
End Class

 
 

Above, I had to call out UTF-8 or the copy that came back from the template would be preceded by three strange characters. vbCrLf seems to allow for splitting at line breaks.

No comments:

Post a Comment