write data into specific position in text file - vb.net

I need to write in an existing text file at 30th position. I am using seek but not working. using below code. Using Startposition as 30.
Public Sub WriteToFile(ByVal data As DataTable, ByVal FileName As String, ByVal FieldLength As String, ByVal StartPosition As String)
Dim sbColumnData As New StringBuilder
Using writer = New StreamWriter(Directory.GetCurrentDirectory() + "\test.txt")
For Each oRecord In data.Rows
sbColumnData.Clear()
If oRecord(0).ToString().Length < FieldLength Then
sbColumnData.Append(oRecord(0).ToString().PadRight(FieldLength))
ElseIf oRecord(0).ToString().Length = FieldLength Then
sbColumnData.Append(oRecord.ToString())
Else
sbColumnData.Append(oRecord.ToString().Substring(0, FieldLength))
End If
writer.Seek(0, StartPosition )
writer.WriteLine(sbColumnData)
writer.Flush()
Next
End Using
End Sub

Your syntax is wrong. Try:
writer.Seek(StartPosition, SeekOrigin.Begin)
writer.Write(sbColumnData, 0, sbColumnData.Length);
https://msdn.microsoft.com/en-us/library/system.io.filestream.seek%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396

Related

How to most efficiently replace this code to vb.net version?

Public Function fileToColHarvest(ByRef stream As Scripting.TextStream, Optional ByRef limit As Integer = 2000000, Optional ByRef unique As Boolean = False, Optional ByRef FirstSectionAsKey As Boolean = False, Optional ByRef prob As Double = 1) As Generic.List(Of String)
Dim buffer As String
Dim i As Integer
If prob < 1 Then
End If
fileToColHarvest = New Generic.List(Of String)
Do While (Not (stream.AtEndOfStream))
i = i + 1
System.Windows.Forms.Application.DoEvents()
'If Microsoft.VisualBasic.Rnd < 0.01 Then
' appendToTextFile CStr(fileToColHarvest.Count) + "|" + microsoft.visualbasic.str(i) + "|" + buffer, RESULT, ForWriting
'End If
buffer = stream.ReadLine
'buffer = Microsoft.VisualBasic.Replace(buffer, " ", "+")
If Microsoft.VisualBasic.Rnd() < prob Then
If unique Then
If Not FirstSectionAsKey Then
fileToColHarvest.AddIfNotExist(buffer)
Else
fileToColHarvest.AddIfNotExist(buffer)
End If
Else
fileToColHarvest.Add(buffer)
End If
End If
If fileToColHarvest.Count() >= limit Then
Exit Do
End If
Loop
End Function
Basically I want to get rid Scripting.TextStream.
Also I want to read the text line by line
You can use StreamReader and asynchronous ReadLineAsync method.
Asynchronous approach will replace "ugly" Application.DoEvents()
Public Async Function FileToColHarvest(
pathToFile As String,
limit As Integer,
isUnique As Boolean,
isFirstSectionAsKey As Boolean,
prob As Single) As Task(Of List(Of String))
Dim lines = New List(Of String)()
Dim uniqueLines = New HashSet(Of String)()
Using stream As New FileStream(pathToFile, FileMode.Open)
Using reader As New StreamReader(stream)
While reader.EndOfStream = False
'Await will prevent blocking UI thread
var line = Await reader.ReadLineAsync()
If prob < VBMath.Rnd() Then Continue While
' I have removed check of isFirstSectionAsKey
' because based on your code it does same thing
If isUnique Then
uniqueLines.Add(line)
If uniqueLines.Count >= limit Then Return uniqueLines.ToList()
Else
lines.Add(line)
If lines.Count >= limit Then Return lines
End If
End While
End Using
End Using
Return If(isUnique, uniqueLines.ToList(), lines)
End Function
Not related but isUnique argument divide this method in two different logic - so I suggest instead of parameter introduce two different methods
FileToColHarvest(...)
FileToColHarvestWithUniqueOnly(...)

read specific values from text file

