Discrepancies between FileGet and StreamReader

G

Guest

Hello:

When I use either one to read a Text file, I get the same result. The length
of the string that the file's content has been written into is the same.

However, if the file is binary, FileGet gets me the correct content while
StreamReader gives me a truncated string.

Can somebody advise me why? Should I be using BinaryReader instead of
StreamReader? Would BinaryReader work on text files?

Venkat
 
G

Guest

I tried using BinayReader but unlike the simplicity of the one single
statement as follows:

FileGet(ciFileHandle, sFileContent)

which will read the contents of the file into sFileContent, I have to read
one byte at a time and concatenate to sFileContent.

Is there one Stream/Binary class that will work both on text and binary files?
 
H

Herfried K. Wagner [MVP]

vvenk said:
Can somebody advise me why? Should I be using
BinaryReader instead of StreamReader?

Depends on what you want to do. Notice that you can specify an encoding in
the 'StreamReader''s constructor.
Would BinaryReader work on text files?

Yes.

\\\
Dim br As New System.IO.BinaryReader( _
New System.IO.FileStream("C:\foo.txt", IO.FileMode.Open) _
)
Dim abyt() As Byte = br.ReadBytes(br.BaseStream.Length)
br.Close()
Dim s As String = System.Text.Encoding.Default.GetString(abyt)
///
 
G

Guest

Herfried:

Thank you so much for your tip. The BinaryReader, in my view, is more
versatile in that it handles different encoding.

Venkat
 
H

Herfried K. Wagner [MVP]

vvenk said:
Thank you so much for your tip. The BinaryReader, in my view,
is more versatile in that it handles different encoding.

The streamreader can handle different encodings too, and thus is more
high-level when reading text files.
 
G

Guest

Herfried:

Thanks to you, I am able to read a binary file and store its contents into a
string:

Dim lfsTemp = New FileStream("Original.INI", IO.FileMode.Open)
Dim lbrTemp = New BinaryReader(lfsTemp)
Dim lbTemp = lbrTemp.ReadBytes(lbrTemp.BaseStream.Length)
Dim sFileContent as String =
System.Text.Encoding.Default.GetString(lbTemp)

I tried saving sFileContent to a new file:

Dim lfsTemp As New FileStream("Copy.Ini", FileMode.CreateNew)
Dim lbwTemp As New BinaryWriter(lfsTemp)

SaveFile = False

lbwTemp.Write(sFileContent)
lbwTemp.Close()
lfsTemp.Close()


I see that the two file sizes are not the same.

Can you tell me why?

Venkat
 
H

Herfried K. Wagner [MVP]

vvenk said:
Thanks to you, I am able to read a binary file and
store its contents into a
string:

Dim lfsTemp = New FileStream("Original.INI", IO.FileMode.Open)
Dim lbrTemp = New BinaryReader(lfsTemp)
Dim lbTemp = lbrTemp.ReadBytes(lbrTemp.BaseStream.Length)
Dim sFileContent as String =
System.Text.Encoding.Default.GetString(lbTemp)

I tried saving sFileContent to a new file:

Dim lfsTemp As New FileStream("Copy.Ini", FileMode.CreateNew)
Dim lbwTemp As New BinaryWriter(lfsTemp)

SaveFile = False

lbwTemp.Write(sFileContent)
lbwTemp.Close()
lfsTemp.Close()


I see that the two file sizes are not the same.

Can you tell me why?

I assume that different encodings are used. If the source file is encoded
in your default code page, then you need 'Encoding.Default' to read it.
Notice that the binary reader does not know that it should use
'Encoding.Default' too to decompose the string into a byte array.
'BinaryWriter' provides a constructor that accepts an encoding:

\\\
Dim br As New BinaryWriter(..., Encoding.Default)
....
///
 
G

Guest

John:

As per your advice, I modified my write statement:

Dim lbwTemp As New BinaryWriter(lfsTemp, System.Text.Encoding.Default)

But I have the following differences:

1. The Original file content is 1205 bytes; the copy file contents is 1207
bytes.
2. I checked the ASC of first character; in Orginal it's 146 and in the
Copy, it's 181.

I see that when reading the file, I had used the following statement to
convert byte to string:

Dim sFileContent as String =
System.Text.Encoding.Default.GetString(lbTemp)

Should I be converting the string to byte before I write it to the file? If
so, can you help me with the syntax?

Thanks for your continued help.

Venkat
 
H

Herfried K. Wagner [MVP]

