By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
425,635 Members | 913 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 425,635 IT Pros & Developers. It's quick & easy.

Read File Byte by Byte

P: 48
Does someone know an (fast) example of reading files in VBA, Byte per Byte ?
I need to be able to take action on every single byte

Thx
Feb 22 '09 #1
Share this Question
Share on Google+
18 Replies


NeoPa
Expert Mod 15k+
P: 31,409
I think you're looking for Get#.

FreeFile(), Open#, Put# & Close# are all related and I would recommend a thorough reading of the help topic before starting along these lines.

It's possible to do, and it can work quite well too, but it's certainly not the default way of handling file I/O so don't expect it to be straightforward.

I use it a bit, as it's perfect for some situations, but generally only when there's no better way of doing what I need.
Feb 22 '09 #2

ADezii
Expert 5K+
P: 8,619
@wquatan
The following code will Open a File (C:\Windows\System.ini), read its contents Byte-by-Byte, display each Character's Position, Decimal and Hexadecimal equivalents, and the actual Character itself. I posted a partial display of the Output for you to see, any questions, feel free to ask.
Expand|Select|Wrap|Line Numbers
  1. Dim intFileNumber As Integer
  2. Dim lngFileSize As Long
  3. Dim strBuffer As String
  4. Dim lngCharNumber As Long
  5. Dim strCharacter As String * 1
  6. Dim strFileName As String
  7.  
  8. strFileName = "C:\Windows\System.ini"
  9.  
  10. 'Get the next available File Number
  11. intFileNumber = FreeFile
  12.  
  13. DoCmd.Hourglass True
  14.  
  15. Open strFileName For Binary Access Read Shared As #intFileNumber
  16.  
  17. lngFileSize = LOF(intFileNumber)    'How large is the File in Bytes?
  18. strBuffer = Space$(lngFileSize)     'Set Buffer Size to File Length
  19.  
  20. Get #intFileNumber, , strBuffer     'Grab a Chunk of Data from the File
  21. Close #intFileNumber
  22.  
  23. 'Display results on a Byte-by-Byte basic
  24. For lngCharNumber = 1 To lngFileSize
  25.   strCharacter = Mid(strBuffer, lngCharNumber, 1)
  26.   Debug.Print Format(lngCharNumber, "0000000") & " = Decimal(" & Format(Asc(strCharacter), "000") & _
  27.               "), Hexidecimal(" & Hex$(Asc(strCharacter)) & "), Character[" & strCharacter & "]"
  28. Next
  29.  
  30. DoCmd.Hourglass False