I have the following visual basic code, which is part of a custom class. I want a simple and effective way(use little computer resources) to assign the "value1" value(100) to "_field1","value2" value(8) to "_field2" etc. Any nice ideas? thanks
Private Sub readcrnFile()
'read files and assing values to the properties
Dim sr As New IO.StreamReader(_fileName)
_field1 = sr.ReadToEnd()
_field2 = sr.ReadToEnd()
_field3 = sr.ReadToEnd()
sr.Close()
End Sub
where _fileName is a full path to a text file which looks like this:
value1: 100
value2: 8
value3: 80
Private Sub readcrnFile()
Dim lines = File.ReadLines(_fileName)
For Each line In lines
Dim val = line.Split(":")(1).Trim
'do something with val?
Next
End Sub
Returning a dictionary is trivial:
Private Sub readcrnFile()
Dim dict = File.ReadLines(_fileName).Select(Function(line) line.Split(":")).ToDictionary(Function(parts) parts(0).Trim, Function(parts) parts(1).Trim)
Debug.WriteLine(dict("value1")) 'will print 100
End Sub
Change your _field1, _field2 and _field3 variables to a List(Of String) (i.e. named field) and access to each field using its index (field(0), field(1), field(2)).
Dim field As New List(Of String)
Private Sub readcrnFile()
For Each line In File.ReadAllLines(_filename)
For i = 1 To 3
If line.Contains("value" & i) Then
field.Add(line.Substring(line.IndexOf(":") + 2))
End If
Next
Next
End Sub

How to center text on Y axis when force wrapping a string

I force wrap some of my text. The following method is used in a loop when I do this; it returns the Y cord for the next line (based on the string height). This works like a charm, however I lose the ability to center the text vertically.
I'm looking for suggestions on how to enhance this method to allow for vertical centering.
<Extension()> _
Public Function DrawText(ByVal p_graphics As Graphics, ByVal p_text As String, ByVal p_Font As Font, ByVal p_fontColor As Brush, ByVal p_X As Decimal, ByVal p_Y As Decimal, _
ByVal p_boundingWidth As Decimal, ByVal p_StringFormat As StringFormat) As Decimal
If String.IsNullOrEmpty(p_text) Then
Return p_Y
End If
Dim _sizef As SizeF = p_graphics.MeasureString(p_text, p_Font, Integer.MaxValue, p_StringFormat)
Dim _LineCnt As Integer = Math.Ceiling(_sizef.Width / p_boundingWidth)
Dim _height As Integer = Math.Ceiling(_LineCnt * Math.Ceiling(_sizef.Height))
p_graphics.TextRenderingHint = Drawing.Text.TextRenderingHint.AntiAliasGridFit
Dim _rec As New RectangleF(p_X, p_Y, p_boundingWidth, _height)
p_graphics.DrawString(p_text, p_Font, p_fontColor, _rec, p_StringFormat)
Return (p_Y + _rec.Height)
End Function
Example of how I use this extension method (writing this free hand so syntax may not be correct):
.
.
.
Using g as graphics.FromImage(_MyImage)
Dim _LineStart as integer = 0
Foreach _line as string in _Lines 'List of String
_LineStart = g.DrawText(line, _font, Obj.FontColorBrush, 0, _LineStart, Obj.DPIWidth, Obj.StringFormat)
End For
End Using
.
.
.
OK, now I think I understand. You need to calculate where to start drawing vertically.
I put a PictureBox and a Button on a form, added your extension method, and used this code:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim lines As New List(Of String)
lines.Add("The quick brown")
lines.Add("fox jumps over")
lines.Add("the lazy dog.")
lines.Add("This line is too wide to fit the available space.")
Dim fmt = StringFormat.GenericTypographic
fmt.Alignment = StringAlignment.Center
Using fnt = New Font("Arial", 8)
Using brsh = New SolidBrush(Color.Black)
Using g = PictureBox1.CreateGraphics
Dim lineY As Integer = (PictureBox1.Height - lines.Count * fnt.Height) \ 2
For Each line As String In lines
lineY = CInt(g.DrawText(line, fnt, brsh, 0, lineY, PictureBox1.Width, fmt))
Next
End Using
End Using
End Using
End Sub
As I use Option Strict On, I had to make some minor modifications to your DrawText method.
Note how the line which is too long is truncated. Centred, but truncated. That is where you might want to use the Graphics.MeasureString Method (String, Font, SizeF, StringFormat) overload so that you have the possibility of it wrapping automatically. Which will of course mess up the calculation for the vertical centring.

