Zebra Printer Outputing HEX when trying to print a bitmap - vb.net

I am using a Zebra iMZ320 printer, a windows mobile device, CPCL and vb.net.
I am trying to get the code to load a bitmap image and then to print this using CPCL
I have previoulsy had a similar piece of code to that contaibed below working with no issue. I must be missing something obvious, but for the life of me I cannot see it.
My problem is the printer will only printout HEX instead of the image ! Has anyone come across this before ? Can you help ?
Public Sub DrawBitmap(ByVal xPosition As Integer, ByVal yPosition As Integer)
Dim bmp As Bitmap
bmp = New System.Drawing.Bitmap(GetLogo)
If bmp Is Nothing Then
Throw New ArgumentNullException("bmp")
End If
'Make sure the width is divisible by 8
Dim loopWidth As Integer = 8 - (bmp.Width Mod 8)
If loopWidth = 8 Then
loopWidth = bmp.Width
Else
loopWidth += bmp.Width
End If
cpclData = ""
cpclData = cpclData & "! 0 200 200 300 1 " & vbCr & vbLf
cpclData = cpclData & (String.Format("EG {0} {1} {2} {3} ", loopWidth \ 8, bmp.Height, xPosition, yPosition))
For y As Integer = 0 To bmp.Height - 1
Dim bit As Integer = 128
Dim currentValue As Integer = 0
For x As Integer = 0 To loopWidth - 1
Dim intensity As Integer
If x < bmp.Width Then
Dim color As Color = bmp.GetPixel(x, y)
Dim MyR As Integer = color.R
Dim MyG As Integer = color.G
Dim MyB As Integer = color.B
intensity = 255 - ((MyR + MyG + MyB) / 3)
Else
intensity = 0
End If
If intensity >= 128 Then
currentValue = currentValue Or bit
End If
bit = bit >> 1
If bit = 0 Then
cpclData = cpclData & (currentValue.ToString("X2"))
bit = 128
currentValue = 0
End If
'x
Next
Next
'y
cpclData = cpclData & vbCr & vbLf
cpclData = cpclData & "PRINT"
Print_Invoice()
End Sub
Public Shared Function StrToByteArray(ByVal str As String) As Byte()
Dim encoding As New System.Text.ASCIIEncoding()
Return encoding.GetBytes(str)
End Function
Private Sub Print_Invoice()
' Instantiate a connection
Dim thePrinterConn As ZebraPrinterConnection = New BluetoothPrinterConnection(MyMacAddress)
' Open the connection - physical connection is established here.
thePrinterConn.Open()
' Send the data to the printer as a byte array
thePrinterConn.Write(StrToByteArray(cpclData))
' Make sure the data got to the printer before closing the connection
Thread.Sleep(500)
' Close the connection to release resources.
thePrinterConn.Close()
' Debug output
txt_TestPrint.Text = cpclData.ToString
Dim objStreamWriter As StreamWriter
Dim file_name As String
'open dialog box for new file
SaveFileDialog1.InitialDirectory = "\Storage Card\"
If SaveFileDialog1.ShowDialog() = Windows.Forms.DialogResult.OK Then
file_name = SaveFileDialog1.FileName
If Len(file_name) > 0 Then
objStreamWriter = New StreamWriter(file_name & ".txt")
'Write a line of text from list box.
objStreamWriter.WriteLine(txt_TestPrint.Text)
'Close the file.
objStreamWriter.Close()
Exit Sub
End If
End If
End Sub
The code produce this file as output if it helps.
! 0 200 200 300 1
EG 10 80 10 10 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF800FFF8001FFFFFFFFFE0001FC00007FFFFFFFF800007000001FFFFFFFF01F80703FF80FFFFFFFE07FF800FFFE07FFFFFFC1FFFC01FFFF87FFFFFFC3FFFC01FFFF83FFFFFF87FFFC01FFFFC3FFFFFF87FFFC11FFFFC3FFFFFF87FFFC39FFFFC1FFFFFF87FFFC7FFFFFC1FFFFFF87FFFCFFFFFFC1FFFFFF87FFFFFFFFFFC1FFFFFFC3FFFFFFFFFFC3FFFFFFC1FFFFFFFFFF83FFFFFFE1FFFFFFFFFF07FFFFFFE1FFFFFFFFFE07FFFFFFE1FFFFFFFFFC0FFFFFFFE1FFFFCF0FF81FFFFFFFC3FFFF8001C03FFFFFFFC3FFCF800000FFFFFFFFC1FF87C04003FFFFFFFFE0FF07FFF81FFFFFFFFFE0780FFFFC3FFFFFFFFFF0001FFFF83FFFFFFFFFFC003FFFF87FFFFFFFFFFF803FFFF87FFFFFFFFFFFFC1FFFF87FFFFFFFFFFFFC1FFFF07FFFFFFFFFFFFE0FFFF0FFFFFFFFFFFFFE0FC020FFFFFFFFFFFFFF000000FFFFFFFFFFFFFF000001FFFFFFFFFFFFFF8001C1FFFFFFFFFFFFFF83E3F9FFFFFFFFFFFFFFCFE3FFFFFFFFFFFFFFFFF9C39FFFFFFFFFFFFFFFF8C70FFFFFFFFFFFFFFFF9879FFFFFFFFFFFFFFFFF8FFFFFFFFFFFFFFFF7FF807FFFFFFFFFFFFFEFFF00FFF7FFFFFFFFFFCFFF03FFF3FFFFFFFFFFCFFFFFFFF3FFFFFFFFFFCFFC001FF3FFFFFFFFFFC7F8000FE3FFFFFFFFFFC1F0000783FFFFFFFFFFC000FF0003FFFFFFFFFFE001FF8007FFFFFFFFFFF003FFC00FFFFF3FFFFFFC07FFF03FFFFE1FFF7FFFFFFFFFFFFFC61FFE0FFFFFFFFFFFFC023FFE01FFFFFFFFFFF803FFFF003FFFFFFFFF0C0FFFFF800FFFFFFFF00C1FFFFF02041FFC7FE00C3FFFFF070000E001E0183FFFFE070400C001F4183FFFFE000F008001FE001FFFFE001F0783C1FE000FFFFC083F0783C1FF0003FFC01C1E0F07E3FF03007FC01E1E0F0700FF83803FE00C1E0F06007F80C07FF0001E0F06007F8043FFFF003E0F83C1FF007FFFFFE0700F83C1FE00FFFFFFFFE0038001FF0FFFFFFFFFF003C001FFFFFFFFFFFFFE03E001FFFFFFFFFFFFFFFFFCFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
PRINT

