Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Can anyone account for these extra bytes? 2

Status
Not open for further replies.

elziko

Programmer
Nov 7, 2000
486
GB
Right, I have a byte array tmp which contains:

tmp(0) = 49
tmp(1) = 50
tmp(2) = 51
tmp(3) = 52


Then I do this:

fnum = FreeFile
Open filenamepath For Binary As fnum
Put #fnum, , tmp
Close #fnum


I then open the file in a text editor and see this:

"   1234"

where I was clearly expecting to see:

"1234"

Where are these extra bytes comming from? I think there are two bytes added to the beginning of the file. A '17' and a '32' are what they seem to be!

Any ideas on what I should do? Should I try text stream or something in the FSO instead??

Cheers

elziko
 
elziko,
Strange, I ran the code below and got no preceeding
bytes.

Option Explicit
Dim Tmp(3) As Byte

Private Sub Form_Load()
Tmp(0) = 49
Tmp(1) = 50
Tmp(2) = 51
Tmp(3) = 52
Dim fnum As Long

fnum = FreeFile

Open App.Path & "\test.bin" For Binary As fnum
Put #fnum, , Tmp
Close #fnum
End Sub

'File contains this :-
'31 32 33 34 00 1234.
 
I looks like your byte array is dynamic.
From the MSDN CD DOCS.
"If the variable being written is a dynamic array, Put writes a descriptor whose length equals 2 plus 8 times the number of dimensions, that is, 2 + 8 * NumberOfDimensions. The record length specified by the Len clause in the Open statement must be greater than or equal to the sum of all the bytes required to write the array data and the array descriptor. For example, the following array declaration requires 118 bytes when the array is written to disk.
Dim MyArray(1 To 5,1 To 10) As Integer

The 118 bytes are distributed as follows: 18 bytes for the descriptor (2 + 8 * 2), and 100 bytes for the data (5 * 10 * 2).


If the variable being written is a fixed-size array, Put writes only the data. No descriptor is written to disk." Compare Code (Text)
Generate Sort in VB or VBScript
 
I tried your code, and opened the resulting file up in notepad and it displayed only 1234 Troy Williams B.Eng.
fenris@hotmail.com

 
Thanks guys.

JohnYingling. Spot on! The code I posted was just an example and the array is indeed dynamically allocated. I didn't think of that.

I don't seem to get any control over which bytes are added to the file, so how else can I create the file with the correct bytes? I haven't tried it but using the FSO TextStream object is the only way I can think of??

What do you think?

Cheers,

elziko
 
How are you going to read it back in if the byte array is dynamic? It seems that you will need some mechanism for knowing the COUNT or UBOUND of the array. FSO requires including the SCRRUN.DLL (MS Scripting Run-time) for those who do not have it BUT Get, Put, Open, Close etc. go way with VB.NET (FSIO is replaced by a new object). Compare Code (Text)
Generate Sort in VB or VBScript
 
Why do I need to know the COUNT or UBOUND?

I'm converting a file into a byte array (for use with Oracle/AppendChunk) and then turning it back into a file.

elziko
 
Hi, elziko

I did that just yesterday. Here's my code if it's any help to you.

To write the file:
----------------------------------------------------
Public Type Position
lat As Single
lon As Single
End Type

do
'Here I read from a flat file and put something into TmpArr
TmpPos.lon = CSng(TmpArr(0))
TmpPos.lat = CSng(TmpArr(1))
Put #OutFile, , TmpPos
loop until eof(InFile)
--------------------------------------------------------

To Read the file into an array:
---------------------------------------------------------
DataArr() As Position
InFile = FreeFile
Open "s:\janus\vb\activex\Jmap\coast.sng" For Binary Access Read As #InFile
ReDim DataArr(LOF(InFile) / 8 - 1)
Get #InFile, , DataArr
Close #InFile
----------------------------------------------------------

It's really fast and efficient.

Sunaj

 
Sunaj,

Thanks but I don't know if your example is helping me??

I have every byte of a file stored in a byte array. I cannot have it in any other form. All I want do is create a file which is made up from the bytes in my array. I want to have full control over what bytes make up the file. I don't want any descriptor bytes.

