Results 1 to 12 of 12

Thread: [RESOLVED] How to convert a byte array ?

  1. #1

    Thread Starter
    Hyperactive Member Daniel Duta's Avatar
    Join Date
    Feb 2011
    Location
    Bucharest, Romania
    Posts
    359

    Resolved [RESOLVED] How to convert a byte array ?

    Hi,
    I have a small text file with 2 columns (tab delimited) which was stored as resource file. When I try to get back the file, its content is provided as byte array using the native function LoadResData
    Code:
    myByteArray() = LoadResData(102, "Custom")
    I know how to load a simple text file from disk into a 2D array but once I already have the file as array how could I convert it in a 2D variant array for example? Thank you.

  2. #2
    PowerPoster Arnoutdv's Avatar
    Join Date
    Oct 2013
    Posts
    3,895

    Re: How to convert a byte array ?

    You can use the StrConv() method for this:
    Code:
      Dim byteArray() As Byte
      Dim sInput As String
      Dim sOutput  As String
      
      ' Just a normal string
      sInput = "Hello world"
      
      ' Store it in an byte array
      byteArray = StrConv(sInput, vbFromUnicode)
      
      ' Convert byte array to string
      sOutput = StrConv(byteArray, vbUnicode)
      
      Debug.Print sInput, sOutput

  3. #3

    Thread Starter
    Hyperactive Member Daniel Duta's Avatar
    Join Date
    Feb 2011
    Location
    Bucharest, Romania
    Posts
    359

    Re: How to convert a byte array ?

    Thanks for reply, Arno. As I mentioned above I need a 2D array as result because my flexgrid requires a 2D variant array for its LoadArray method. Let's say I would split further the byte array as below
    Code:
    myText = StrConv(myByteArray, vbUnicode)
    strArray = Split(myText, vbNewLine)
    However, in this case I will get an 1D array instead with all column data grouped on each row. Maybe including again each row in a other loops could do the task but I am not really sure if it is the most straightforward way for this kind of conversion.

  4. #4
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    19,482

    Re: How to convert a byte array ?

    Quote Originally Posted by Daniel Duta View Post
    Maybe including again each row in a other loops could do the task but I am not really sure if it is the most straightforward way for this kind of conversion.
    Process the myText variable same as if it were the actual text file, which you already have code for.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  5. #5

    Thread Starter
    Hyperactive Member Daniel Duta's Avatar
    Join Date
    Feb 2011
    Location
    Bucharest, Romania
    Posts
    359

    Re: How to convert a byte array ?

    After many attempts I have managed to solve my issue avoiding the byte array conversion. Knowing the FlexGrid control has a useful Clip property I preferred to transfer my text file from the vb Resource file directly using the Clipboard object. For this purpose I have written the following routine that worked as I wanted and could be useful for others:
    Code:
    Private Sub FillFlexFromResFile()
        Dim myByteArray() As Byte, myText As String
    
        myByteArray() = LoadResData(102, "Custom")
        myText = StrConv(myByteArray, vbUnicode)
        Clipboard.Clear
        Clipboard.SetText myText
        
    With fg
        .Redraw = flexRDNone                         'Avoid the flickering effect
        .Row = 1                                     'Paste starting with second row (first is header usually)
        .Col = 1                                     'Paste starting with second column (or other)
        .Rows = UBound(Split(myText, vbNewLine)) + 1 'Recalculate the max nb of fg rows considering the text file nb of rows
        .RowSel = .Rows - 1                          'Extend the row selection to maximum allowed
        .ColSel = .Cols - 1                          'Select the all range of columns
        .Clip = Clipboard.GetText                    'Paste the clipboard content over selection
        .Col = 1                                     'Remove the fg body selection
        .Redraw = True                               'Resume redrawing
    End With
        
        Clipboard.Clear                              'Clears the clipboard content
    End Sub
    Thank you all for your suggestions.

  6. #6
    PowerPoster Arnoutdv's Avatar
    Join Date
    Oct 2013
    Posts
    3,895

    Re: [RESOLVED] How to convert a byte array ?

    You don't need the Clipboard, just assign the string directly to the .Clip property
    Last edited by Arnoutdv; Feb 13th, 2015 at 01:56 PM.

  7. #7
    PowerPoster
    Join Date
    Jun 2013
    Posts
    4,930

    Re: [RESOLVED] How to convert a byte array ?

    Not sure why the Clipboard is involved in the above code,
    since you could simply use the myText-content also directly...:
    fg.clip = myText


    I personally prefer, to store such Data-related resources in a
    "Non-GUI-Control-dependent" format...

    E.g. ADO-Recordsets come to mind (in case one needs to serialize Multi-
    Column-Data into a ByteArray) - and those ADO-Rs could then also be used
    "free-standing" (without any underlying DB-Engine).

    Serialization-features of "Non-GUI-Data-Container-Classes" are common
    nowadays in many class-libraries - so, beside the already mentioned ADO-
    Recordset, VB6-users could also use the vbRichClient5-Container-Objects,
    which all support Unicode-capable serialization/deserialzation into ByteArrays:

    Multi-Column-Data:
    e.g. the (SQLite-DB-derived - from InMemory-or File-Connection)
    - cRecordset (over its Read and Write .Content Property which accepts/hands out ByteArrays)
    - cConnection.CreateTableFromRsContent (could also directly make an InMemory-Table or FileDB-Table from such Content)
    - cConnection.CreateTableFromADORs (can do the same SQLite-InMemory-Table-Creation in one Line, but from an ADO-Rs as the source

    Key-Value-Pairs:
    - cCollection (ByteArrray-serialization/deserialization of Key-Value-Pairs over its .Content-Property)
    - cCollection.SerializeToJSONString (is alternatively also available ...)
    - cCollection.SerializeToJSONUTF8 (...as well as UTF8-ByteArray-Serialization...)
    all of the above 3 methods work also hierarchically (on a nested Tree, in case a Value is another cCollection).

    1D-Arrays of all simple Types (Long, String, Currency, Double, etc.):
    - cArrayList (in the same way as the other two above, supports a Read-Write .Content-Property)

    So, in your concrete case you could e.g. store your ByteArray-Content, derived from
    an ADO-Rs (e.g. a free-standing one, which you created per Rs.Fields.Append, etc.)

    And deserializing it on App-LoadTime from your resource, then being able
    to "hang it in" with one line of code, not only into a HFlexGrid, but also into an
    editable VB.DataGrid - or bind it against TextFields etc. - I guess what I mean to
    say is, that it's a good idea to use data-serializations, which can be deserialized into
    Containers which are more flexible and "bindable" to all sorts of GUI-controls.


    Olaf

  8. #8
    PowerPoster
    Join Date
    Feb 2006
    Posts
    21,446

    Re: [RESOLVED] How to convert a byte array ?

    Quote Originally Posted by Schmidt View Post
    I personally prefer, to store such Data-related resources in a
    "Non-GUI-Control-dependent" format...
    I assume this is an issue of locale-dependent formatting of things like fractional numbers, currency values, date/time values, boolean values, etc.

    Text formats don't have to be a barrier to data interchange, they just need to be formatted using the "invariant" locale's formatting. For example in XML it is never legal to use "1,23" to mean "1.23" even if your system or user account is set for a German UI. if you do that then it isn't XML, but a nonconformat look-alike.

    The same is true for CSV or other delimited text data. While for convenience German language users may be able to use semicolons in place of the commas, allowing goofy punctuation in their numbers, the result isn't really "CSV" at all. You certainly wouldn't want to use it as a data interchange format.

    Most code that can process data seriaized as XML, JSON, etc. is smart enough to always use the invariant locale. However not all software can do this for a format like CSV.

    ADO or example, when fed text as data, will always apply the current user UI locale when "deformatting" the text back to a binary representation. If your user account is set for a German language UI, feeding "1.23" to ADO for a Single field gets you 123 instead of 1.23 in your Recordset. Feeding it "1,23" when your UI language is English gets you 123 in the same way. I have not found any override for this.

    So CSV is hazardous, conceived in early times before the Internet was widely available. It's legacy is all over the place.

    That's why binary formats are safer. To use text you want to stick to XML or JSON and software that conforms to the standards. This is probably a bigger problem for JSON than XML, though there are plenty of incorrect parsers and serializers for both of them that assume the UI locale is always U.S. English.


    In the U.S. people are lucky in a way. Even when you lump in Canada, which is close enough that most things will just work. As long as they can get away with treating N. America as its own universe everything mostly works with no fiddling.

    Of course Canada has French as well, and the U.S. has a ton of Spanish speakers... not to forget Mexico and friends to the south. But you are still mostly safe until you deal with true/false values or dates with month names in them.

  9. #9
    PowerPoster
    Join Date
    Feb 2006
    Posts
    21,446

    Re: [RESOLVED] How to convert a byte array ?

    BTW: my new TabularParse seems to work for this sort of thing.

  10. #10
    PowerPoster
    Join Date
    Feb 2006
    Posts
    21,446

    Re: [RESOLVED] How to convert a byte array ?

    I was just reminded that binary formats pose risks of their own.

    Quite a few are proprietary, and those that aren't can present platform portability woes (big vs. little endian, date/time representation, 1's complement vs. 2's complement, etc.).

  11. #11
    PowerPoster
    Join Date
    Jun 2013
    Posts
    4,930

    Re: [RESOLVED] How to convert a byte array ?

    Quote Originally Posted by dilettante View Post
    I assume this is an issue of locale-dependent formatting of things like fractional numbers, currency values, date/time values, boolean values, etc.
    Yes, that's one of the reasons, since such "non-GUI-containers" (aka "common List-Structures")
    support correct storage of different (native) datatypes, according to their Field-Definition -
    (in a truly portable format, which works locale-independent - no matter if "binary formatted",
    or as alternatively possible with e.g. ADO-Rs, per XML-based serialization-format).
    These containers will always "serialize/deserialize" correctly - at least on any current
    Win-machine, since we have no Endianness-problems to take into account on these OSes.

    Same thing with powerful Container-Objects which store Key/Value-pairs - when both,
    the Keys and the Values are "native-Type-aware" - e.g. when they (as in VB5/6) are
    based on the selfdescribing Variant-Type, often damned - but it really *is* a powerful
    Struct(ure), especially in these Serialization/Deserialization-scenarios (which e.g. COM-
    Marshalling + IDispatch is a larger part of - and one of the reasons, the Variant-Type was
    "invented" or "needed").

    So these (native serializing) List-Structures are useful not only in storage-scenarios - but also
    in RPCs (Remote-Procedure-Calls) - no matter if across Thread- or Process-boundaries -
    or across Machine-boundaries (per Pipes or sockets).

    But I also was trying to make my point with regards to larger convenience in daily programming-
    scenarios - since those Containers usually also support sorting and filtering (which will reduce
    your efforts with certain GUI-Bindings, since not each and every GUI-Control supports Filtering,
    Sorting, or has built-in search-mechanisms).

    Especially when such containers are used against "Virtual List-Controls" (as you recently posted a
    nice one in the CodeBank), you will be able to keep your Data in your non-GUI-containers, and
    then sort + filter them there - your changes easily reflectable in the (few, only currently visual)
    Lines of your Virtual-ListControl-Rendering-Update.

    Olaf

  12. #12

    Thread Starter
    Hyperactive Member Daniel Duta's Avatar
    Join Date
    Feb 2011
    Location
    Bucharest, Romania
    Posts
    359

    Re: [RESOLVED] How to convert a byte array ?

    Quote Originally Posted by Arnoutdv View Post
    You don't need the Clipboard, just assign the string directly to the .Clip property
    You are absolutely right, Arno, the Clipboard usage is redundant in this case. Just fg.Clip = myText does all the work.
    Quote Originally Posted by Schmidt View Post
    Not sure why the Clipboard is involved in the above code
    Me neither I tested an idea, it worked and I thought that it is the right way... You know, when people get married they have a similar behavior. So, take it as a lack of maturity. It is the first time when I use the Clip property and I didn't find any example about how a resource file could be loaded in a flexgrid directly. Anyway, these days I want to see how the vbRichClient5 library works on the database side, especially with SQLight because I hope to find more degrees of freedom than with Access - tsql query syntax, bulk insert data, speed and many other.
    Quote Originally Posted by dilettante View Post
    BTW: my new TabularParse seems to work for this sort of thing.
    I found both your functions from codebank very useful to me. The TabularParse does convert a binary text file in a variant array, taking into account a multidimensional structure and the Null values. The PutString function is useful when we try to load data with ADO but now I try to adapt your function to a 2D array because when we get data from excel usually we have a 2D variant. This array cannot be loaded in Access db directly (bulk insert) using the ADO AddNew method but I have noted that you succeeded to insert 8 columns and 5000 rows in a fast way (avoiding the Update method) calling the AddNew method only at the end of the each row. I didn't write a small benchmark but your approach is visible faster. Thank you all.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width