The iMZ printer comes pre configured to be in line mode. You have to change it to zpl mode so that it would parse either zpl or cpcl
Send this SGD to change the language of the printer.
! U1 setvar "device.languages" "zpl"

You convert the bitmap to a hex string
cpclData = cpclData & (currentValue.ToString("X2"))
then you encode this as byte[]
Return encoding.GetBytes(str)
end send the data to the printer:
thePrinterConn.Write(StrToByteArray(cpclData))
But I assume you have to encode the hex data string back to a byte array with the coresponding hex values converted back to a byte. In example a hex string of "FFFFFFFF" has to be converted back to byte[]{0xff,0xff,0xff,0xff}, exxcpet the printer language (CPCL?) reads hex string data and converts that back to byte itself.

Related

How to operate with binary files faster?

What I'm trying to do:
Open two binary files, each 64 MB
Take first half of each byte of each file and combine those halves in 1 bytes same with second half, for example: first byte in first file is 0x51, in second file its 0xA2, so I need write two bytes in third file which are 0x5A and 0x12, same for whole bytes, therefore final length in third file will be 128 MB.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles
Button1.Click
Try
' choosing first file
OpenFileDialog1.FileName = "First file"
OpenFileDialog1.Title = "Choose the Address.bin file"
OpenFileDialog1.Filter = "bin files (*.bin)|*.bin|All files
(*.*)|*.*"
If OpenFileDialog1.ShowDialog() = Windows.Forms.DialogResult.OK
Then
Label1.Text =
System.IO.Path.GetFullPath(OpenFileDialog1.FileName)
Else
Exit Sub
End If
Catch ex As Exception
End Try
Try ' choosing first file
OpenFileDialog1.FileName = "Second FIle"
OpenFileDialog1.Title = "Choose the Flash.bin file"
OpenFileDialog1.Filter = "bin files (*.bin)|*.bin|All files (*.*)|*.*"
If OpenFileDialog1.ShowDialog() = Windows.Forms.DialogResult.OK Then
Label2.Text = System.IO.Path.GetFullPath(OpenFileDialog1.FileName)
Else
Exit Sub
End If
Catch ex As Exception
End Try
Dim firstFileByte(1) As Byte
Dim SecondFileByte(1) As Byte
Dim Result As String
Dim Result2 As String
Dim Final(1) As Byte
For i = 0 To FileLen(Label1.Text) - 1
Using FirstFile As New FileStream(Label1.Text, FileMode.Open) 'save
'FIRST DIGIT********************************************************************************************
FirstFile.Seek(i, SeekOrigin.Begin)
FirstFile.Read(firstFileByte, 0, 1)
'TextBox1.Text = final(0).ToString("X")
Using SecFile As New FileStream(Label2.Text, FileMode.Open) 'save
SecFile.Seek(i, SeekOrigin.Begin)
SecFile.Read(SecondFileByte, 0, 1)
End Using
Result = firstFileByte(0).ToString("X2").Substring(0, 1) & SecondFileByte(0).ToString("X2").Substring(0, 1) ' comobining frist half of the first file and second file
Result2 = firstFileByte(0).ToString("X2").Substring(1, 1) & SecondFileByte(0).ToString("X2").Substring(1, 1) ' comobining second half of the first file and second file
End Using
Using vFs As New FileStream(Environment.GetFolderPath(Environment.SpecialFolder.Desktop) & "\Result.bin", FileMode.Append) ' save
TextBox1.Text = Result2
'Dim FileLenVar As UInt32 = FileLen(Environment.GetFolderPath(Environment.SpecialFolder.Desktop) & "\Result.bin") - 1
Final(0) = Convert.ToByte(Result, 16) 'converting result to the byte
Final(1) = Convert.ToByte(Result2, 16)
vFs.Write(Final, 0, 1)
vFs.Write(Final, 1, 1)
End Using
Next
End Sub
It works, but takes a lot of time: it writes 1 MB in 1 minute. How can I optimize it?
The files are small enough to load into RAM for processing. Processing the data in RAM can minimise the disk I/O needed, the latter very often being the slowest part of a program, especially if it is done in very small pieces like individual bytes. As also noted by Ben Voigt, string operations are somewhat slower than numeric operations.
Here's a simple demonstration of what could be done:
Imports System.IO
Module Module1
Dim f1 As String = "C:\temp\A.bin"
Dim f2 As String = "C:\temp\B.bin"
Dim outFile As String = "C:\temp\C.bin"
Sub CombineFiles()
Dim a1 = File.ReadAllBytes(f1)
Dim a2 = File.ReadAllBytes(f2)
Dim c(a1.Length + a2.Length - 1) As Byte ' c for combined
Dim highBits As Byte = &HF0
Dim lowBits As Byte = &HF
For i = 0 To c.Length - 1 Step 2
c(i) = a1(i \ 2) And highBits Or a2(i \ 2) >> 4
c(i + 1) = a1(i \ 2) << 4 Or a2(i \ 2) And lowBits
Next
File.WriteAllBytes(outFile, c)
End Sub
Sub CreateTestFiles()
'TODO: be more creative with the generated data.
Dim nBytes = 64
Dim a(nBytes - 1) As Byte
For i = 0 To nBytes - 1
a(i) = &H12
Next
File.WriteAllBytes(f1, a)
For i = 0 To nBytes - 1
a(i) = &HAB
Next
File.WriteAllBytes(f2, a)
End Sub
Sub Main()
'CreateTestFiles()
CombineFiles()
End Sub
End Module
Of course, you'd check that the input files were of equal length, and check for any other possible problems ;)

