I am attempting to learn SharpDX via DirectX tutorials. I have this line of code in the C++ project I am working from:
std::ifstream fin("Models/skull.txt");
if(!fin)
{
MessageBox(0, L"Models/skull.txt not found.", 0, 0);
return;
}
UINT vcount = 0;
UINT tcount = 0;
std::string ignore;
fin >> ignore >> vcount;
fin >> ignore >> tcount;
fin >> ignore >> ignore >> ignore >> ignore;
float nx, ny, nz;
XMFLOAT4 black(0.0f, 0.0f, 0.0f, 1.0f);
std::vector<Vertex> vertices(vcount);
for(UINT i = 0; i < vcount; ++i)
{
fin >> vertices[i].Pos.x >> vertices[i].Pos.y >> vertices[i].Pos.z;
vertices[i].Color = black;
// Normal not used in this demo.
fin >> nx >> ny >> nz;
}
fin >> ignore;
fin >> ignore;
fin >> ignore;
mSkullIndexCount = 3*tcount;
std::vector<UINT> indices(mSkullIndexCount);
for(UINT i = 0; i < tcount; ++i)
{
fin >> indices[i*3+0] >> indices[i*3+1] >> indices[i*3+2];
}
fin.close();
And I would like to know how to covert this over to C#. I am 99% sure I need to be using System.IO.FileStream but I am unsure how all the C++ stuff works. What is really messing me up is the fin >> ignore >> vcount; If someone can explain to me how to do the same thing in C# I can probably figure it out from there.
As requested the text file resembles this:
VertexCount: 31076
TriangleCount: 60339
VertexList (pos, normal)
{
0.592978 1.92413 -2.62486 0.572276 0.816877 0.0721907
0.571224 1.94331 -2.66948 0.572276 0.816877 0.0721907
0.609047 1.90942 -2.58578 0.572276 0.816877 0.0721907
…
}
TriangleList
{
0 1 2
3 4 5
6 7 8
…
}
ignore is declared as a std::string. It appears that the original author of the code you are looking at was not aware of the std::istream::ignore function and is using a local variable to read in elements of the file they are simply discarding (that is, he didn't care about). So the lines like:
fin >> ignore >> vcount;
Are reading in a string element (basically up to the first whitespace) and dumping it into the local string he is ignoring, and then reading in the vcount value (which he is storing as an unsigned int).
If you are going to port this to C#, you could do the same thing (read in parts of the file and simply discard them) and it would be a fairly direct port.
As an example (not tested):
using (FileStream file = new FileStream("File.txt", FileMode.Open))
using (StreamReader reader = new StreamReader(file))
{
// with your sample, this will read "VertexCount: 31076"
string line = reader.ReadLine();
string sVCount = line.Substring(line.IndexOf(": ") + 2);
uint vcount = int.Parse(sVCount);
// ... read of your code
}
Thanks to Zac Howland's answer I was able to get everything working. For anyone else trying to convert Frank Luna's book from DirectX to SharpDX I hope this helps. Here is what I ended up doing:
private void _buildGeometryBuffers()
{
System.IO.FileStream fs = new System.IO.FileStream(#"Chapter6/Content/skull.txt", System.IO.FileMode.Open);
int vcount = 0;
int tcount = 0;
//string ignore = string.Empty; // this is not needed for my C# version
using (System.IO.StreamReader reader = new System.IO.StreamReader(fs))
{
// Get the vertice count
string currentLine = reader.ReadLine();
string extractedLine = currentLine.Substring(currentLine.IndexOf(" ") + 1);
vcount = int.Parse(extractedLine);
// Get the indice count
currentLine = reader.ReadLine();
extractedLine = currentLine.Substring(currentLine.IndexOf(" ") + 1);
tcount = int.Parse(extractedLine);
// Create vertex buffer
// Skip over the first 2 lines (these are not the lines we are looking for)
currentLine = reader.ReadLine();
currentLine = reader.ReadLine();
string[] positions = new string[6];
List<VertexPosCol> vertices = new List<VertexPosCol>(vcount);
for (int i = 0; i < vcount; ++i)
{
currentLine = reader.ReadLine();
extractedLine = currentLine.Substring(currentLine.IndexOf("\t") + 1);
positions = extractedLine.Split(' ');
// We only use the first 3, the last 3 are normals which are not used.
vertices.Add(new VertexPosCol(
new Vector3(float.Parse(positions[0]), float.Parse(positions[1]), float.Parse(positions[2])),
Color.Black)
);
}
BufferDescription vbd = new BufferDescription();
vbd.Usage = ResourceUsage.Immutable;
vbd.SizeInBytes = Utilities.SizeOf<VertexPosCol>() * vcount;
vbd.BindFlags = BindFlags.VertexBuffer;
vbd.StructureByteStride = 0;
_vBuffer = Buffer.Create(d3dDevice, vertices.ToArray(), vbd);
// Create the index buffer
// Skip over the next 3 lines (these are not the lines we are looking for)
currentLine = reader.ReadLine();
currentLine = reader.ReadLine();
currentLine = reader.ReadLine();
string[] indexes = new string[6];
_meshIndexCount = 3 * tcount;
List<int> indices = new List<int>(_meshIndexCount);
for (int i = 0; i < tcount; ++i)
{
currentLine = reader.ReadLine();
extractedLine = currentLine.Substring(currentLine.IndexOf("\t") + 1);
indexes = extractedLine.Split(' ');
indices.Add(int.Parse(indexes[0]));
indices.Add(int.Parse(indexes[1]));
indices.Add(int.Parse(indexes[2]));
}
BufferDescription ibd = new BufferDescription();
ibd.Usage = ResourceUsage.Immutable;
ibd.SizeInBytes = Utilities.SizeOf<int>() * _meshIndexCount;
ibd.BindFlags = BindFlags.IndexBuffer;
_iBuffer = Buffer.Create(d3dDevice, indices.ToArray(), ibd);
}
fs.Close();
}
As always is someone sees a problem with the code or a better way of doing something I am always open to ideas.
Related
I found a C# source code that read from file which have 1000000 double number. The source code is below.
public void filereader()
{
using (BinaryReader b = new BinaryReader(File.Open("C:\\Users\\Hanieh\\Desktop\\nums.txt", FileMode.Open)))
{
int length = (int)b.BaseStream.Length;
byte[] fileBytes = b.ReadBytes(length);
for (int ii = 0; ii < fileBytes.Length - 32 ; ii++)
{
savg1[ii / 2] = (double)(BitConverter.ToInt16(fileBytes, ii) / 20000.0);// inja error index midee
ii++;
}
}
}
when I run source code to read from text file I have an error that related to savg1 index that is out of bound. I debug step by step and result shows size of length= 24000000 but savg1=1000000. my question is here: how this source code work and how I can fix this problem.
I suggest something like this (File.ReadAllBytes and BitConverter.ToDouble):
byte[] source = File.ReadAllBytes(#"C:\Users\Hanieh\Desktop\nums.txt");
double[] data = new double[source.Length / sizeof(double)];
for (int i = 0; i < data.Length; ++i)
data[i] = BitConverter.ToDouble(source, i * sizeof(double));
I would solve it like:
double[] data;
using (BinaryReader b = new BinaryReader(File.Open("C:\\Users\\Hanieh\\Desktop\\nums.txt", FileMode.Open)))
{
// create array/buffer for the doubles (filelength / bytes per double)
data = new double[b.BaseStream.Length / sizeof(double)];
// read the data from the binarystream
for (int i = 0; i < data.Length; i++)
data[i] = b.ReadDouble();
}
MessageBox.Show("doubles read: " + data.Length.ToString());
Although, your file nums.txt implies that it is a textfile. You might not read it as a binary file.
I'm currently trying to do pitch shifting of a wave file using this algorithm
https://sites.google.com/site/mikescoderama/pitch-shifting
Here my code which use the above implementation, but with no luck. The outputted wave file seems to be corrupted or not valid.
The code is quite simple, except for the pitch shift algorithm :)
It load a wave file, it reads the wave file data and put it in a
byte[] array.
Then it "normalize" bytes data into -1.0f to 1.0f format (as
requested by the creator of the pitch shift algorithm).
It applies the pitch shift algorithm and then convert back the
normalized data into a bytes[] array.
Finally saves a wave file with the same header of the original wave
file and the pitch shifted data.
Am I missing something?
static void Main(string[] args)
{
// Read the wave file data bytes
byte[] waveheader = null;
byte[] wavedata = null;
using (BinaryReader reader = new BinaryReader(File.OpenRead("sound.wav")))
{
// Read first 44 bytes (header);
waveheader= reader.ReadBytes(44);
// Read data
wavedata = reader.ReadBytes((int)reader.BaseStream.Length - 44);
}
short nChannels = BitConverter.ToInt16(waveheader, 22);
int sampleRate = BitConverter.ToInt32(waveheader, 24);
short bitRate = BitConverter.ToInt16(waveheader, 34);
// Normalized data store. Store values in the format -1.0 to 1.0
float[] in_data = new float[wavedata.Length / 2];
// Normalize wave data into -1.0 to 1.0 values
using(BinaryReader reader = new BinaryReader(new MemoryStream(wavedata)))
{
for (int i = 0; i < in_data.Length; i++)
{
if(bitRate == 16)
in_data[i] = reader.ReadInt16() / 32768f;
if (bitRate == 8)
in_data[i] = (reader.ReadByte() - 128) / 128f;
}
}
//PitchShifter.PitchShift(1f, in_data.Length, (long)1024, (long)32, sampleRate, in_data);
// Backup wave data
byte[] copydata = new byte[wavedata.Length];
Array.Copy(wavedata, copydata, wavedata.Length);
// Revert data to byte format
Array.Clear(wavedata, 0, wavedata.Length);
using (BinaryWriter writer = new BinaryWriter(new MemoryStream(wavedata)))
{
for (int i = 0; i < in_data.Length; i++)
{
if(bitRate == 16)
writer.Write((short)(in_data[i] * 32768f));
if (bitRate == 8)
writer.Write((byte)((in_data[i] * 128f) + 128));
}
}
// Compare new wavedata with copydata
if (wavedata.SequenceEqual(copydata))
{
Console.WriteLine("Data has no changes");
}
else
{
Console.WriteLine("Data has changed!");
}
// Save modified wavedata
string targetFilePath = "sound_low.wav";
if (File.Exists(targetFilePath))
File.Delete(targetFilePath);
using (BinaryWriter writer = new BinaryWriter(File.OpenWrite(targetFilePath)))
{
writer.Write(waveheader);
writer.Write(wavedata);
}
Console.ReadLine();
}
The algorithm here works fine
https://sites.google.com/site/mikescoderama/pitch-shifting
My mistake was on how i was reading the wave header and wave data. I post here the fully working code
WARNING: this code works only for PCM 16 bit (stereo/mono) waves. Can be easily adapted to works with PCM 8 bit.
static void Main(string[] args)
{
// Read header, data and channels as separated data
// Normalized data stores. Store values in the format -1.0 to 1.0
byte[] waveheader = null;
byte[] wavedata = null;
int sampleRate = 0;
float[] in_data_l = null;
float[] in_data_r = null;
GetWaveData("sound.wav", out waveheader, out wavedata, out sampleRate, out in_data_l, out in_data_r);
//
// Apply Pitch Shifting
//
if(in_data_l != null)
PitchShifter.PitchShift(2f, in_data_l.Length, (long)1024, (long)10, sampleRate, in_data_l);
if(in_data_r != null)
PitchShifter.PitchShift(2f, in_data_r.Length, (long)1024, (long)10, sampleRate, in_data_r);
//
// Time to save the processed data
//
// Backup wave data
byte[] copydata = new byte[wavedata.Length];
Array.Copy(wavedata, copydata, wavedata.Length);
GetWaveData(in_data_l, in_data_r, ref wavedata);
//
// Check if data actually changed
//
bool noChanges = true;
for (int i = 0; i < wavedata.Length; i++)
{
if (wavedata[i] != copydata[i])
{
noChanges = false;
Console.WriteLine("Data has changed!");
break;
}
}
if(noChanges)
Console.WriteLine("Data has no changes");
// Save modified wavedata
string targetFilePath = "sound_low.wav";
if (File.Exists(targetFilePath))
File.Delete(targetFilePath);
using (BinaryWriter writer = new BinaryWriter(File.OpenWrite(targetFilePath)))
{
writer.Write(waveheader);
writer.Write(wavedata);
}
Console.ReadLine();
}
// Returns left and right float arrays. 'right' will be null if sound is mono.
public static void GetWaveData(string filename, out byte[] header, out byte[] data, out int sampleRate, out float[] left, out float[] right)
{
byte[] wav = File.ReadAllBytes(filename);
// Determine if mono or stereo
int channels = wav[22]; // Forget byte 23 as 99.999% of WAVs are 1 or 2 channels
// Get sample rate
sampleRate = BitConverter.ToInt32(wav, 24);
int pos = 12;
// Keep iterating until we find the data chunk (i.e. 64 61 74 61 ...... (i.e. 100 97 116 97 in decimal))
while(!(wav[pos]==100 && wav[pos+1]==97 && wav[pos+2]==116 && wav[pos+3]==97)) {
pos += 4;
int chunkSize = wav[pos] + wav[pos + 1] * 256 + wav[pos + 2] * 65536 + wav[pos + 3] * 16777216;
pos += 4 + chunkSize;
}
pos += 4;
int subchunk2Size = BitConverter.ToInt32(wav, pos);
pos += 4;
// Pos is now positioned to start of actual sound data.
int samples = subchunk2Size / 2; // 2 bytes per sample (16 bit sound mono)
if (channels == 2)
samples /= 2; // 4 bytes per sample (16 bit stereo)
// Allocate memory (right will be null if only mono sound)
left = new float[samples];
if (channels == 2)
right = new float[samples];
else
right = null;
header = new byte[pos];
Array.Copy(wav, header, pos);
data = new byte[subchunk2Size];
Array.Copy(wav, pos, data, 0, subchunk2Size);
// Write to float array/s:
int i=0;
while (pos < subchunk2Size)
{
left[i] = BytesToNormalized_16(wav[pos], wav[pos + 1]);
pos += 2;
if (channels == 2)
{
right[i] = BytesToNormalized_16(wav[pos], wav[pos + 1]);
pos += 2;
}
i++;
}
}
// Return byte data from left and right float data. Ignore right when sound is mono
public static void GetWaveData(float[] left, float[] right, ref byte[] data)
{
// Calculate k
// This value will be used to convert float to Int16
// We are not using Int16.Max to avoid peaks due to overflow conversions
float k = (float)Int16.MaxValue / left.Select(x => Math.Abs(x)).Max();
// Revert data to byte format
Array.Clear(data, 0, data.Length);
int dataLenght = left.Length;
int byteId = -1;
using (BinaryWriter writer = new BinaryWriter(new MemoryStream(data)))
{
for (int i = 0; i < dataLenght; i++)
{
byte byte1 = 0;
byte byte2 = 0;
byteId++;
NormalizedToBytes_16(left[i], k, out byte1, out byte2);
writer.Write(byte1);
writer.Write(byte2);
if (right != null)
{
byteId++;
NormalizedToBytes_16(right[i], k, out byte1, out byte2);
writer.Write(byte1);
writer.Write(byte2);
}
}
}
}
// Convert two bytes to one double in the range -1 to 1
static float BytesToNormalized_16(byte firstByte, byte secondByte)
{
// convert two bytes to one short (little endian)
short s = (short)((secondByte << 8) | firstByte);
// convert to range from -1 to (just below) 1
return s / 32678f;
}
// Convert a float value into two bytes (use k as conversion value and not Int16.MaxValue to avoid peaks)
static void NormalizedToBytes_16(float value, float k, out byte firstByte, out byte secondByte)
{
short s = (short)(value * k);
firstByte = (byte)(s & 0x00FF);
secondByte = (byte)(s >> 8);
}
sorry to revive this but I tried that pitchshifter class and, while it works, I get crackles in the audio while pitching down(0.5f). You work out a way around that?
Well I am currently trying to implement a compression algorithm in my project, it has to be lz77 as a matter of effect... I am already able to decompress data but I can't imagine where to start in terms of compressing. I thought it would be best to pass by a byte array with data, but that's about it...
My problem is that all descriptions of the algorithm are quite cryptic for me to understand. I would appreciate a clear description of how the algorithm works and what I have to watch for.
Also: Am I obliged to use unsafe methods and pointers when coding in C#? It would be better to avoid that... I suppose.
Here is what I got so far thanks to the information you gave me:
private const int searchWindow = 4095;
private const byte lookaheadWindow = 15;
public static byte[] lzCompressData(byte[] input)
{
int position = 0;
List<byte> tempInput = input.ToList();
List<byte> output = new List<byte>();
MemoryStream init = new MemoryStream();
BinaryWriter inbw = new BinaryWriter(init);
inbw.Write(((input.Length << 8) & 0xFFFFFF00) | 0x10);
output.AddRange(init.ToArray());
while (position < input.Length)
{
byte decoder = 0;
List<byte> tempOutput = new List<byte>();
for (int i = 0; i < 8; ++i)
{
List<byte> eligible;
if(position < 255)
{
eligible = tempInput.GetRange(0, position);
}
else
{
eligible = tempInput.GetRange(position - searchWindow, searchWindow);
}
if (!(position > input.Length - 8))
{
MemoryStream ms = new MemoryStream(eligible.ToArray());
List<byte> currentSequence = new List<byte>();
currentSequence.Add(input[position]);
int offset = 0;
int length = 0;
long tempoffset = StreamHelper.FindPosition(ms, currentSequence.ToArray());
while ((tempoffset != -1) && (length < lookaheadWindow) && position < input.Length - 8)
{
offset = (int)tempoffset;
length = currentSequence.Count;
position++;
currentSequence.Add(input[position]);
}
if (length >= 3)
{
decoder = (byte)(decoder | (byte)(1 << i));
byte b1 = (byte)((length << 4) | (offset >> 8));
byte b2 = (byte)(offset & 0xFF);
tempOutput.Add(b1);
tempOutput.Add(b2);
}
else
{
tempOutput.Add(input[position]);
position++;
}
}
else
{
if (position < input.Length)
{
tempOutput.Add(input[position]);
position++;
}
else
{
tempOutput.Add(0xFF);
}
}
}
output.Add(decoder);
output.AddRange(tempOutput.ToArray());
}
return output.ToArray();
}
I would apreciate a clear description of how the algorithm works and
what I have to watch for
it is very well explained here . If you have problem in understanding something specific please ask that.
Am I obliged to use unsafe methods and pointers when coding in C#
You don't have to worry about anything. No need to re-invent the wheel. it is already implemented. its implementation
I want to add some string in the middle of image metadata block. Under some specific marker. I have to do it on bytes level since .NET has no support for custom metadata fields.
The block is built like 1C 02 XX YY YY ZZ ZZ ZZ ... where XX is the ID of the field I need to append and YY YY is the size of it, ZZ = data.
I imagine it should be more or less possible to read all the image data up to this marker (1C 02 XX) then increase the size bytes (YY YY), add data at the end of ZZ and then add the rest of the original file? Is this correct?
How should I go on with it? It needs to work as fast as possible with 4-5 MB JPEG files.
In general there is no way to speed up this operation. You have to read at least portion that needs to be moved and write it again in updated file. Creating new file and copying content to it may be faster if you can parallelize read and write operations.
Note: In you particular case it may not be possible to just insert content in the middle of the file as most of file formats are not designed with such modifcations in mind. Often there are offsets to portions of the file that will be invalid when you shift part of the file. Specifying what file format you trying to work with may help other people to provide better approaches.
Solved the problem with this code:
List<byte> dataNew = new List<byte>();
byte[] data = File.ReadAllBytes(jpegFilePath);
int j = 0;
for (int i = 1; i < data.Length; i++)
{
if (data[i - 1] == (byte)0x1C) // 1C IPTC
{
if (data[i] == (byte)0x02) // 02 IPTC
{
if (data[i + 1] == (byte)fileByte) // IPTC field_number, i.e. 0x78 = IPTC_120
{
j = i;
break;
}
}
}
}
for (int i = 0; i < j + 2; i++) // add data from file before this field
dataNew.Add(data[i]);
int countOld = (data[j + 2] & 255) << 8 | (data[j + 3] & 255); // curr field length
int countNew = valueToAdd.Length; // new string length
int newfullSize = countOld + countNew; // sum
byte[] newSize = BitConverter.GetBytes((Int16)newfullSize); // Int16 on 2 bytes (to use 2 bytes as size)
Array.Reverse(newSize); // changes order 10 00 to 00 10
for (int i = 0; i < newSize.Length; i++) // add changed size
dataNew.Add(newSize[i]);
for (int i = j + 4; i < j + 4 + countOld; i++) // add old field value
dataNew.Add(data[i]);
byte[] newString = ASCIIEncoding.ASCII.GetBytes(valueToAdd);
for (int i = 0; i < newString.Length; i++) // append with new field value
dataNew.Add(newString[i]);
for (int i = j + 4 + newfullSize; i < data.Length; i++) // add rest of the file
dataNew.Add(data[i]);
byte[] finalArray = dataNew.ToArray();
File.WriteAllBytes(Path.Combine(Path.GetDirectoryName(jpegFilePath), "newfile.jpg"), finalArray);
Here is an easy and quite fast solution. It moves all bytes after given offset to their new position according to given extraBytes, so you can insert your data.
public void ExpandFile(FileStream stream, long offset, int extraBytes)
{
// http://stackoverflow.com/questions/3033771/file-io-with-streams-best-memory-buffer-size
const int SIZE = 4096;
var buffer = new byte[SIZE];
var length = stream.Length;
// Expand file
stream.SetLength(length + extraBytes);
var pos = length;
int to_read;
while (pos > offset)
{
to_read = pos - SIZE >= offset ? SIZE : (int)(pos - offset);
pos -= to_read;
stream.Position = pos;
stream.Read(buffer, 0, to_read);
stream.Position = pos + extraBytes;
stream.Write(buffer, 0, to_read);
}
Need to be checked, though...
I have a program write save a text file using stdio interface. It swap the 4 MSB with the 4 LSB, except the characters CR and/or LF.
I'm trying to "decode" this stream using a C# program, but I'm unable to get the original bytes.
StringBuilder sb = new StringBuilder();
StreamReader sr = new StreamReader("XXX.dat", Encoding.ASCII);
string sLine;
while ((sLine = sr.ReadLine()) != null) {
string s = "";
byte[] bytes = Encoding.ASCII.GetBytes(sLine);
for (int i = 0; i < sLine.Length; i++) {
byte c = bytes[i];
byte lb = (byte)((c & 0x0F) << 4), hb = (byte)((c & 0xF0) >> 4);
byte ascii = (byte)((lb) | (hb));
s += Encoding.ASCII.GetString(new byte[] { ascii });
}
sb.AppendLine(s);
}
sr.Close();
return (sb);
I've tried to change encoding in UTF8, but it didn't worked. I've also used a BinaryReader created using the 'sr' StreamReader, but nothing good happend.
StringBuilder sb = new StringBuilder();
StreamReader sr = new StreamReader("XXX.shb", Encoding.ASCII);
BinaryReader br = new BinaryReader(sr.BaseStream);
string sLine;
string s = "";
while (sr.EndOfStream == false) {
byte[] buffer = br.ReadBytes(1);
byte c = buffer[0];
byte lb = (byte)((c & 0x0F) << 4), hb = (byte)((c & 0xF0) >> 4);
byte ascii = (byte)((lb) | (hb));
s += Encoding.ASCII.GetString(new byte[] { ascii });
}
sr.Close();
return (sb);
If the file starts with 0xF2 0xF2 ..., I read everything except the expected value. Where is the error? (i.e.: 0xF6 0xF6).
Actually this C code do the job:
...
while (fgets(line, 2048, bfd) != NULL) {
int cLen = strlen(xxx), lLen = strlen(line), i;
// Decode line
for (i = 0; i < lLen-1; i++) {
unsigned char c = (unsigned char)line[i];
line[i] = ((c & 0xF0) >> 4) | ((c & 0x0F) << 4);
}
xxx = realloc(xxx , cLen + lLen + 2);
xxx = strcat(xxx , line);
xxx = strcat(xxx , "\n");
}
fclose(bfd);
What wrong in the C# code?
Got it.
The problem is the BinaryReader construction:
StreamReader sr = new StreamReader("XXX.shb", Encoding.ASCII);
BinaryReader br = new BinaryReader(sr.BaseStream);
I think this construct a BinaryReader based on StreaReader which "translate" characters coming from the file.
Using this code, actually works well:
FileInfo fi = new FileInfo("XXX.shb");
BinaryReader br = new BinaryReader(fi.OpenRead());
I wonder if it is possible to read those kind of data with a Text stream reader line by line, since line endings are preserved during "encoding" phase.
I guess you should use a BinaryReader and ReadBytes(), then only use Encoding.ASCII.GetString() on the bytesequence after you have swapped the bits.
In your example, you seem to read the file as ascii (meaning, you convert bytes to .NET internal dual-byte code upon read telling it that it is ascii), then convert it BACK to bytes again, as ascii-bytes.
That is unnecessary for you.