Partial OUTPUT:
Expand|Select|Wrap|Line Numbers
  1. 0000056 = Decimal(116), Hexidecimal(74), Character[t]
  2. 0000057 = Decimal(105), Hexidecimal(69), Character[i]
  3. 0000058 = Decimal(109), Hexidecimal(6D), Character[m]
  4. 0000059 = Decimal(101), Hexidecimal(65), Character[e]
  5. 0000060 = Decimal(114), Hexidecimal(72), Character[r]
  6. 0000061 = Decimal(061), Hexidecimal(3D), Character[=]
  7. 0000062 = Decimal(116), Hexidecimal(74), Character[t]
  8. 0000063 = Decimal(105), Hexidecimal(69), Character[i]
  9. 0000064 = Decimal(109), Hexidecimal(6D), Character[m]
  10. 0000065 = Decimal(101), Hexidecimal(65), Character[e]
  11. 0000066 = Decimal(114), Hexidecimal(72), Character[r]
  12. 0000067 = Decimal(046), Hexidecimal(2E), Character[.]
  13. 0000068 = Decimal(100), Hexidecimal(64), Character[d]
  14. 0000069 = Decimal(114), Hexidecimal(72), Character[r]
  15. 0000070 = Decimal(118), Hexidecimal(76), Character[v]
  16. 0000071 = Decimal(013), Hexidecimal(D), Character[
  17. ]
  18. 0000072 = Decimal(010), Hexidecimal(A), Character[
  19. ]
  20. 0000073 = Decimal(013), Hexidecimal(D), Character[
  21. ]
  22. 0000074 = Decimal(010), Hexidecimal(A), Character[
  23. ]
  24. 0000075 = Decimal(091), Hexidecimal(5B), Character[[]
  25. 0000076 = Decimal(109), Hexidecimal(6D), Character[m]
  26. 0000077 = Decimal(099), Hexidecimal(63), Character[c]
  27. 0000078 = Decimal(105), Hexidecimal(69), Character[i]
  28. 0000079 = Decimal(093), Hexidecimal(5D), Character[]]
  29. 0000080 = Decimal(013), Hexidecimal(D), Character[
  30. ]
  31. 0000081 = Decimal(010), Hexidecimal(A), Character[
  32. ]
  33. 0000082 = Decimal(091), Hexidecimal(5B), Character[[]
  34. 0000083 = Decimal(100), Hexidecimal(64), Character[d]
  35. 0000084 = Decimal(114), Hexidecimal(72), Character[r]
  36. 0000085 = Decimal(105), Hexidecimal(69), Character[i]
  37. 0000086 = Decimal(118), Hexidecimal(76), Character[v]
  38. 0000087 = Decimal(101), Hexidecimal(65), Character[e]
  39. 0000088 = Decimal(114), Hexidecimal(72), Character[r]
  40. 0000089 = Decimal(051), Hexidecimal(33), Character[3]
  41. 0000090 = Decimal(050), Hexidecimal(32), Character[2]
  42. 0000091 = Decimal(093), Hexidecimal(5D), Character[]]
  43. 0000092 = Decimal(013), Hexidecimal(D), Character[
  44. ]
  45. 0000093 = Decimal(010), Hexidecimal(A), Character[
  46. ]
  47. 0000094 = Decimal(091), Hexidecimal(5B), Character[[]
  48. 0000095 = Decimal(051), Hexidecimal(33), Character[3]
  49. 0000096 = Decimal(056), Hexidecimal(38), Character[8]
  50. 0000097 = Decimal(054), Hexidecimal(36), Character[6]
  51. 0000098 = Decimal(101), Hexidecimal(65), Character[e]
  52. 0000099 = Decimal(110), Hexidecimal(6E), Character[n]
  53. 0000100 = Decimal(104), Hexidecimal(68), Character[h]
  54. 0000101 = Decimal(093), Hexidecimal(5D), Character[]]
  55. 0000102 = Decimal(013), Hexidecimal(D), Character[
  56. ]
  57. 0000103 = Decimal(010), Hexidecimal(A), Character[
  58. ]
  59. 0000104 = Decimal(119), Hexidecimal(77), Character[w]
  60. 0000105 = Decimal(111), Hexidecimal(6F), Character[o]
  61. 0000106 = Decimal(097), Hexidecimal(61), Character[a]
  62. 0000107 = Decimal(102), Hexidecimal(66), Character[f]
  63. 0000108 = Decimal(111), Hexidecimal(6F), Character[o]
  64. 0000109 = Decimal(110), Hexidecimal(6E), Character[n]
  65. 0000110 = Decimal(116), Hexidecimal(74), Character[t]
  66. 0000111 = Decimal(061), Hexidecimal(3D), Character[=]
  67. 0000112 = Decimal(100), Hexidecimal(64), Character[d]
  68. 0000113 = Decimal(111), Hexidecimal(6F), Character[o]
  69. 0000114 = Decimal(115), Hexidecimal(73), Character[s]
  70. 0000115 = Decimal(097), Hexidecimal(61), Character[a]
  71. 0000116 = Decimal(112), Hexidecimal(70), Character[p]
  72. 0000117 = Decimal(112), Hexidecimal(70), Character[p]
  73. 0000118 = Decimal(046), Hexidecimal(2E), Character[.]
  74. 0000119 = Decimal(070), Hexidecimal(46), Character[F]
  75. 0000120 = Decimal(079), Hexidecimal(4F), Character[O]
  76. 0000121 = Decimal(078), Hexidecimal(4E), Character[N]
  77. 0000122 = Decimal(013), Hexidecimal(D), Character[
  78. ]
  79. 0000123 = Decimal(010), Hexidecimal(A), Character[
  80. ]
  81. 0000124 = Decimal(069), Hexidecimal(45), Character[E]
  82. 0000125 = Decimal(071), Hexidecimal(47), Character[G]
  83. 0000126 = Decimal(065), Hexidecimal(41), Character[A]
  84. 0000127 = Decimal(056), Hexidecimal(38), Character[8]
  85. 0000128 = Decimal(048), Hexidecimal(30), Character[0]
  86. 0000129 = Decimal(087), Hexidecimal(57), Character[W]
  87. 0000130 = Decimal(079), Hexidecimal(4F), Character[O]
  88. 0000131 = Decimal(065), Hexidecimal(41), Character[A]
  89. 0000132 = Decimal(046), Hexidecimal(2E), Character[.]
  90. 0000133 = Decimal(070), Hexidecimal(46), Character[F]
  91. 0000134 = Decimal(079), Hexidecimal(4F), Character[O]
  92. 0000135 = Decimal(078), Hexidecimal(4E), Character[N]
  93. 0000136 = Decimal(061), Hexidecimal(3D), Character[=]
  94. 0000137 = Decimal(069), Hexidecimal(45), Character[E]
  95. 0000138 = Decimal(071), Hexidecimal(47), Character[G]
  96. 0000139 = Decimal(065), Hexidecimal(41), Character[A]
  97. 0000140 = Decimal(056), Hexidecimal(38), Character[8]
  98. 0000141 = Decimal(048), Hexidecimal(30), Character[0]
  99. 0000142 = Decimal(087), Hexidecimal(57), Character[W]
  100. 0000143 = Decimal(079), Hexidecimal(4F), Character[O]
  101. 0000144 = Decimal(065), Hexidecimal(41), Character[A]
  102. 0000145 = Decimal(046), Hexidecimal(2E), Character[.]
  103. 0000146 = Decimal(070), Hexidecimal(46), Character[F]
  104. 0000147 = Decimal(079), Hexidecimal(4F), Character[O]
  105. 0000148 = Decimal(078), Hexidecimal(4E), Character[N]
  106. 0000149 = Decimal(013), Hexidecimal(D), Character[
  107. ]
  108. 0000150 = Decimal(010), Hexidecimal(A), Character[
  109. ]
  110. 0000151 = Decimal(069), Hexidecimal(45), Character[E]