Hex Edit with BinaryWriter (VB.NET)

I'm opening an .exe file in Hex Workshop, and I want to edit this line:
How is that possible with VB.NET using a BinaryWriter? The line represents the IP of the exe. I want to have a program that includes a textbox where you put the new IP. So, I have so far:
Using writer As BinaryWriter = New BinaryWriter(File.Open("C:\localhost.exe", FileMode.Open))
writer.BaseStream.Position = ???
writer.write???
End Using
So, what position do I set it to, and what type do I write? Bytes? Thanks.
Find the offset of the first character in your string and use this method:
Private Sub Patch(ByVal TargetFile As String, ByVal FileOffset As Long, ByVal NewValue() As Byte)
Try
Dim br As BinaryReader = New BinaryReader(File.Open(TargetFile, FileMode.Open))
br.BaseStream.Position = FileOffset
Dim byteB As Byte
For Each byteB In NewValue
If (byteB.ToString <> String.Empty) Then
br.BaseStream.WriteByte(byteB)
Else
Exit For
End If
Next byteB
br.Close()
Catch
End Try
End Sub
Like this:
Patch("C:\localhost.exe", Val("OFFSET OF FIRST CHARACTER IN STRING"), New Byte() {&H31, &H32, &H37, &H2e, &H30, &H2e, &H30, &H2e, &H38})
Or instead of your byte-array, use this:
System.Text.Encoding.ASCII.GetBytes("127.0.0.8") 'It'll change 127.0.0.1 to 127.0.0.8
Just make sure you have the right offset for the first character of your string

Count specific word in txt file vb.net

How do I count a specific word in a specific text file ussing vb.net
Something like this would help you:
Private Function GetWordCountInFile(ByVal filepath As String, ByVal word As String)
Dim dict As New Dictionary(Of String, Integer)()
Dim lst As New List(Of String)(IO.File.ReadAllText(filepath).Split(" "))
For Each entry As String In lst
If Not (dict.ContainsKey(entry.ToLower.Trim)) Then
dict.Add(entry.ToLower.Trim, 1)
Else
dict(entry.ToLower.Trim) += 1
End If
Next
lst.Clear()
Return dict(word.ToLower.Trim)
End Function
you can use it like this:
Dim count As Integer = GetWordCountInFile("../../Sample.txt", "sample")
This will look for a word "sample" in a text file "sample.txt" and returns a count.
Also, may not a good one but a single line approach would be:
Private Function GetWordCountInFile(ByVal filepath As String, ByVal word As String)
Return System.Text.RegularExpressions.Regex.Matches(IO.File.ReadAllText(filepath), "(?i)\b(\s+)?" & word & "(\s+|\S{0})\b|^" & word & "\.?$|" & word & "[\.\,\;]").Count
End Function
OR something like this: (no need to declare additional variable to hold word count)
Private Function GetWordCountInFile(ByVal filepath As String, ByVal word As String)
Dim lst As New List(Of String)(IO.File.ReadAllText(filepath).ToLower.Split(New Char() {" ", ",", ";", ".", ":"}))
Return lst.FindAll(Function(c) c.Trim() = word.ToLower).Count()
End Function
Assuming 4.0...
The word must be an exact match (excluding mixed case). If you want to count matching sub-words, such as searching for "sub" and counting "subway" as a word, change to LCase(strWord).Contains(LCase("TargetWord"))...
Dim intCount As Integer = 0
IO.File.ReadAllText("C:\file.txt").Split(" ").ToList().ForEach(Sub(strWord As String)
If LCase(strWord) = LCase("TargetWord") Then
intCount += 1
End If
End Sub)
MsgBox(CStr(intCount))