I need to read a txt file part by part...
For example, in a txt file: (age,5char_name)
17susan23wilma25fredy
I need to read firstly 17susan. In other words, the first seven characters and after 23wilma and 25fredy, but I'm not reading the whole file and substring the file record. Is there a way to do this via streamreader?
Records are always seven bytes... 2 bytes for age, 5 bytes for name and all records in a line. There is no jump into the next line.
I think there is the solution:
Dim filestream As New FileStream("\records.txt", FileMode.Open)
Dim streamreader As New StreamReader(fs)
Dim buffer(7) As Char
bw.ReadBlock(buffer, 0, 7)
Console.WriteLine(buffer)
this is read first 7.. you can read other via loop or for..
If you ALWAYS want to use the first 7 characters, you can simply use Visual Basic line of code like:
Dim Result as String = Microsoft.VisualBasic.Left(string, no)
String is the StreamReader line from which you want to read only first seven characters.
No is any integer value and it is equal to the number of characters you want to read, in this case 7.
Also, in the same way, you can use Right and Mid to select a string from the right or somewhere in the middle.
Assuming a static number of characters per record (seven in your description), you could use a FileStream reader instead, and use the Read method to retrieve seven chars at a time.
For example:
Const chunkSize As Integer = 7
Using inputFile = File.OpenRead("namefile.txt")
Dim bytesRead As Integer
Dim buffer = New Byte(chunkSize - 1) {}
bytesRead = inputFile.Read(buffer, 0, buffer.Length)
while bytesRead = 7
'Process the buffer here
bytesRead = inputFile.Read(buffer, 0, buffer.Length)
End While
End Using
(code isn't tested, but should be close)
Related
I'm trying to create an MP3 ID3v1 Tag editor in Visual Basic (2010)
I have no problem reading tags, however, I can't seem to update the tags correctly.
I use FileStream to open the file, and then I use BinaryWriter. I seek to right after the "TAG" header, which is 125 bytes from the end of file.
The first field is the Title field, which is 30 characters long.
So before writing the new tag, I would clear it by writing 30 spaces.
Then I seek back to the beginning, and try to write the new data. But it ends up overwriting data in the next field.
Dim file As New System.IO.FileStream(songpath, IO.FileMode.Open)
Dim bw As New System.IO.StreamWriter(file)
file.Seek(-125, IO.SeekOrigin.End)
bw.Write(" ")
file.Seek(-125, IO.SeekOrigin.End)
bw.Write(data(0))
bw.Close()
file.Close()
Here is a screen cap of the result. I attempted to write "Test" in the title field, I write the data and then reopen the file and this is what I get.
Rather than using file.Seek, I would set the .Position property, like this:
Imports System.IO
Imports System.Text
Module Module1
Sub Main()
Dim f = "C:\temp\sample.MP3"
Dim newTitle = "This is a test."
Dim dataLen = 30
Dim titleData(dataLen - 1) As Byte
Dim newTitleBytes = Encoding.ASCII.GetBytes(newTitle)
Array.Copy(newTitleBytes, titleData, Math.Min(dataLen, newTitleBytes.Length))
Using str As New FileStream(f, FileMode.Open, FileAccess.Write, FileShare.None)
Dim titlePosition = str.Length - 125
str.Position = titlePosition
str.Write(titleData, 0, dataLen)
End Using
End Sub
End Module
The unused portion of the title should be bytes with a value of zero - when you create an array its values are set to zero* for you. Then you can fill the start of the title bytes with the bytes which represent the string in ASCII. I suspect you could get away with using ISO-8859-1 if you need accented characters, but don't rely on that.
The Using construction makes sure that the file is closed afterwards even if something goes wrong.
* If it's an array of a numeric type, like Byte or Integer and so on.
I have two strings, each string is a PDF etiquette, I must to write this two etiquette into a PDF file. To do this I convert a each string to a byte array (I don't know if this is the best way) and each I Write into a PDF file. When I write one etiquette into PDF file all is good, I see the etiquette, but then I try to appending the second, the result is the same, into the file is only the first etiquette. For example this code write first etiquette and all working good:
Dim fs As FileStream = New FileStream(fullFileName, FileMode.CreateNew)
fs.Close()
fs = New FileStream(fullFileName, FileMode.Append)
Dim str As String = GetPDFString(27)
Dim binaryData As Byte() = ConvertStringToByte(str)
fs.Write(binaryData, 0, binaryData.Length)
fs.Close()
but if I want to append the second etiquette in the same PDF file using this code ... this not appending.
Dim fs As FileStream = New FileStream(fullFileName, FileMode.CreateNew)
fs.Close()
fs = New FileStream(fullFileName, FileMode.Append)
Dim str As String = GetPDFString(25)
Dim str1 As String = GetPDFString(27)
Dim binaryData As Byte() = ConvertStringToByte(str)
Dim binaryData1 As Byte() = ConvertStringToByte(str1)
fs.Write(binaryData, 0, binaryData.Length)
fs.Write(binaryData1, 0, binaryData1.Length)
fs.Close()
both have the same result, and I don't understand why the second etiquette isn't appending? Thank you a lot.
Your question title suggests that you are asking about how to append a byte to a FileStream, not about PDF, and not about Base64 string conversion (which you are using in your code).
Before asking a question on StackOverflow, you need to ensure you are conveying only one problem at a time. Remove everything that is not relevant, and prepare a code sample we can use in a brand new VS project, in order to reproduce your problem and help you solve it.
Now, if your question is really about appending a byte (or a byte array) to a file, it's as simple as one line of code (or two, if you keep FileStream approach). See below link:
C# Append byte array to existing file
Also copy-pasted for your convenience here (and converted from C# to VB.NET):
Dim appendMe As Byte() = New Byte(999) {}
File.AppendAllBytes("C:\test.exe", appendMe)
Or, to avoid memory overflow, if your byte array is expected to be large enough:
Public Shared Sub AppendAllBytes(path As String, bytes As Byte())
'argument-checking here.
Using stream = New FileStream(path, FileMode.Append)
stream.Write(bytes, 0, bytes.Length)
End Using
End Sub
With this line:
fs.Write(binaryData1, binaryData.Length + 1, binaryData1.Length)
Specifically the second argument (binaryData.Length + 1), you're telling it to start appending from the wrong position of binaryData1. If it's 3 bytes long, for example, and so is binaryData, it won't append anything. It should be similar to the first .Write line:
fs.Write(binaryData1, 0, binaryData1.Length)
So it appends all of binaryData1. It will still append it after binaryData - you don't need to specify the length of the preceeding binaryData in this line.
Alternatively, bypassing the above entirely, concatenate your two strings before encoding/writing them to the file:
Dim fs As FileStream = New FileStream(fullFileName, FileMode.CreateNew)
fs.Close()
fs = New FileStream(fullFileName, FileMode.Append)
Dim str As String = GetPDFString(id, token, depot, 25)
Dim str1 As String = GetPDFString(id, token, depot, 27)
Dim binaryData As Byte() = Convert.FromBase64String(str & str1) 'concatenate strings
fs.Write(binaryData, 0, binaryData.Length)
fs.Close()
I am trying to read a file from my computer and output its contents into a literal control. It gives the error : Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection. This is my first time using FileStream and I'm not 100% about all of the syntax for VB, or if there's even a community-preferred way of reading from a file, but could somebody help me out with this error?
This is the code:
Using fs As New FileStream(_path, FileMode.Open, FileAccess.Read)
Try
Dim fileLength As Integer = CInt(fs.Length)
Dim buffer() As Byte = New Byte() {fileLength}
Dim count As Integer
Dim sum As Integer = 0
While ((count = fs.Read(buffer, sum, fileLength - sum)) > 0)
sum = sum + count
End While
litOutput.Text = buffer.ToString()
Catch ex As Exception
'TODO: log error
End Try
End Using
This line is wrong
Dim buffer() As Byte = New Byte() {fileLength}
It declares an array of 1 byte in which you try to store the length of your file. Probably you have Option Strict set to Off and thus you could go away without noticing immediately the problem.
Of course, if your file is of a reasonable length and it is a simple textfile then there is no need for this loop. Just use File.ReadAllText or File.ReadLines or File.ReadAllLines, and by the way, your code read all your data in a single call because the last parameter of FileStream.Read is the quantity of bytes to read from file and the expression fileLength - sum produces a request to read all the bytes in a single call
Instead if you want to read your file in chunks of certain sizes then
probably you need
Using fs As New FileStream(path, FileMode.Open, FileAccess.Read)
Try
Dim chunkSize = 2000
Dim fileLength As Integer = CInt(fs.Length)
Dim buffer(fileLength) as Byte
Dim blockSize(chunkSize) as Byte
Dim count As Integer = -1
Dim pos As Integer = 0
While count <> 0
count = fs.Read(blockSize, 0, chunkSize-1)
Array.Copy(blockSize, 0, buffer, pos, count)
pos += count
End While
litOutput.Text = Encoding.UTF8.GetString(buffer)
Catch ex As Exception
Console.WriteLine(ex.Message)
End Try
End Using
Notice that this code assumes that your file is a Text file with UTF8 encoding.
It this is not the case then you could try with Encoding.ASCII.GetString or Encoding.Unicode.GetString
I'm using Visual Basic (Visual Studio 2010) to open and read a large text file that isn't delimited (the file is produced by a UNIX based program). I need to parse that long line into rows of 130 characters. I do know how to read the file. But I don't know how to break this up into those rows. Can you help?
In advance, thanks for your assistance!
Don
Create StreamReader strReader = New StreamReader("file.txt")
And use the method StreamReader.read(new char[130], 0, 130);
The 130 first character will be placed into the char array. Then, you have to offset until the end of the file.
The documentation of the function is here: http://msdn.microsoft.com/en-us/library/9kstw824(v=vs.110).aspx
Edit:
An even better way will be to use the readBlocks method as suggested here : When to use StreamReader.ReadBlock()?
char buffer = char[130];
int len = 0;
while((len = strReader.ReadBlock(buffer, 0 , 130)) != 0)
{
Dim value As String = New String(buffer);
Console.WriteLine(value);
}
The while will go on until there are remaining characters in your file. The value String contains your line of 130 character and you can do whatever you want with it.
Here's a VB version of Mathieu Nls ReadBlock() with some minor changes and fixes:
Dim charsRead As Integer
Dim buffer(129) As Char ' 0 to 129 = 130 chars
Using SR As New System.IO.StreamReader(RestranName)
While Not SR.EndOfStream
charsRead = SR.ReadBlock(buffer, 0, buffer.Length)
If charsRead > 0 Then
Dim str As New String(buffer, 0, charsRead)
Debug.Print(str)
End If
End While
End Using
I want to be able to make is so that when my program loads it checks to see if the bytes in the file are set to something specific. If they are set to a certain byte then carry out the code.
So I want to be able to make it go to a specific byte, check if it's a certain byte and if it is that certain byte then carry out the code else if it is something else then carry out the other code.
I tried this:
Dim bytes As Byte() = New Byte(writeStream.Length) {}
Dim ByteResult As Integer = writeStream.Read(bytes, 30, 1)
MsgBox(ByteResult)
But it didn't work because for some reason it always returned 1.
I also tried this:
Dim dataArray(60) As Byte
If dataArray(30) <> writeStream.ReadByte() - 0 Then
MsgBox("The bytes have been checked.")
End If
But that didn't seem to work either because it never opened the message box for me.
For example, I want it to seek to offset 30 and then check if the byte is 00 then I want it to carry out code 1 and else if it is 01 I want it to carry out code2.
Thanks.
I found that the following code works:
fLocation = ("file.txt")
Dim writeStream As New FileStream(fLocation, FileMode.Open)
Dim writeBinary As New BinaryWriter(writeStream)
writeStream.Seek(30, SeekOrigin.Begin)
Dim ByteResult = writeStream.ReadByte()
MsgBox(ByteResult)
You can also do this
Dim FileStream1 As New IO.FileStream("File.txt", IO.FileMode.Open)
FileStream1.Position = 30
MsgBox(FileStream1.ReadByte)
FileStream1.Close()
FileStream1.Dispose()