Feb 22 '09 #3

P: 48
Hi,

Thank you for the interesting example !!

However, there is one problem : I'm unable to read the whole file into one strBuffer. The files I have to threat can be very very large.

I really need to read byte per byte till the end is reached.

Thx
Feb 22 '09 #4

NeoPa
Expert Mod 15k+
P: 31,409
You should find all you need in post #2. It's not all done for you, but I don't imagine that should be a problem.

ADezii's post is an example of what can be done with it. You may find some good example code in there.

You have all you need though to program it as you require.
Feb 22 '09 #5

NeoPa
Expert Mod 15k+
P: 31,409
@wquatan
What am I talking about?!?

I just read through ADezii's code and it does exactly that for you :S Furthermore it illustrates clearly what it's doing with the output as displayed.

I'm confused as to what the problem is.

PS. I'm no longer confused. I see the limitation. It assumes that the whole file is small enough to fit into a string buffer. It should be fairly straightforward to build from this a version which handles the whole thing if less than a certain size, but breaks it down to multiples of your maximum buffer size if it exceeds that surely.
Feb 22 '09 #6

NeoPa
Expert Mod 15k+
P: 31,409
Alternatively, if buffered input is beyond your scope, direct input of each character is still quite plausible. It is all buffered by the operating system anyway. All the building blocks are introduced and there are even examples of how to use them.

We can probably help in more detail still, but are you sure you want us to?
Feb 22 '09 #7

P: 48
@NeoPa
Yep, that's the point.

And what I don't know (yet) is how to indicate to Get # that only one byte needs to be read, and at the next Get # that the second byte must be read a.s.o. I assume eof() can be used to detect the end.
Feb 22 '09 #8

P: 48
@NeoPa
What sort of remark is this ?
Feb 22 '09 #9

NeoPa
Expert Mod 15k+
P: 31,409
@wquatan
The amount of data read in with a Get# statement is equal to the number of characters already in the variable passed. But you would know this already if you'd simply checked out the resources I pointed you to in my earlier post.

Determining the size of the file, as already shown in ADezii's code, can be done with the LOF() function.
Feb 22 '09 #10

NeoPa
Expert Mod 15k+
P: 31,409
@wquatan
Since you ask - I thought you might be worried that it would appear you required spoon-feeding.

The answers are all there. It only takes a little effort to read through and find what you need.
Feb 22 '09 #11

