i just would like to be sure whether i missed something in my code or not. I want to validate before moving my files from one folder to another that file is image. I prepared this function and usegae like below. Can you please tell me is it ok? Do i need some dispose or anything else or its just quit enought. many thanks, cheers.
Function IsValidImage(filename As String) As Boolean
Try
Dim img As System.Drawing.Image = System.Drawing.Image.FromFile(filename)
img.Dispose()
Catch generatedExceptionName As OutOfMemoryException
' Image.FromFile throws an OutOfMemoryException
' if the file does not have a valid image format or
' GDI+ does not support the pixel format of the file.
'
Return False
End Try
Return True
End Function
If IsValidImage("c:\path\to\your\file.ext") Then
'do something
'
Else
'do something else
'
End If
Let the file path be "D:\web\sample\Image\my.Image.png" then you can check whether the file is an image file or not using the following code:
Dim filepath As String = "D:\web\sample\Image\my.Image.png"
Dim imageExtensions() As String = {"bmp", "gif", "jpg", "png", "psd", "psp", "thm", "tif", "yuv"}
Dim pat As String = "\\(?:.+)\\(.+)\.(.+)"
Dim r As Regex = New Regex(pat)
Dim m As Match = r.Match(filepath)
If imageExtensions.Contains(m.Groups(2).Captures(0).ToString()) Then
MsgBox("valid Image")
End If
You are on the right way, but you should make up your mind what you want to whant to gain:
If you want to develop a method telling you wheter the content of a file is considered a .Net recognized picture image, your approach is totally fine.
I start with your (slightly) overworked code:
Function IsValidImage(filename As String) As Boolean
Try
Using img As System.Drawing.Image = System.Drawing.Image.FromFile(filename)
' the file could be opened as image so it is valid
Return True
End Using
Catch notValidException As OutOfMemoryException
' Image.FromFile throws an OutOfMemoryException
' if the file does not have a valid image format or
' GDI+ does not support the pixel format of the file.
'
Return False
End Try
' Every other Exception is considered not to be able too look whether the
' file is an Image or not, so it should be thrown to outside
End Function
Don't misjudge this approach as using Exception for control flow, you are only reacting to the one thrown if the content of the file is not usable for creating an Image. This let's the decision on the framework whether the file is valid for an Imageor not.
Let's refine your Method a little bit, so that you can determine wheter the image in the file does not exceed a given size:
Function IsValidImage(filename As String, maxSize As Size) As Boolean
Try
Using img As System.Drawing.Image = System.Drawing.Image.FromFile(filename)
' Returns True if the image is smaller or equal than maxSize
Return img.Size.Width <= maxSize.Width AndAlso
img.Size.Height <= maxSize.Height
End Using
Catch notValidException As OutOfMemoryException
Return False
End Try
End Function
Also this is not a misuse of Exceptions. It is a practice of fail fast: if I can't get an Image the file is not an Image. Otherwise I check the dimension on the opened Image, making my outcome dependent on operations done with it.
Misusing an Exception for control flow could, but must not be the following:
Sub CheckImage(filename As String)
Try
Using img As System.Drawing.Image = System.Drawing.Image.FromFile(filename)
End Using
Catch notValidException As OutOfMemoryException
Throw New FileIsNoImageException()
End Try
End Sub
Try
CheckImage("c:\path\to\your\file.ext")
'do something
'
Catch invalid As FileIsNoImageException
'do something else
'
End Try
Even this approach has a valid usage if you consider a file not beeing an Image as an error.
But normaly you would do this in functions which give you the Image as return value.
But this is a tottaly no go:
Sub CheckImage(filename As String)
Try
Using img As System.Drawing.Image = System.Drawing.Image.FromFile(filename)
Throw New FileIsImageException() ' DON'T DO SUCH A CRAP
End Using
Catch notValidException As OutOfMemoryException
Throw New FileIsNoImageException()
End Try
End Sub
Try
CheckImage("c:\path\to\your\file.ext")
Catch valid As FileIsImageException
'do something
'
Catch invalid As FileIsNoImageException
'do something else
'
End Try
#Tim, I beg your pardon, but I can't hear this Exception use is a bad practice tale any more.
Related
I get the feeling this is something really simple, but I've tried I don't know how many permutations of vbNewLine, Environment.NewLine, sMessage & vbNewLine (or Environment.Newline) I've tried, or how many pages on this site, or through Google I've looked at but nothing has worked.
I even tried getting help from a VB.Net discord channel I'm a part of and they suggested to do the same things that I've done and the procedure is still writing each new log entry at the end of the previous one in a continuous string. My writer is below. Am I missing something simple?
Edit: The code that worked is below in case anyone else comes along with the same issue. If you want to see the original code it's in the edit log.
Option Explicit On
Imports System.IO
Public Class WriteroLog
Public Shared Sub LogPrint(sMessage As String)
Dim AppPath As String = My.Application.Info.DirectoryPath
If File.Exists($"{AppPath}\Log.txt") = True Then
Try
Using objWriter As StreamWriter = File.AppendText($"{AppPath}\Log.Txt")
objWriter.WriteLine($"{Format(Now, "dd-MMM-yyyy HH:mm:ss")} – {sMessage}")
objWriter.Close()
End Using
Catch ex As Exception
MsgBox(ex)
Return
End Try
Else
Try
Using objWriter As StreamWriter = File.CreateText($"{AppPath}\Log.Txt")
objWriter.WriteLine($"{Format(Now, "dd-MMM-yyyy HH:mm:ss")} – {sMessage}")
objWriter.Close()
End Using
Catch ex As Exception
MsgBox(ex)
Return
End Try
End If
End Sub
End Class
The File.AppendText() method creates a new StreamWriter that is then used to append Text to the specified File.
Note, reading the Docs about this method, that you don't need to verify whether the File already exists: if it doesn't, the File is automatically created.
As a side note, when creating a Path, it's a good thing to use the Path.Combine method: it can prevent errors in the path definition and handles platform-specific formats.
Your code could be simplified as follows:
Public Shared Sub LogPrint(sMessage As String)
Dim filePath As String = Path.Combine(Application.StartupPath, "Log.Txt")
Try
Using writer As StreamWriter = File.AppendText(filePath)
writer.WriteLine($"{Date.Now.ToString("dd-MMM-yyyy HH:mm:ss")} – {sMessage}")
End Using
Catch ex As IOException
MsgBox(ex)
End Try
End Sub
The File.CreateText does not assign result to "objWrite", should be:
objWriter = File.CreateText($"{AppPath}\Log.Txt")
Not really sure if this is the root of your problem, but it is an issue.
In essences, your logic is re-opening or creating the stream "objWriter" for every call to this method. I would recommend you initialize "objWriter" to Nothing and only define if it is Nothing.
Set to Nothing as below.
Shared objWriter As IO.StreamWriter = Nothing
Then add check for Nothing in logic.
When image field property in class is set with the image raw format of the same image from my database in picture box, it always throws this exception. In contrast, if the image in the picture box has been updated with one I select from my local PC directory, the update function work fine.
Below is my code:
Try
With mEmployee
If Miscellaneous.GetImageName(ofdPhoto).ToLower = "No_Photo.jpg".ToLower Then
.Image = Nothing
Else
Dim stream As New MemoryStream
pbImage.Image.Save(stream, pbImage.Image.RawFormat)
.Image = stream.GetBuffer()
End If
End With
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
Now everything has solved. This GDI+ generic error caused by the picture box itself. Actually, When I bound the record with image from the database and update that record without updating the image in the PictureBox, the image field has been set with old byte() data from the box, and that caused the error.
To solve this, I have declare a byte() type variable to store the temp image byte() data from the database, and when update, if the image has not been changed it will be set with the data from that variable.
This is my code that solve everything:
Try
If Miscellaneous.GetImageName(ofdPhoto).ToLower = "No_Photo.jpg".ToLower Then
.Image = Nothing
Else
If isImageChanged = True Then
Dim stream As New MemoryStream
pbImage.Image.Save(stream, pbImage.Image.RawFormat)
.Image = stream.GetBuffer()
isImageChanged = False
ElseIf isRemoveImage = True Then
.Image = Nothing
isRemoveImage = False
Else
.Image = tempImage
End If
End If
Catch ex As Exception
MessageBox.Show(ex.Message)
End Try
I am currently working on a console application to play a freshly created WAV RIFF file, and then delete it. Like I said, it is freshly created, so I need to make sure the file isn't being edited before I start playing it or it will be corrupted. After it plays, I delete it.
Currently, my code looks like this (using System.IO):
Sub Main()
Dim fileName As String
fileName = "C:\temp\Burst\Burst.wav"
While CheckFile(fileName)
End While
Try
My.Computer.Audio.Play(fileName, AudioPlayMode.WaitToComplete)
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try
My.Computer.FileSystem.DeleteFile(fileName)
End Sub
Private Function CheckFile(ByVal filename As String) As Boolean
Try
System.IO.File.Open(filename, IO.FileMode.Open, IO.FileAccess.Read, IO.FileShare.None)
FileClose(1)
Return False
Catch ex As Exception
Return True
End Try
End Function
The function I am using to check if the file is opened was created by sealz. I found it here. Unfortunately, however, this function is causing an exception in that after it runs, the program cannot access the file because it is being used by another process. If I remove this function, the file can be opened, played and deleted.
The exception reads as follows:
An unhandled exception of type'System.IO.IOException' occurred in mscorlib.dll Additionalinformation: The process cannot access the file 'C:\temp\Burst\burst.wav' because it is being used by another process.
So the function that is supposed to help determine if the file is being used, is actually causing the file to be opened. It seems like it isn't closing. Is there anyway I can modify this current function to work properly for my application or are there any other ideas on how to tackle this. Thanks for your time.
-Josh
Here is your problem:
System.IO.File.Open(filename, IO.FileMode.Open, IO.FileAccess.Read, IO.FileShare.None)
FileClose(1)
Return False
A Using will help:
Using _fs as System.Io.FileStream = System.IO.File.Open(filename, IO.FileMode.Open, IO.FileAccess.Read, IO.FileShare.None)
End Using
Return False
File.Open Returns a Filestream, not an Integer needed for FileClose
As far as I get you are trying to check if file exists before playback using System.IO.File.Open however you may do it with File.Exists.
Method File.Exists from System.IO returns true if file exists on path and returns false the otherwise.
Also you are doing it wrong here,
While CheckFile(fileName)
End While
If file is found it will enter into an infinite loop without doing anything other than calling CheckFile repeatedly. If file is not found, it will get out of loop and attempt Audio.Play and FileSystem.DeleteFile and you end up getting a file not found exception.
Here is your code modified and working.
Imports System.IO
Module Module1
Sub Main()
Dim fileName As String
fileName = "C:\temp\Burst\Burst.wav"
While CheckFile(fileName)
Try
My.Computer.Audio.Play(fileName, AudioPlayMode.WaitToComplete)
'Delete statement here if you want file to be deleted after playback
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try
End While
My.Computer.FileSystem.DeleteFile(fileName)
Console.ReadLine()
End Sub
Private Function CheckFile(ByVal filename As String) As Boolean
If (File.Exists(filename)) Then
Return True
Else
Return False
End If
End Function
End Module
I really can not understand why the exception is triggered.
I created this code that performs some checks for the correctness of the license.
The function isittrial occurs if the trial software is creating a hidden file, this file is then checked with File.exist.
The problem is the following:
the file is created by isittrial but for some strange reason you enable the exception of file.exist, what can I do to fix it?
I really can not understand why it does not work.
isittrial() 'this function make the file to check
Dim percorsoCompleto As String = System.Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\Software\cc.txt"
Try
If My.Computer.FileSystem.FileExists(directory) Then
Dim fileReader As String
Dim dire As String = System.Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\Software\cc.txt"
fileReader = My.Computer.FileSystem.ReadAllText(directory,
System.Text.Encoding.UTF32)
Dim check = DeCryptIt(fileReader, "aspanet")
Dim datadecripted As String = DeCryptIt(Registry.GetValue("HKEY_CURRENT_USER\Software\cc", "end", ""), "aspanet")
If Date.Now < check And check <> datadecripted Then
MsgBox("License not valid", MsgBoxStyle.Critical, "Attention!")
DeActivate()
ForceActivation()
Else
End If
Else
MsgBox("License not valid", MsgBoxStyle.Critical, "Attention!")
DeActivate()
ForceActivation()
End If
Catch ex As Exception
MsgBox("License not valid", MsgBoxStyle.Critical, "Attention!")
'DeActivate()
'ForceActivation()
End Try
This line
If My.Computer.FileSystem.FileExists(directory) Then
seems to test for the existence of a file passing the name of a directory (or an empty string or whatever, we can see how this variable is initialized). In every case the result will be false.
Then your code jumps to an else block with the same error message of the exception fooling your perception of the error.
Try instead
Dim percorsoCompleto As String = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)
percorsoCompleto = Path.Combine(percorsoCompleto, "Software", "cc.txt")
Try
If My.Computer.FileSystem.FileExists(percorsoCompleto) Then
Dim fileReader As String
fileReader = My.Computer.FileSystem.ReadAllText(percorsoCompleto,
System.Text.Encoding.UTF32)
.....
Notice that I have removed the path concatenation with a more fail safe call to Path.Combine
Is there a method to verify that a file is open? The only thing I can think of is the Try/Catch to see if i can catch the file-open exception but I figured that a method be available to return true/false if file is open.
Currently using System.IO and the following code under class named Wallet.
Private holdPath As String = "defaultLog.txt"
Private _file As New FileStream(holdPath, FileMode.OpenOrCreate, FileAccess.ReadWrite)
Private file As New StreamWriter(_file)
Public Function Check(ByVal CheckNumber As Integer, ByVal CheckAmount As Decimal) As Decimal
Try
file.WriteLine("testing")
file.Close()
Catch e As IOException
'Note sure if this is the proper way.
End Try
Return 0D
End Function
Any pointers will be appreciated! Thank you!!
Private Sub IsFileOpen(ByVal file As FileInfo)
Dim stream As FileStream = Nothing
Try
stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None)
stream.Close()
Catch ex As Exception
If TypeOf ex Is IOException AndAlso IsFileLocked(ex) Then
' do something here, either close the file if you have a handle, show a msgbox, retry or as a last resort terminate the process - which could cause corruption and lose data
End If
End Try
End Sub
Private Shared Function IsFileLocked(exception As Exception) As Boolean
Dim errorCode As Integer = Marshal.GetHRForException(exception) And ((1 << 16) - 1)
Return errorCode = 32 OrElse errorCode = 33
End Function
Call it like this:
Call IsFileOpen(new FileInfo(filePath))
There is really no point using a 'is file in use check' function since you will still need to have try catch to handle the case that the file fails to open. The file open can fail for many more reasons than it just being already open.
Also using a function to do a check is no guarantee of success. The 'is file in use check' might return false only for the file open to fail with a file already open error, because in time between the check and trying to open the file it was opened by someone else.
It looks like the two suggestions from this MSDN forum posting both involve trying to open the file.
The first one is similar to what you are doing now, and the second involves using a Windows API function (CreateFile) and checking for a invalid handle signifying the file is in use. In both cases they are relying on an error condition to determine if the file is open or not. In short, in my opinion the method you are using is correct since there is not a System.IO.File.IsOpen property.