vvenk said:
Should I be converting the string to byte before I write it to the file?
If
so, can you help me with the syntax?
You can try to do that:

\\\
Dim abyt() As Byte = _
System.Text.Encoding.Default.GetBytes(Content)
....
///
 
G

Guest

Herbert:

I viewed the two files. The copy has two extra bytes added to the front.
That accounts for the difference in size. Let me try converting the string to
a byte and then saving it.

Thanks again.

venkat
 
G

Guest

Herfried:

I am so sorry. Coincidentally, I just finished talking to someone named
Herbert and the name was apparently etched into my short-term memory!

Venkat
 
J

Jay B. Harlow [MVP - Outlook]

Venkat
In addition to Herfried's excellent help.
I see that the two file sizes are not the same.

Can you tell me why?

BinaryWriter has overloaded Write methods, you asked to write a String.
BinaryWriter.Write(String) writes the encoded length of the string first,
followed by the contents of the string.

Based on your example you are only reading & writing text, I would recommend
using StreamReader & StreamWriter, they specialize in reading & writing text
to a file.

BinaryReader & BinaryWriter specialize in reading & writing stuff in binary
(its native bit format, aka bytes). For example Binary.Write(Integer) will
write four bytes that make up an Integer, BinaryWriter(Long) will write 8
bytes, where as StreamWriter.Write(Integer) will format the Integer as text,
then write the chars that make up that text.

To really see the difference compare the overloaded Write methods on
BinaryWriter:

http://msdn.microsoft.com/library/d.../frlrfSystemIOBinaryWriterClassWriteTopic.asp

With the overloaded Write methods on StreamWriter:

http://msdn.microsoft.com/library/d.../frlrfSystemIOStreamWriterClassWriteTopic.asp

Notice that BinaryWriter has all the "built-in" types, while StreamWriter
only as Char & String.

So using Stream Reader & Writer instead of Binary Reader & Writer you have:
Dim lfsTemp = New FileStream("Original.INI", IO.FileMode.Open)
Dim lbrTemp = New BinaryReader(lfsTemp)
Dim lbTemp = lbrTemp.ReadBytes(lbrTemp.BaseStream.Length)
Dim sFileContent as String =
System.Text.Encoding.Default.GetString(lbTemp)

Dim lbrTemp As New StreamReader("Original.INI", Encoding.Default)
Dim sFileContent As String = lbrTemp.ReadToEnd()

While:
Dim lfsTemp As New FileStream("Copy.Ini", FileMode.CreateNew)
Dim lbwTemp As New BinaryWriter(lfsTemp)

SaveFile = False

lbwTemp.Write(sFileContent)

With a StreamWriter is:

Dim lbwTemp As New StreamWriter("Copy.Ini", False, Encoding.Default)
lbwTemp.Write(sFileContent)

SaveFile = False

Note you can pass the file name directly to the constructor of BinaryReader,
BinaryWriter, StreamReader & StreamWriter. You don't have to create a
FileStream first...


Hope this helps
Jay
 
G

Guest

Jay:

Thank you for the additional help.

I am not reading and writing text. The file content is encrypted using a
custom algorithm and so, I need to be able to read the bytes.

Venkat
 
J

Jay B. Harlow [MVP - Outlook]

Venkat,
You may want to use a Stream directly & forgo BinaryReader or StreamReader
then.

I would consider creating an EncryptedStream (see composing streams below)
that inherits from Stream and overrides Stream.Read & Stream.Write to do the
encryption & decryption for me. Similar to
System.SecruityCryptography.CryptoStream. Note EncryptedStream would not be
based on FileStream.

Then depending on whether the encrypted contents is Binary or Text, I would
use a BinaryReader or StreamReader over a EncryptedStream.

Something Like:
Dim stream As New EncryptedStream(lfsTemp)

Dim reader As New StreamReader(stream)

Dim writer As New StreamWriter(stream)

By basing EncryptedStream on Steam itself, you can use EncryptedStream with
a NetworkStream or other kinds of stream & still encrypt & decrypt data from
them.

The following section of MSDN discusses streams and readers & writers:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconworkingwithio.asp

This page discusses composing streams (what I am suggesting above), but I
think could use a better example:
http://msdn.microsoft.com/library/d.../en-us/cpguide/html/cpconcomposingstreams.asp

Basically EncryptedStream would be a pass-through stream that provides the
encryption & decryption that you need, most of its methods would pass
through to its base stream, while some (read & write) would do the
decryption & encryption.

Hope this helps
Jay
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top