Login Register






VB.NET Create temp file marked for removal filter_list
Author
Message
VB.NET Create temp file marked for removal #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
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 Sub

Create 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 Module

In 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 Sub

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
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

Reply

RE: VB.NET Create temp file marked for removal #2
Awesome stuff keep it up. Smile I need something like this in my ImageViewer.
[Image: rytwG00.png]
Redcat Revolution!

Reply

RE: VB.NET Create temp file marked for removal #3
(01-02-2011, 08:06 AM)Coder Wrote: Awesome stuff keep it up. Smile I need something like this in my ImageViewer.

Speaking of image viewers, here is a language extension
Code:
Module WinControlExtensions <Runtime.CompilerServices.Extension()> _ Public Sub LoadImageClone(ByVal ImageControl As PictureBox, ByVal Path As String) If IO.File.Exists(Path) Then Dim imageClone As Bitmap Dim imageOriginal As System.Drawing.Image = System.Drawing.Image.FromFile(Path) ' create clone, initially empty, same size imageClone = New Bitmap(imageOriginal.Width, imageOriginal.Height) ' get object representing(clone) 's currently empty drawing surface Dim gr As Graphics = Graphics.FromImage(imageClone) gr.SmoothingMode = Drawing2D.SmoothingMode.None gr.InterpolationMode = Drawing2D.InterpolationMode.NearestNeighbor gr.PixelOffsetMode = Drawing2D.PixelOffsetMode.HighSpeed ' copy original image onto this surface gr.DrawImage(imageOriginal, 0, 0, imageOriginal.Width, imageOriginal.Height) gr.Dispose() imageOriginal.Dispose() ' assign the clone to picture box ImageControl.Image = imageClone End If End Sub End Module

Sample usage
Code:
Imports System.IO Public Class Form1 Private Sub cmdImage_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdImage.Click If OpenFileDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then ' Loading this way locks the file 'Dim bm As New Bitmap(OpenFileDialog1.FileName) 'PictureBox1.Image = bm PictureBox1.LoadImageClone(OpenFileDialog1.FileName) End If End Sub Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load OpenFileDialog1.FileName = "" If IO.Directory.Exists("ImagesSafe") Then OpenFileDialog1.InitialDirectory = Application.StartupPath Dim FileList = From item In _ (From file In My.Computer _ .FileSystem.GetFiles("ImagesSafe", _ FileIO.SearchOption.SearchAllSubDirectories, "*.*") _ Select New FileInfo(file)) _ Where item.Extension.ToLower = ".jpg" OrElse item.Extension.ToLower = ".gif" _ Select item For Each file In FileList If Not IO.File.Exists(String.Format("{0}\{1}", Application.StartupPath, file.Name)) Then My.Computer.FileSystem.CopyFile(file.FullName, _ String.Format("{0}\{1}", Application.StartupPath, file.Name)) End If Next End If End Sub Private Sub cmdClose_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdClose.Click Close() End Sub End Class
Conflict is inevitable, but combat is optional
My humble self-defense site
Use Option Strict = On when coding with VB.NET

Reply

RE: VB.NET Create temp file marked for removal #4
Nah, same problem with releasing HDC. If I don't the Billenear filter keeps hogging up memory, 800MB+
[Image: rytwG00.png]
Redcat Revolution!

Reply