VB File Handling

ChiefRedBull
07-21-2002, 03:39 PM
I'm hearing people recommend the FSO more and more for even the simplest of operations, and IMHO it's just overkill.
VB's native file methods are perfectly capably of performing even the most advanced operations such as moving an entire folder and all its contents, including subfolders. If VB isn't quite enough, then API can be used. Some of the methods in the class are wrappers for VB methods or API calls.

The main class - CFileHandler - has the following methods:

Exists : will check the existance of a file or folder (uses API)
MakeFile : creates a blank file
MakeFolder : creates an empty folder (MkDir wrapper)
MoveFile : moves a file (FileCopy wrapper)
MoveFolder : recursive routine, moves a folder and its contents
DeleteFile : deletes a file (Kill wrapper)
DeleteFolder : recursive routine, deletes a folder and its contents
ListDrives : returns an array of drive letters (uses API)
FindFiles : searches a folder for a file pattern

The recursive routines use a static CStack class to store information about the parent folders as it navigates down through the folder tree.
There is also one more class - IFileEvents - used for early bound events from CFileHandler. All you have to do is implement this interface with the Implements keyword, and then Set CFileHandler.Callback = Me.

Report all bugs to me via PM please :)

Scroll down for latest version

Thinker
07-21-2002, 05:43 PM
There is one operation the FSO can do better than anything else
in windows. Read a LineFeed only terminated Unix/Linux file line
by line.

ChiefRedBull
07-24-2002, 10:28 AM
I took that as a challenge Thinker... here you go. I did some testing which is included in this project, and it seems that my class is faster than the FSO.
It now has extra methods and properties:

openfile - opens a file within the class for binary
eolchar - sets the End Of Line character used when reading a line
filelength - length of currently open file
readstream - read a certain number of bytes, from a certain place
readline - read the next line (everything from the current point upto the next EOL char)
writestream - write bytes at a certain point
closefile - close the file
stringtobytes - convert a string to a byte array
bytestostring - convert a byte array back to a string


Much faster for reading: 85% (approx)
Not so much for writing: 20% (approx)
Of course, my testing has never been great... :p

Once again, bugs via PM please :)

Volte
07-24-2002, 10:46 AM
Sweet! Excellent work, Chief!

Thinker
07-24-2002, 12:08 PM
Cool. I like someone who takes on a challenge.
I haven't tried using it yet, but I notice that you Dim the
byte array to the size of the file, then loop reading in one byte at
a time until you find the eol character. I wonder if it would be
faster to just read in the whole file, then search through the byte
array looking for the defined EOL.
One more thing that makes me wonder. Your function to move
bytes from the bytearray into the string don't do any kind of ANSI
to Unicode conversions. Usually the bytes read in would be ANSI
and the returned string should be in Unicode. Am I just missing
something?

ChiefRedBull
07-24-2002, 02:16 PM
Yeh, i was wondering about reading a byte at a time.. you're right, it would probably be faster to just read the whole lot and search it. I'll change that.
On the second point - you are missing one small thing. The ByVal in the call temporarily converts the string to ANSI before it receives the contents of the array, then converts it back to UNICODE once it's full.
It needs a couple more properties and methods.. number of lines in the file and the ability to skip a line when reading.. version 3 coming right up :)

Thinker
07-24-2002, 02:34 PM
The ByVal in the call temporarily converts the string to ANSI before it receives the contents of the array, then converts it back to UNICODE once it's full.

Yeah, neat trick there, but I am referring to the BytesToString function.

ChiefRedBull
07-24-2002, 02:39 PM
So am I.

You can convert a Byte array holding an ANSI string into a Unicode string using the StrConv function

res$ = StrConv(byteArr(), vbUnicode)

This approach isn’t efficient, however, when you want to extract only a substring–a portion of the Byte array–and store it in a VB variable...
...use the CopyMemory API function:

res$ = Space$(length)
CopyMemory ByVal res$, byteArr(startIndex), length

This works because the ByVal keyword temporarily converts the string to ANSI an instant before it receives the contents of the subarray. When the function returns, it converts the string back to Unicode.

From - http://www.vb2themax.com/HtmlDoc.asp?Table=Articles&ID=30

Thinker
07-24-2002, 03:08 PM
Ok, I guess that makes sense, except for one thing. This means
res$ is going through two conversions - to ANSI and back
to Unicode. How is that more efficient than StrConv, which only
does one conversion? I assume they mean because you aren't
converting the whole string, but I would try it like this...

Dim sTmp() As Byte
Dim lLen As Long

If Length = -1 Then
lLen = UBound(bArr) + 1
Else
lLen = Length
End If

ReDim sTmp(lLen - 1)
CopyMemory sTmp(0), bArr(StartIndex), lLen
BytesToString = StrConv(sTmp, vbUnicode)

I guess a time test would help.

ChiefRedBull
07-24-2002, 03:34 PM
I see what you're thinking (pun intended :)), and testing produces odd results... the smaller the string, the faster copymemory is. However, once the string goes above about 140 chars, strconv becomes quicker.

Not sure what's going on now.. but I'll change mine to your solution, since the pros outweigh the cons.

Thinker
07-24-2002, 05:57 PM
Maybe it could be optimised for string length - do it both ways,
but decide on the method based on iLen.

ChiefRedBull
07-24-2002, 06:12 PM
The other thing you mentioned about the ReadLine method - reading the entire file then searching the array is much quicker - 50% at least, although again, it varies with file size, and current read position within the file.

Thanks for the tips :)

EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum