I need to check whether a file (with unknown extension) is a valid SQLite database.
My function works fine, but when it fails, the file is still locked after exiting the function:
Public Function IsSqliteDB(ByVal uPath As String) As Boolean
'Workaround for my problem: Make a copy and work on this because this function is going to lock the file unfortunately
Dim sNewPath As String
sNewPath = Settings.Locations.Folder_LocalAppData_Temp & "\temp_" & Replace(Now.ToString, ":", "_") & ".db"
modIO.FileForceCopy(uPath, sNewPath)
Dim bIsSQLiteDB As Boolean = False
Dim c As New dhRichClient3.cConnection
Dim r As dhRichClient3.cRecordset
Try
Dim b As Boolean = c.OpenDB(sNewPath) 'returns true although this is not an sqlite-db. Can't do anything about it
R = c.OpenRecordset("SELECT * FROM sqlite_master")
bIsSQLiteDB = True
Catch ex As Exception
r = Nothing
c = Nothing
Finally
r = Nothing
c = Nothing
End Try
modIO.DeleteFile(sNewPath)'this fails. File is locked
Return bIsSQLiteDB
End Function
Does anybody see where I could ensure that the file is not locked anymore? Or do I really have to work with a copy of the file because the behaviour of the COM component is not really known (closed source unfortunately)?
I could indeed work with a backup, but the file may be really large (> 1 GB), so I would like to avoid making a copy to work on if I could avoid it.
There is no "close" function in dhRichClient. "Close" is called internally once the cConection goes out out scope, I guess. Calling GC.Collect() at the end of the function does not help.
To determine if a file is an SQLite database, just check the first 16 bytes of the database header.
from tmighty's comment:
Public Function IsSqliteDB(ByVal uPath As String) As Boolean
Dim bytes(16) As Byte
Using fs As New IO.FileStream(uPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
fs.Read(bytes, 0, 16)
End Using
Dim text As String = System.Text.ASCIIEncoding.ASCII.GetString(bytes)
Return text.Contains("SQLite format")
End Function
Related
I am trying to upload a csv file that has two records in it.
The below code executed for two times and third time I got this exception----Conversion of type string " " to double not valid
I put a debugger where I found the values of two colums of excel sheet but third time I am getting this exception. Your help is highly appreciated.
Below is the code.
Public Function GetLocationInformation(stream As Stream) As List(Of CsvPropLocation) _
Implements ICsvHandling.GetLocationInformation
If stream Is Nothing Then Return Nothing
Dim locations = New List(Of CsvPropLocation)
Using reader = New StreamReader(stream)
Dim config = New CsvConfiguration(CultureInfo.InvariantCulture) With {
.HasHeaderRecord = True,
.IgnoreBlankLines = False
}
Using csv = New CsvReader(reader, config)
Using dataReader As New CsvDataReader(csv)
Dim dt = New DataTable()
dt.Load(dataReader)
For Each row As DataRow In dt.Rows
Dim propLocation As CsvPropLocation
'find or create a propLocation
If locations.Any(Function(x) x.nLocationNumber = row("LocNum")) Then ######Got exception here ######
propLocation = locations.First(Function(x) x.nLocationNumber = row("LocNum"))
Else
propLocation = New CsvPropLocation(row("LocNum"))
locations.Add(propLocation)
End If
'do building stuff.
Dim building = ParseRowIntoBuilding(row)
propLocation.AddBuilding(building)
Next
End Using
End Using
End Using
Return locations
End Function
Change your line to
Dim number As Double
If Double.TryParse(row("LocNum"), number ) AndAlso locations.Any(Function(x) x.nLocationNumber = number )
This way you make sure number will be evaluated only if it gets a valid value from row("LocNum")
Also keep in mind the Else part must be controlled as New CsvPropLocation(row("LocNum")) probably is expecting a valid Double which isnt inside locations so, change to:
Else If Double.TryParse(row("LocNum"), number ) 'You can check against number = 0
'if zero isn't a valid value for number
'(or initialize number to a known invalid value and check against it)
'if yuo didn't want a double try parse
propLocation = New CsvPropLocation(number)
locations.Add(propLocation)
End If
I am writing a simple application that copies files recursively from one directory to another. The application has a checkbox where the user can choose to overwrite the destination files if they exist. If the file exists, and overwrite is deselected, then the catch statement should exit the function and return 1, so that the main code can handle the error.
Dim result As Integer
Dim sourceDirectoryInfo As New System.IO.DirectoryInfo(sourcePathHere)
' If the destination folder doesn't exist then create it
If Not System.IO.Directory.Exists(destinationPathHere) Then
System.IO.Directory.CreateDirectory(destinationPathHere)
End If
Dim overwriteHere As Boolean
If chkOverwrite.Checked = True Then
overwriteHere = True
Else
overwriteHere = False
End If
Dim fileSystemInfo As System.IO.FileSystemInfo
Try
For Each fileSystemInfo In sourceDirectoryInfo.GetFileSystemInfos
Dim destinationFileName As String =
System.IO.Path.Combine(destinationPathHere, fileSystemInfo.Name)
' Now check whether its a file or a folder and take action accordingly
If TypeOf fileSystemInfo Is System.IO.FileInfo Then
System.IO.File.Copy(fileSystemInfo.FullName, destinationFileName, overwriteHere)
Else
' Recursively call the mothod to copy all the nested folders
CopyDirectory(fileSystemInfo.FullName, destinationFileName)
End If
Next
result = 0
Catch
txtStatus.Text = "Error"
result = 1
End Try
'MsgBox(result) <=For Testing
Return result
End Function
I would expect that since the catch is outside the for Each loop, once the catch is hit it should set result to 1 and return from the function. However, when putting a MsgBox there, I'm seeing the box appear 9 times as follows:
1,1,1,0,1,1,0,0
These results don't seem to correspond to my source files at all.
Since the last result is returning 0, the main code completes as if there was no error. Why isn't my code breaking out of the For Each loop (or maybe something else is happening here)?
There are no other loops in the code calling the function, it is called as follows:
Dim success As Integer = CopyDirectory(sourcePath, destinationPath)
Thanks Chris Dunaway, the problem was that the function is recursive, so when the Return is called, it just goes up one level of the function but continues. I fixed that by creating an error flag, that once set to true, will persist throughout all the iterations of the function so that it exits gracefully from all of them:
Public Function CopyDirectory(ByVal sourcePathHere As String, ByVal destinationPathHere As String, Optional overwriteFiles As Boolean = False, Optional errFlag As Boolean = False) As Boolean
Dim sourceDirectoryInfo As New System.IO.DirectoryInfo(sourcePathHere)
' If the destination folder doesn't exist then create it
If Not System.IO.Directory.Exists(destinationPathHere) Then
System.IO.Directory.CreateDirectory(destinationPathHere)
End If
Dim fileSystemInfo As System.IO.FileSystemInfo
Try
For Each fileSystemInfo In sourceDirectoryInfo.GetFileSystemInfos
Dim destinationFileName As String =
System.IO.Path.Combine(destinationPathHere, fileSystemInfo.Name)
' Now check whether its a file or a folder and take action accordingly
If TypeOf fileSystemInfo Is System.IO.FileInfo Then
System.IO.File.Copy(fileSystemInfo.FullName, destinationFileName, overwriteFiles)
Else
' recursive call of the function, accepting the return with the errFlag will stop the function from running again.
errFlag = CopyDirectory(fileSystemInfo.FullName, destinationFileName, overwriteFiles, errFlag)
End If
Next
Catch
txtStatus.Text = "Error"
errFlag = True
End Try
Return errFlag
End Function
I want to know if folder (subfolder) exist in google drive or not , after searching in this page , i try to do it , i create a boolean function which return true if folder exist .
here is a code of boolean function
Public Function exist(v As String) As Boolean
Dim pag As String
Dim req = Service.Files.List()
req.Q = "application/vnd.google-apps.folder"
req.PageToken = pag
Dim result = req.Execute()
If (result.NextPageToken IsNot Nothing) Then
Return False
Else
Return True
End If
End Function
and here how i call it
If (exist(dat_sauv.SelectedItem) = False) Then
MessageBox.Show("folder exist")
End If
the exception is
exception has declenched in exist method in this insctruction
Dim result = req.Execute()
is my method correct or not ? can you help me
There are two problems with your code.
Improper query
Your line req.Q = "application/vnd.google-apps.folder"
should be
req.Q = "mimeType='application/vnd.google-apps.folder' and name = '"+v+"' and trashed=false"
You'll probably need to tidy up the quoting and escaping (ie Don't copy/paste and expect it to work first time)
use of nextPageToken
The presence of the folder will not be indicated by the presence of nextpageToken. Instead, you need to check the files array within the response for >0 elements.
I am trying to find the size of a file in my FELC. I have used the following code but I keep getting an error. This is the code in my script task.
Public Sub Main()
Dim LoopFilePath As String = Dts.Variables("User::vvarcharsource").Value.ToString
Dim infoReader As System.IO.FileInfo
infoReader = My.Computer.FileSystem.GetFileInfo(LoopFilePath)
Dts.Variables("User::vintsize").Value = infoReader.Length
Dts.TaskResult = ScriptResults.Success
End Sub
I use one read variable vvarcharsource that is of type varchar and one readwrite variable vintsize that is of type double.
The error I'm getting is:
Exception has been thrown by the target of an invocation.
i do not entirely get what you are trying to do here.
What is this "DTS variable" consting of ?
Also i do not know what you mean with FELC
(google says First English Lutheran church or other stuff so an explanation would be good ;) )
Maybe you split it into more single functions to see where exactly it fails, it is gonna be hard to get what happens at the moment
I'd put the filesize-part into something like this (you might even want to build a function that returns the values you want)
Public Sub GetFileInfo(ByVal Path As String)
If System.IO.File.Exists(Path) Then
Dim Fi As New FileInfo(Path)
Dim FileSize As Long
Dim FilsizeInt As Integer
FileSize = Fi.Length
FilsizeInt = CInt(Math.Round(FileSize / 1024))
MsgBox("filesize is about " & FilsizeInt & " kb")
Else
MsgBox("file not found")
End If
End Sub
hth
Converting datatype of User::vintsize to varchar solved the problem
I have a database with about 180,000 records. I'm trying to attach a pdf file to each of those records. Each pdf is about 250 kb in size. However, after about a minute my program starts taking about about a GB of memory and I have to stop it. I tried doing it so the reference to each linq object is removed once it's updated but that doesn't seem to help. How can I make it clear the reference?
Thanks for your help
Private Sub uploadPDFs(ByVal args() As String)
Dim indexFiles = (From indexFile In dataContext.IndexFiles
Where indexFile.PDFContent = Nothing
Order By indexFile.PDFFolder).ToList
Dim currentDirectory As IO.DirectoryInfo
Dim currentFile As IO.FileInfo
Dim tempIndexFile As IndexFile
While indexFiles.Count > 0
tempIndexFile = indexFiles(0)
indexFiles = indexFiles.Skip(1).ToList
currentDirectory = 'I set the directory that I need
currentFile = 'I get the file that I need
writePDF(currentDirectory, currentFile, tempIndexFile)
End While
End Sub
Private Sub writePDF(ByVal directory As IO.DirectoryInfo, ByVal file As IO.FileInfo, ByVal indexFile As IndexFile)
Dim bytes() As Byte
bytes = getFileStream(file)
indexFile.PDFContent = bytes
dataContext.SubmitChanges()
counter += 1
If counter Mod 10 = 0 Then Console.WriteLine(" saved file " & file.Name & " at " & directory.Name)
End Sub
Private Function getFileStream(ByVal fileInfo As IO.FileInfo) As Byte()
Dim fileStream = fileInfo.OpenRead()
Dim bytesLength As Long = fileStream.Length
Dim bytes(bytesLength) As Byte
fileStream.Read(bytes, 0, bytesLength)
fileStream.Close()
Return bytes
End Function
I suggest you perform this in batches, using Take (before the call to ToList) to process a particular number of items at a time. Read (say) 10, set the PDFContent on all of them, call SubmitChanges, and then start again. (I'm not sure offhand whether you should start with a new DataContext at that point, but it might be cleanest to do so.)
As an aside, your code to read the contents of a file is broken in at least a couple of ways - but it would be simpler just to use File.ReadAllBytes in the first place.
Also, your way of handling the list gradually shrinking is really inefficient - after fetching 180,000 records, you're then building a new list with 179,999 records, then another with 179,998 records etc.
Does the DataContext have ObjectTrackingEnabled set to true (the default value)? If so, then it will try to keep a record of essentially all the data it touches, thus preventing the garbage collector from being able to collect any of it.
If so, you should be able to fix the situation by periodically disposing the DataContext and creating a new one, or turning object tracking off.
OK. To use the smallest amount of memory we have to update the datacontext in blocks. I've put a sample code below. Might have sytax errors since I'm using notepad to type it in.
Dim DB as YourDataContext = new YourDataContext
Dim BlockSize as integer = 25
Dim AllItems = DB.Items.Where(function(i) i.PDFfile.HasValue=False)
Dim count = 0
Dim tmpDB as YourDataContext = new YourDataContext
While (count < AllITems.Count)
Dim _item = tmpDB.Items.Single(function(i) i.recordID=AllItems.Item(count).recordID)
_item.PDF = GetPDF()
Count +=1
if count mod BlockSize = 0 or count = AllItems.Count then
tmpDB.SubmitChanges()
tmpDB = new YourDataContext
GC.Collect()
end if
End While
To Further optimise the speed you can get the recordID's into an array from allitems as an anonymous type, and set DelayLoading on for that PDF field.