The only way I have found of doing this so far is by using a string instead of a byte array but this requires a conversion from a byte array to an ASCII string which takes FAR too long for big files.

How can I get full control, on a byte by byte level, over a file I create??

Cheers

elziko
 

I guess that if you loop through the array and use 'put' to write the individual bytes to the file, you'll be in total control.
You should still be able to read the entire file into an array as I did, just 'dim MyArr() as byte' and 'ReDim DataArr(LOF(InFile)-1)' -without having tested it.

Sunaj
 
Thanks. First your code gave be 'Bad File Mode' so I changed the open typr from binary to Output. In this case the new file contained just "??" instead of "1234".

After a bit of fiddling the only way I can get this to work is like so:

Open filenamepath For Output As fnum
For i = LBound(tmp) To UBound(tmp)
Print #fnum, Chr(tmp(i));
Next i


But this still needs to call the 'Chr' function for every byte of tyhe file which takes too long in my mind. Anyone got any further ideas?

elziko
 
Bad file mode was due to using Print with binary mode. Put with output mode also causes bad file mode.
Change
Print #fnum, tmp(i)
to
Put #fnum,,tmp(i)

The two commas are required.

My test appears to have worked OK
[tt]
Sub main()
Dim fnum
Dim tmp() As Byte
Dim i As Integer

ReDim tmp(3)
For i = 0 To 3: tmp(i) = 48 + i: Next i

fnum = FreeFile
Open App.Path & "\test.txt" For Binary As fnum
For i = 0 To 3
Put #fnum, , tmp(i)
Next i
Close fnum

end sub
[/tt]

Wil Mead
wmead@optonline.net

 
Your code creates this:

[color]" 1 2 3 4 5"[/color]

when I use it. You say if you create a text file (only as an example) you get:

[color]"1234"[/color] with NO extra bytes apart from the ones you put in??????

Strange. I'm not getting the same as you???

elziko

 
Hmmm... I get 4 byte file (verified in file properties) with contents of "0123" (verified in notepad) just as I expected.

With you getting 2 bytes to 1, I suspect the data type of your array is not byte and that the first byte is a null character.

When I change dim tmp() as byte to dim tmp() I get results similar to what you state: 16 byte file, 8 bytes visible in notepad 0123.

There is a catch! If I do not delete the test file, the results are funky!


Wil Mead
wmead@optonline.net

 
You're running under a version of NT rather than W9X/ME, aren't you? Which means that your problem is predominantly caused by ASCII v Unicode issues.

Try the following:
[tt]
Dim strA As String
Dim tmp() As Byte
Dim fnum As Long

ReDim tmp(3) ' Make dynamic to emulate problem discussed

tmp(0) = 49
tmp(1) = 50
tmp(2) = 51
tmp(3) = 52


strA = StrConv(tmp, vbUnicode) ' Deal with Unicode problem
fnum = FreeFile
Open "c:\dummy.txt" For Binary As fnum
Put #fnum, , strA
Close #fnum
 
AGhhhh! :)

I refer you to JohnYingling's first post in this thread! It looks like you suggested that I do what I first posted didn't work!! LOL

The array is a variant and therefore descriptor bytes are added!

I am trying to write the bytes to the file without this happening. Right, I'm back off to see if the API does a similar thing.......

elziko
 
Sorry we posted at the same time. The "Aghhh" was aimed at WilMead (in a friendly, non-critical manner, hence the funny little faces) not yourself. :)

Anyway, what you are doing seems to be similar to my final solution:

Open filenamepath For Output As fnum
For i = LBound(tmp) To UBound(tmp)
Print #fnum, Chr(tmp(i));
Next i


I'll try your suggestion and see if its any quicker than mine. I'm sure it would be much quicker if I could leave the whole string thing out of it??? Which is why I wanna look at the relavant API functions. But naturally I'm supposed to be working on something else at the mo.

Cheers

elziko
 
Right... your method is TEN times faster than mine. Thanks!

I'll let you know if I get it working (faster) using the API.

elziko
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top