NeoPa
Expert Mod 15k+
P: 31,409
I'm gonna take out that last part.

I reread through what you'd posted, and it probably didn't warrant such a response.

I'm still not exactly impressed, but what you wrote was not insulting of ADezii (as I'd misread it to be). What is left there now I do hold to be appropriate.
Feb 22 '09 #12

P: 48
@NeoPa
Attitude ? Which attitude ? Of the Administrator ?

I just wanted to know
- a fast example to read byte by byte (in the assumption) there might be different solutions with differences in processing speed or system-impact
- I was very pleased with the example given by ADezii but wasn't aware how to indicate the Get # to read one byte

Meaning, everything went fine, till a certain Administrator came in

EOD
Feb 22 '09 #13

P: 48
@wquatan
The above reply was related to the removed content of the Reply.

Be sure, that before posting any question, I try to do my homework by searching around. Google is my friend. But I didn't know the Get# command, probably the reason why I couldn't find anything.
Feb 22 '09 #14

NeoPa
Expert Mod 15k+
P: 31,409
@wquatan
I can appreciate that, without an administrator's ability to change your mind retrospectively, and the fact that I did, you deserve to be cut some slack on that. Consider it cut.
@wquatan
I appreciate that attitude.

I'm guessing from this that you never noticed post #2.

It was from how you behaved after that, that I got the impression you weren't bothering to check out what was posted. Clearly if you missed it, the rest must be viewed from an entirely different angle.
Feb 22 '09 #15

P: 48
The example from ADezii (with many thanks !!! ) adaped for Byte per Byte reading

Expand|Select|Wrap|Line Numbers
  1. Dim intFileNumber As Integer
  2. Dim lngByteNumber As Long
  3. Dim strOneByte As String * 1
  4. Dim strFileName As String
  5. strOneByte = Space$(1)     'Set Buffer Size to 1 byte
  6. strFileName = "C:\Windows\System.ini"
  7.  
  8. 'Get the next available File Number
  9. intFileNumber = FreeFile
  10.  
  11. DoCmd.Hourglass True
  12.  
  13. Open strFileName For Binary Access Read Shared As #intFileNumber
  14. Get #intFileNumber, , strOneByte     'Grab First Byte of Data from the File
  15.  
  16. Do While Not EOF(intFileNumber)
  17.     'Get and Display results on a Byte-by-Byte basic
  18.     lngByteNumber = lngByteNumber + 1
  19.     Debug.Print Format(lngByteNumber, "0000000") & " = Decimal(" & Format(Asc(strOneByte), "000") & _
  20.     "), Hexidecimal(" & Hex$(Asc(strOneByte)) & "), Character[" & strOneByte & "]"
  21.     Get #intFileNumber, , strOneByte     'Grab Next Byte of Data from the File
  22. Loop
  23.  
  24. Close #intFileNumber
  25. DoCmd.Hourglass False
Feb 22 '09 #16

ADezii
Expert 5K+
P: 8,619
I feel as though one critical point to mention here, the one that actually makes the entire process work, is the omission of the 2nd Argument to the Get # Statement in Code Lines #14 and #21 of Post #16. If you omit recnumber (missing Argument), the Byte following the last Get statement will be read for subsequent Get # Calls. Without this inherent characteristic, you would not be able to perform a Byte-by-Byte analysis.
Feb 23 '09 #17

P: 48
Hi ADezii

@ADezii
Could you explain what's wrong with the approach used ? It's seems doing exactly what I was looking after, but maybe I'm overlooking something

AFIK, the number of bytes read per Get# is determined by
strOneByte = Space$(1) 'Set Buffer Size to 1 byte

Isn't it correct that
strOneByte = Space$(n) 'Set Buffer Size to n bytes
would return n Bytes for every get# ?

Thx
Feb 23 '09 #18

ADezii
Expert 5K+
P: 8,619
@wquatan
Could you explain what's wrong with the approach used ?
Absolutely nothing that I can see. I was simply making a point about the second Argument to the Get # Statement. You may, however, wish to incorporate the code into a Function/Sub-Routine, passing to it the Path of the intended File. You may also wish to test for a Zero-Length String for the Passed File Name, and also test for the existence of the File itself. Take care.
Feb 23 '09 #19

Post your reply

Sign in to post your reply or Sign up for a free account.