VBA to load very large file in one go (no buffering)

I am experiencing an unexpected vb limitation on the string max size, as explained in this post:
VBA unexpected reach of string size limit
While I was expecting to be able to load files up to 2GB (2^31 char) using open path for binary and get function, I get an out of string space error when I try to load a string larger than 255,918,061 characters.
I managed to work around this issue buffering the input stream of get. The problem is that I need to load the file as an array of string by splitting the buffer on vbCrLf characters.
This requires then to build the array line by line. Moreover, since I cannot be sure whether the buffer is ending on a break line or not I need additional operations. This solution is Time and Memory consuming. Loading a file of 300MB with this code costs 900MB (!) use of memory by excel. Is there a better solution ?
Here bellow is my code:
Function Load_File(path As String) As Variant
Dim MyData As String, FNum As Integer
Dim LenRemainingBytes As Long
Dim BufferSizeCurrent As Long
Dim FileByLines() As String
Dim CuttedLine As Boolean
Dim tmpSplit() As String
Dim FinalSplit() As String
Dim NbOfLines As Long
Dim LastLine As String
Dim count As Long, i As Long
Const BufferSizeMax As Long = 100000
FNum = FreeFile()
Open path For Binary As #FNum
LenRemainingBytes = LOF(FNum)
NbOfLines = FileNbOfLines(path)
ReDim FinalSplit(NbOfLines)
CuttedLine = False
Do While LenRemainingBytes > 0
MyData = ""
If LenRemainingBytes > BufferSizeMax Then
BufferSizeCurrent = BufferSizeMax
Else
BufferSizeCurrent = LenRemainingBytes
End If
MyData = Space$(BufferSizeCurrent)
Get #FNum, , MyData
tmpSplit = Split(MyData, vbCrLf)
If CuttedLine Then
count = count - 1
tmpSplit(0) = LastLine & tmpSplit(0)
For i = 0 To UBound(tmpSplit)
If count > NbOfLines Then Exit For
FinalSplit(count) = tmpSplit(i)
count = count + 1
Next i
Else
For i = 0 To UBound(tmpSplit)
If count > NbOfLines Then Exit For
FinalSplit(count) = tmpSplit(i)
count = count + 1
Next i
End If
Erase tmpSplit
LastLine = Right(MyData, Len(MyData) - InStrRev(MyData, vbCrLf) - 1)
CuttedLine = Len(LastLine) > 1
LenRemainingBytes = LenRemainingBytes - BufferSizeCurrent
Loop
Close FNum
Load_File = FinalSplit
Erase FinalSplit
End Function
Where the function FileNbOfLines is efficiently returning the number of line break characters.
Edit:
My Needs are:
To look for a specific string within the file
To get a specific number of lines coming after this string
Here you go, not pretty but should give you the general concept:
Sub GetLines()
Const fileName As String = "C:\Users\bloggsj\desktop\testfile.txt"
Const wordToFind As String = "FindMe"
Dim lineStart As String
Dim lineCount As String
Dim linesAfterWord As Long
With CreateObject("WScript.Shell")
lineCount = .Exec("CMD /C FIND /V /C """" """ & fileName & """").StdOut.ReadAll
lineStart = Split(.Exec("CMD /C FIND /N """ & wordToFind & """ """ & fileName & """").StdOut.ReadAll, vbCrLf)(2)
End With
linesAfterWord = CLng(Trim(Mid(lineCount, InStrRev(lineCount, ":") + 1))) - CLng(Trim(Mid(lineStart, 2, InStr(lineStart, "]") - 2)))
Debug.Print linesAfterWord
End Sub
Uses CMD to count the number of lines, then find the line at which the word appears, then subtract one from the other to give you the amount of lines after the word has been found.
Answer: Yes, using ReadAll from FSO should do the job.
Best answer: Just avoid it !
My needs were:
Identify a specific string within the file
Extract a certain number of lines after this string
As far as you precisely know the exact amout of data you want to extract, and assuming this amount of data is below vba string size limit (!), here is what it does the job the faster.
Decrease of computation time is improved using binary comparison of strings. My code is as follows:
Function GetFileLines(path As String, str As String, NbOfLines As Long) As String()
Const BUFSIZE As Long = 100000
Dim StringFound As Boolean
Dim lfAnsi As String
Dim strAnsi As String
Dim F As Integer
Dim BytesLeft As Long
Dim Buffer() As Byte
Dim strBuffer As String
Dim BufferOverlap As String
Dim PrevPos As Long
Dim NextPos As Long
Dim LineCount As Long
Dim data As String
F = FreeFile(0)
strAnsi = StrConv(str, vbFromUnicode) 'Looked String
lfAnsi = StrConv(vbLf, vbFromUnicode) 'LineBreak character
Open path For Binary Access Read As #F
BytesLeft = LOF(F)
ReDim Buffer(BUFSIZE - 1)
'Overlapping buffer is 3/2 times the size of strBuffer
'(two bytes per character)
BufferOverlap = Space$(Int(3 * BUFSIZE / 4))
StringFound = False
Do Until BytesLeft = 0
If BytesLeft < BUFSIZE Then ReDim Buffer(BytesLeft - 1)
Get #F, , Buffer
strBuffer = Buffer 'Binary copy of bytes.
BytesLeft = BytesLeft - LenB(strBuffer)
Mid$(BufferOverlap, Int(BUFSIZE / 4) + 1) = strBuffer 'Overlapping Buffer
If Not StringFound Then 'Looking for the the string
PrevPos = InStrB(BufferOverlap, strAnsi) 'Position of the looked string within the buffer
StringFound = PrevPos <> 0
If StringFound Then strBuffer = BufferOverlap
End If
If StringFound Then 'When string is found, loop until NbOfLines
Do Until LineCount = NbOfLines
NextPos = InStrB(PrevPos, strBuffer, lfAnsi)
If NextPos = 0 And LineCount < NbOfLines Then 'Buffer end reached, NbOfLines not reached
'Adding end of buffer to data
data = data & Mid$(StrConv(strBuffer, vbUnicode), PrevPos)
PrevPos = 1
Exit Do
Else
'Adding New Line to data
data = data & Mid$(StrConv(strBuffer, vbUnicode), PrevPos, NextPos - PrevPos + 1)
End If
PrevPos = NextPos + 1
LineCount = LineCount + 1
If LineCount = NbOfLines Then Exit Do
Loop
End If
If LineCount = NbOfLines then Exit Do
Mid$(BufferOverlap, 1, Int(BUFSIZE / 4)) = Mid$(strBuffer, Int(BUFSIZE / 4))
Loop
Close F
GetFileLines = Split(data, vbCrLf)
End Function
To crunch even more computation time, it is highly advised to use fast string concatenation as explained here.
For instance the following function can be used:
Sub FastConcat(ByRef Dest As String, ByVal Source As String, ByRef ccOffset)
Dim L As Long, Buffer As Long
Buffer = 50000
L = Len(Source)
If (ccOffset + L) >= Len(Dest) Then
If L > Buffer Then
Dest = Dest & Space$(L)
Else
Dest = Dest & Space$(Buffer)
End If
End If
Mid$(Dest, ccOffset + 1, L) = Source
ccOffset = ccOffset + L
End Sub
And then use the function as follows:
NbOfChars = 0
Do until...
FastConcat MyString, AddedString, NbOfChars
Loop
MyString = Left$(MyString,NbOfChars)

How do I get an Ascii to warp to a certain value after it has past 122?

I am trying to write an encryption program. The problem I am facing is that I am converting the text to ascii and then adding on the offset. However when it goes past the letter 'z' I want it to warp back to 'a' and go from there.
Sub enc()
Text = TextBox1.Text
finalmessage = ""
letters = Text.ToCharArray
offset = ComboBox1.SelectedItem
For x = LBound(letters) To UBound(letters)
finalmessage = finalmessage + Chr(Asc(letters(x)) + offset)
Next
TextBox2.Text = finalmessage
End Sub
I guess to make it easy to decode afterwards, you should to it somewhat in the line of base64 encoding, first encoding everything to a normalized binary string, then encode in the range you want (since using binary, it has to be something that fits with 2^X).
To match your range, i used a baseset of 32, and a simple encoding decoding example (a bit more verbose that it should be, perhaps)
Module Module1
Dim encodeChars As String = "abcdefghijklmnopqrstuvwxyzABCDEF" ' use 32 as a base
Function Encode(text As String) As String
Dim bitEncoded As String = ""
Dim outputMessage As String = ""
For Each ch As Char In text.ToCharArray()
Dim i As Integer = Convert.ToByte(ch)
bitEncoded &= Convert.ToString(i, 2).PadLeft(8, "0"c)
Next
While bitEncoded.Length Mod 5 <> 0
bitEncoded &= "0"
End While
For position As Integer = 0 To bitEncoded.Length - 1 Step 5
Dim range As String = bitEncoded.Substring(position, 5)
Dim index As Integer = Convert.ToInt32(range, 2)
outputMessage &= encodeChars(index).ToString()
Next
Return outputMessage
End Function
Function Decode(encodedText As String) As String
Dim bitEncoded As String = ""
Dim outputMessage As String = ""
For Each ch In encodedText
Dim index As Integer = encodeChars.IndexOf(ch)
If index < 0 Then
Throw New FormatException("Invalid character in encodedText!")
End If
bitEncoded &= Convert.ToString(index, 2).PadLeft(5, "0"c)
Next
' strip the extra 0's
While bitEncoded.Length Mod 8 <> 0
bitEncoded = bitEncoded.Substring(0, bitEncoded.Length - 1)
End While
For position As Integer = 0 To bitEncoded.Length - 1 Step 8
Dim range As String = bitEncoded.Substring(position, 8)
Dim index As Integer = Convert.ToInt32(range, 2)
outputMessage &= Chr(index).ToString()
Next
Return outputMessage
End Function
Sub Main()
Dim textToEncode As String = "This is a small test, with some special characters! Just testing..."
Dim encodedText As String = Encode(textToEncode)
Dim decodedText As String = Decode(encodedText)
Console.WriteLine(textToEncode)
Console.WriteLine(encodedText)
Console.WriteLine(decodedText)
If Not String.Equals(decodedText, textToEncode) Then
Console.WriteLine("Encoding / decoding failed!")
Else
Console.WriteLine("Encoding / decoding completed succesfully!")
End If
Console.ReadLine()
End Sub
End Module
this then gives the following output?
This is a small test, with some special characters! Just testing...
krugsCzanfzsayjaonwwcBdmebAgkCBufqqhoAlunaqhgBBnmuqhgCdfmnuwcBbamnugcCtbmnAgkCtteeqeuDltoqqhizltoruwCzzofyxa
This is a small test, with some special characters! Just testing...
Encoding / decoding completed succesfully!

Open/Read a binary file - access rights

I am trying to convert VB5 to .NET and cannot get a binary read to work. My VB.NET decode only reads the first two characters correctly.
The (VB5->VB.NET) encode is
' Open file
x = Rnd(-mKeyValue)
filenum = FreeFile()
Try
FileOpen(filenum, Filename, OpenMode.Binary)
Catch ex As IO.IOException
MsgBox(ex.ToString, MsgBoxStyle.Critical, "File opening error")
Exit Sub
End Try
' write data
filecontents = ""
For i = 1 To Len(stringdate)
charnum = Asc(Mid(stringdate, i, 1))
randomint = Int(256 * Rnd())
charnum = charnum Xor randomint
singlechar = Chr(charnum)
FilePut(filenum, singlechar, i)
filecontents = filecontents & singlechar
Next i
And the (VB5->VB.NET) decode is
x = Rnd(-mKeyValue)
filenum = FreeFile()
FileOpen(filenum, Filename, OpenMode.Binary)
For i = 1 To LOF(filenum)
'To VB.NET
FileGet(filenum, singlechar, i)
charnum = Asc(singlechar)
Debug.Print("VB5 singlechar = " & singlechar)
randomint = Int(256 * Rnd())
charnum = charnum Xor randomint
singlechar = Chr(charnum)
Next i
My VB.NET code which fails (cannot read the file correctly) is;
Using reader As New BinaryReader(File.Open(Filename, FileMode.Open))
' Loop through length of file.
Dim pos As Integer = 0
Dim length As Integer = reader.BaseStream.Length
While pos < length
' Read the integer.
singlechar = reader.ReadChar()
charnum = Asc(singlechar) 'singlechar is type Char
randomint = Int(256 * Rnd())
charnum = charnum Xor randomint
singlechar = Chr(charnum)
i += 1
End While
End Using
Can anyone help me with translation from VB5 to .NET?
In VB.Net everything is a bit shorter ;)
' get a string from an encrypted file file:
Dim b() As Byte = IO.File.ReadAllBytes("path")
For i = 0 To b.Length - 1
b(i) = b(i) Xor (256 * Rnd())
Next
Dim s As String = System.Text.Encoding.ASCII.GetString(b)
Why read byte by byte (no sense to read 'char' anyway, since you only want the 8bit ASCII code), when .Net can read it at once? Your file is not larger > 100 MB, I assume? Then after getting the array, you simply XOR each element with your "random" value. If you dont need to be compatible to old versions, you might better use Random. Or maybe even better ... USE REAL ENCRYPTION (in .Net it's built-in!)
' put a string into a file
Dim c() As Byte = System.Text.Encoding.ASCII.GetBytes("The String you want to store encrypted")
For i = 0 To c.Length - 1
c(i) = c(i) Xor (256 * Rnd())
Next
IO.File.WriteAllBytes("another path", c)
Same for "encrypting". Convert the string to an array of byte (=ASCII values), XOR it and then write it back in ONE operation.
See the dangers of Unicode:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
' Beware of UNICODE ... !!!
Using sw As New FileStream("foo.foo", FileMode.OpenOrCreate, FileAccess.Write)
' with old VB you effectively wrote BYTE data
sw.Write({65, 192}, 0, 2)
End Using
Using br As New BinaryReader(File.Open("foo.foo", FileMode.Open, FileAccess.Read))
' You are telling. Net that you expect a CHAR, which is not ASCII, but UNICODE
Dim c As Char = br.ReadChar
Dim d As Char = br.ReadChar
Dim cc = Asc(c)
Dim dd = Asc(d)
Debug.Print("65 -> {0}, 192 -> {1}", cc, dd)
End Using
End Sub
The output is 65 -> 65, 192 -> 63

Read Number of lines in Large Text File VB6

I have text File of Size 230MB. I want to Count Number of Lines OF that File.
I tried "Scripting.FileSystemOblect" but it goes out Of memory.
Please Help.
Thanks.
Normal Windows line breaks are CRLF, so you can count the LFs and add 1 to the count in cases where the last line of your files doesn't have one after it.
In true VB (i.e. VB5, VB6, etc.) you can make use of the byte-oriented String operations to speed many tasks. If we can assume the text files contain ANSI then this is pretty fast:
Option Explicit
Private Sub Main()
Const BUFSIZE As Long = 100000
Dim T0 As Single
Dim LfAnsi As String
Dim F As Integer
Dim FileBytes As Long
Dim BytesLeft As Long
Dim Buffer() As Byte
Dim strBuffer As String
Dim BufPos As Long
Dim LineCount As Long
T0 = Timer()
LfAnsi = StrConv(vbLf, vbFromUnicode)
F = FreeFile(0)
Open "big.txt" For Binary Access Read As #F
FileBytes = LOF(F)
ReDim Buffer(BUFSIZE - 1)
BytesLeft = FileBytes
Do Until BytesLeft = 0
If BufPos = 0 Then
If BytesLeft < BUFSIZE Then ReDim Buffer(BytesLeft - 1)
Get #F, , Buffer
strBuffer = Buffer 'Binary copy of bytes.
BytesLeft = BytesLeft - LenB(strBuffer)
BufPos = 1
End If
Do Until BufPos = 0
BufPos = InStrB(BufPos, strBuffer, LfAnsi)
If BufPos > 0 Then
LineCount = LineCount + 1
BufPos = BufPos + 1
End If
Loop
Loop
Close #F
'Add 1 to LineCount if last line of your files do not
'have a trailing CrLf.
MsgBox "Counted " & Format$(LineCount, "#,##0") & " lines in" & vbNewLine _
& Format$(FileBytes, "#,##0") & " bytes of text." & vbNewLine _
& Format$(Timer() - T0, "0.0#") & " seconds."
End Sub
Given a 7,000,000 line file of 293MB it only takes 0.7 seconds here. But note that I had not rebooted to ensure that the file wasn't cached when I ran that test. Without caching (i.e. after a reboot) I'd expect it to take as long as 5 times that.
Converting to handle Unicode text files is fairly simple. Just replace the B-functions by the non-B equivalents, make sure you set BUFSIZE to a multiple of 2, and search for vbLf instead of an ANSI LF byte.
You can do it by reading each line into the same variable. There's no need to save all the lines:
dim s as string
dim n as integer
open "filename.txt" for input as 1
n = 0
do while not eof(1)
line input #1, s
n = n + 1
loop
This has not been tested, and it's been a while since I've done any VB6, but it should be close.
This takes about 6 seconds for me on a 480mb binary file with 1mil+ 0xD (vbcr)
Dim buff() As Byte
Dim hF As Integer
Dim i As Long, n As Long
hF = FreeFile(0)
Open "c:\windows\Installer\2f91fd.msp" For Binary Access Read As #hF
ReDim buff(LOF(hF) - 1)
Get #hF, , buff()
Close #hF
For i = 0 To UBound(buff)
If buff(i) = 13 Then n = n + 1
Next
MsgBox n