VB.NET Create temp file marked for removal 01-02-2011, 06:46 AM
#1
Note that the code presented will work in versions of Visual Studio prior to VS2008 but will need to be altered as there are things like language extensions used in the code below which were new to Visual Studio as of VS2008 but the underlying code can and does work with VS2005, not sure about VS2003.
I have attached a demo VS2008 project.
There are times when developers need a temporary file created to do some work during the execution of a task followed by removing the file once the task has been completed. If the program crashes before you clean code (code to remove the temp file) runs to remove the file then it will be left behind. I know several developers this has happened to and ended up having to write code to get these files and remove them. The code presented below demonstrates how to mark a temporary file as remove when the application closes or you close the FileStream (wrapped in a language extension), which created the file. For precautions, it might be worth giving the file created by the FileStream a unique name so in the code the file name a random name using a language extension.
Create a button on a form called cmdCreateAndRemoveTempFileOnClose and place the following code into the click event
Create a code module and place the following into it
In the form you placed the first button add another button and call it cmdCreateAndRemoveTempFileOnClose2 with the code below for the click event
The second button code above removes the temp file when the FileStream is closed
Add another code module for my My Namespace addition for a message box wrapper for asking users a question (I have many more but this is all that is needed for the demo).
File contents
I have attached a demo VS2008 project.
There are times when developers need a temporary file created to do some work during the execution of a task followed by removing the file once the task has been completed. If the program crashes before you clean code (code to remove the temp file) runs to remove the file then it will be left behind. I know several developers this has happened to and ended up having to write code to get these files and remove them. The code presented below demonstrates how to mark a temporary file as remove when the application closes or you close the FileStream (wrapped in a language extension), which created the file. For precautions, it might be worth giving the file created by the FileStream a unique name so in the code the file name a random name using a language extension.
Create a button on a form called cmdCreateAndRemoveTempFileOnClose and place the following code into the click event
Code:
Private Sub cmdCreateAndRemoveTempFileOnClose_Click( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles cmdCreateAndRemoveTempFileOnClose1.Click
Dim TempFileName As String = Application.StartupPath & "\K1".GenerateRandomXmlFile(5)
Dim Creator1 As System.IO.FileStream = FileStreamDeleteOnClose(TempFileName)
' This could come say from a physical XML file in which case you could
' read in using XDocument.Load(SomeFileName) then get the string representation
' of the file contents and pass on to ByteArray variable below.
Dim XmlData = _
<?xml version="1.0" standalone="yes"?>
<Customers>
<Customer>
<CustomerID>ALFKI</CustomerID>
<CompanyName>Alfreds Futterkiste</CompanyName>
</Customer>
<Customer>
<CustomerID>ANATR</CustomerID>
<CompanyName>Ana Trujillo Emparedados y helados</CompanyName>
</Customer>
<Customer>
<CustomerID>BOLID</CustomerID>
<CompanyName>Bilido Comidas preparadas</CompanyName>
</Customer>
<Customer>
<CustomerID>CENTC</CustomerID>
<CompanyName>Centro comercial Moctezuma</CompanyName>
</Customer>
</Customers>
Dim ByteArray As Byte() = System.Text.Encoding.ASCII.GetBytes(XmlData.ToString)
Creator1.Write(ByteArray, 0, ByteArray.Length)
Dim Reader As System.IO.StreamReader
Reader = New System.IO.StreamReader(Creator1)
Reader.BaseStream.Seek(0, IO.SeekOrigin.Begin)
Dim CustomerData As String = ""
While (Reader.Peek > -1)
CustomerData &= Reader.ReadLine
End While
Dim Customers = (From customer In XDocument.Parse(CustomerData)...<Customer> _
Select Name = customer.<CompanyName>.Value, _
Identifier = customer.<CustomerID>.Value).ToList
' Show the customer we just read in
For Each C In Customers
Console.WriteLine("ID=[{0}] Company [{1}]", C.Identifier, C.Name)
Next
If IO.File.Exists(TempFileName) Then
If My.Dialogs.Question("Open Explorer to see~'" & _
IO.Path.GetFileName(TempFileName) & _
"'~exists and goes away when app closes?") Then
Process.Start(Application.StartupPath)
End If
Else
MsgBox("Does not exists")
End If
End SubCreate a code module and place the following into it
Code:
Module Various
<System.Diagnostics.DebuggerStepThrough()> _
<System.Runtime.CompilerServices.Extension()> _
Public Function GetSingleRandom(Of T)(ByVal sender As IEnumerable(Of T)) As T
Dim r As New Random(DateTime.Now.Millisecond)
Dim Position As Integer = r.Next(sender.Cast(Of T).Count)
Return sender.ElementAt(Position)
End Function
''' <summary>
''' Creates a file stream which will be removed from disk when the application closes
''' </summary>
''' <param name="FileName"></param>
''' <returns>FileStream marked for removal when app closes</returns>
''' <remarks></remarks>
Public Function FileStreamDeleteOnClose(ByVal FileName As String) As System.IO.FileStream
Dim Result As New System.IO.FileStream(FileName, _
System.IO.FileMode.Create, _
System.Security.AccessControl.FileSystemRights.Modify, _
System.IO.FileShare.None, _
8, _
System.IO.FileOptions.DeleteOnClose)
System.IO.File.SetAttributes(Result.Name, _
System.IO.File.GetAttributes(Result.Name) Or _
System.IO.FileAttributes.Temporary)
Return Result
End Function
<System.Diagnostics.DebuggerStepThrough()> _
<System.Runtime.CompilerServices.Extension()> _
Public Function GenerateRandomFile(ByVal sender As String, ByVal Length As Integer) As String
Return GenerateRandomBaseName(Length)
End Function
<System.Diagnostics.DebuggerStepThrough()> _
<System.Runtime.CompilerServices.Extension()> _
Public Function GenerateRandomFile(ByVal sender As String, ByVal Length As Integer, ByVal Extension As String) As String
If Not Extension.StartsWith(".") Then
Extension = String.Concat(".", Extension)
End If
Return sender & GenerateRandomBaseName(Length) & Extension.ToUpper
End Function
<System.Diagnostics.DebuggerStepThrough()> _
<System.Runtime.CompilerServices.Extension()> _
Public Function GenerateRandomTextFile(ByVal sender As String, ByVal Length As Integer) As String
Return sender & GenerateRandomBaseName(Length) & ".TXT"
End Function
<System.Diagnostics.DebuggerStepThrough()> _
<System.Runtime.CompilerServices.Extension()> _
Public Function GenerateRandomXmlFile(ByVal sender As String, ByVal Length As Integer) As String
Return sender & GenerateRandomBaseName(Length) & ".XML"
End Function
<System.Diagnostics.DebuggerStepThrough()> _
Private Function GenerateRandomBaseName(ByVal Length As Integer) As String
Dim rand As Random = New Random()
Return CStr(Enumerable.Range(0, Length).Select(Function(i) (Chr(Asc("A") + rand.Next(0, 26)))).ToArray)
End Function
End ModuleIn the form you placed the first button add another button and call it cmdCreateAndRemoveTempFileOnClose2 with the code below for the click event
Code:
Private Sub cmdCreateAndRemoveTempFileOnClose2_Click( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles cmdCreateAndRemoveTempFileOnClose2.Click
Dim TempFileName As String = Application.StartupPath & "\K1".GenerateRandomXmlFile(5)
Dim Creator1 As System.IO.FileStream = FileStreamDeleteOnClose(TempFileName)
' This could come say from a physical XML file in which case you could
' read in using XDocument.Load(SomeFileName) then get the string representation
' of the file contents and pass on to ByteArray variable below.
Dim XmlData = _
<?xml version="1.0" standalone="yes"?>
<Customers>
<Customer>
<CustomerID>ALFKI</CustomerID>
<CompanyName>Alfreds Futterkiste</CompanyName>
</Customer>
<Customer>
<CustomerID>ANATR</CustomerID>
<CompanyName>Ana Trujillo Emparedados y helados</CompanyName>
</Customer>
<Customer>
<CustomerID>BOLID</CustomerID>
<CompanyName>Bilido Comidas preparadas</CompanyName>
</Customer>
<Customer>
<CustomerID>CENTC</CustomerID>
<CompanyName>Centro comercial Moctezuma</CompanyName>
</Customer>
</Customers>
Dim ByteArray As Byte() = System.Text.Encoding.ASCII.GetBytes(XmlData.ToString)
Creator1.Write(ByteArray, 0, ByteArray.Length)
Dim Reader As System.IO.StreamReader
Reader = New System.IO.StreamReader(Creator1)
Reader.BaseStream.Seek(0, IO.SeekOrigin.Begin)
Dim CustomerData As String = ""
While (Reader.Peek > -1)
CustomerData &= Reader.ReadLine
End While
Dim Customers = (From customer In XDocument.Parse(CustomerData)...<Customer> _
Select Name = customer.<CompanyName>.Value, _
Identifier = customer.<CustomerID>.Value).ToList
' Show the customer we just read in
For Each C In Customers
Console.WriteLine("ID=[{0}] Company [{1}]", C.Identifier, C.Name)
Next
If IO.File.Exists(TempFileName) Then
MsgBox("Temp file exits, will now close it.")
Else
MsgBox("Does not exists")
End If
Creator1.Close()
If IO.File.Exists(TempFileName) Then
MsgBox("Temp file exits, it should have been removed")
Else
MsgBox("Does not exists, all worked as expected.")
End If
End SubThe second button code above removes the temp file when the FileStream is closed
Add another code module for my My Namespace addition for a message box wrapper for asking users a question (I have many more but this is all that is needed for the demo).
File contents
Code:
Namespace My
<Global.System.ComponentModel.EditorBrowsable(Global.System.ComponentModel.EditorBrowsableState.Never)> _
Partial Friend Class _Dialogs
Private Function CreateLineBreaks(ByVal Text As String) As String
Return Text.Replace("~", Environment.NewLine)
End Function
''' <summary>
''' Ask question with NO as the default button
''' </summary>
''' <param name="Text"></param>
''' <returns></returns>
''' <remarks></remarks>
Public Function Question(ByVal Text As String) As Boolean
Return (MessageBox.Show(CreateLineBreaks(Text), My.Application.Info.Title, MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) = MsgBoxResult.Yes)
End Function
End Class
<Global.Microsoft.VisualBasic.HideModuleName()> _
Friend Module KSG_Dialogs
Private instance As New ThreadSafeObjectProvider(Of _Dialogs)
ReadOnly Property Dialogs() As _Dialogs
Get
Return instance.GetInstance()
End Get
End Property
End Module
End Namespace
Conflict is inevitable, but combat is optional
My humble self-defense site
Use Option Strict = On when coding with VB.NET
My humble self-defense site
Use Option Strict = On when coding with VB.NET


![[+]](https://sinister.li/images/modern/collapse_collapsed.png)



I need something like this in my ImageViewer.
![[Image: rytwG00.png]](http://i.imgur.com/rytwG00.png)