Question Struggling with DirectoryInfo and FileInfo classes.

Thonord

Member
Joined
Oct 25, 2012
Messages
23
Programming Experience
10+
Hi,I'm an old Clipperhead and vb5+ hobby programmer - now VB.NET wannabe.
I have a bundle of small grafics files, several hundreds, in a number of directories and I want to resize them, maintaining the same filenames and directory structure. I can do it in VB.NET, but my code is still in "VB5 mode".
I want my code to be in the wonder that is VB.NET.


So, I'm using the DirectoryInfo and FileInfo classes, racing through the directories and files, resizing using Rectangles, with only a couple of lines of code - but I have to give the resized file a different name.


For the sake of argument, dealing with only one file: I start with "something.png" in ...SubDir\1.

The Resize Sub resizes something.png and saves something_.png in same Dir.

Private Sub myResize(DirectoryName As String) 'The code is modified from an example at VB-Helper.com
Dim Dir_info As New System.IO.DirectoryInfo(DirectoryName)
Dim MyScale As Single
For Each File_info As System.IO.FileInfo In Dir_info.GetFiles()
Dim ext As String = File_info.Extension


If ext = ".png" Then ' There are other files in same dir I don't want to resize
Dim From_png As New Bitmap(File_info.FullName)
Dim From_rect As New Rectangle(0, 0, From_png.Width, From_png.Height)
MyScale = 100 / From_png.Height ' I change .Height to 100 pix and .Width proportionally


Dim Dest_png As New Bitmap(CInt(MyScale * From_png.Width), 100)
Dim Dest_rect As New Rectangle(0, 0, CInt(MyScale * From_png.Width), 100)
Using g As Graphics = Graphics.FromImage(Dest_png)
g.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
g.DrawImage(From_png, Dest_rect, From_rect, GraphicsUnit.Pixel)
End Using


'Here comes my problem.
'The original file can't be changed. Its "in use". I'm guessing by file_info, so I have tried to -
Dim NewPathAndName As String = File_info.FullName
NewPathAndName = NewPathAndName.Substring(0, NewPathAndName.Length - ext.Length) 'Stripping off the .png
NewPathAndName &= "_" & ext 'Adding _ and putting back the extension


Dest_png.Save(NewPathAndName, System.Drawing.Imaging.ImageFormat.Png)
End If
Next File_info
End Sub

I thought adding this Sub might do the trick


Private Sub DeleteAndRename(DirectoryName As String) ' So, I do the For Each File_info once more
' The directory now contains Something.png (original) and Something_.png (Resized)
Dim Dir_info As New System.IO.DirectoryInfo(DirectoryName)
For Each File_info As System.IO.FileInfo In Dir_info.GetFiles()
Dim ext As String = File_info.Extension
Dim FileName As String = File_info.Name
If ext = ".png" Then
If InStr(FileName, "_") <> 0 Then 'Only respond to the Something_.png, the resized one


'I have tried two alternatives. This one
Dim TempFileName As String = File_info.Name
FileName = Mid(TempFileName, 1, Len(TempFileName) - 5) & ".png" 'Stripping off the "_"
File_info.CopyTo(FileName, True)
'Which, for some reason, puts it into C:\Programmering\VB Express 2010\Development\ResizeImageFile\bin\Debug directory?
'Not the C:\Programmering\VB Express 2010\Development\ResizeImageFile\bin\Debug\SubDir\1 Where I want it.'



'And this one
Dim SamePathAndName As String = File_info.FullName
SamePathAndName = SamePathAndName.Substring(0, SamePathAndName.Length - (ext.Length + 1)) 'Stripping off the _.png
SamePathAndName &= ext
File_info.CopyTo(SamePathAndName, True)
'Which again causes exception:The process cannot access the file
'C:\Programmering\VB Express 2010\Development\ResizeImageFile\bin\Debug\SubDir\1\Something.png'
'because it is being used by another process.


File_info.Delete() 'At least, this works and kills the Something_.png
End If
End If
Next File_info
End Sub
I guess I could make an other sub moving the Someting.png file from Debug to SubDir\1, but I don't feel it to be in the spirit of .NET


Is there any "kosher" .NET way to resize the files and keeping the same name while using Dir- and FileInfo?
 
It's not related to FileInfo, it is this "Dim From_png As New Bitmap(File_info.FullName)" that is locking the source file. Dispose this object and you can overwrite source file.
 
That simple - huh? I should have thought about that - actually I knew that - I mean, I come from an environment where the importance of closing files is second nature.
Guess I thought the garbage collector in .NET was intuitive enough to know when I don't need stuff any more.
Thank you very much.

Slightly embarrassed
Thormod
 
Guess I thought the garbage collector in .NET was intuitive enough to know when I don't need stuff any more.
It is, but at the point where you try to save the source image object is still in scope. Furthermore, you can't anticipate when GC does it's job, and even more so, if you don't dispose objects you are leaving these objects for Finalizer to clean up, which can take several rounds of GC to complete before the unmanaged resources is freed. Always call Dispose when you are done with a disposable object, or consume it with the Using code block.
 
Back
Top