How to simplify replacement process of fixed length line in a file
To get byte[]
from the object Item
, I've this:
byte[] getBytes(Item item)
{
var array = new byte[64];
var name = Encoding.ASCII.GetBytes(item.Name);
var address = Encoding.ASCII.GetBytes(item.Address);
Buffer.BlockCopy(BitConverter.GetBytes(item.Id), 0, array, 0, 4);
Buffer.BlockCopy(name, 0, array, 4, name.Length);
Buffer.BlockCopy(address, 0, array, 20, address.Length);
return array;
}
and in the Test function I, first, create and append 20 lines to the text file and then search for Id, 10, and replace the last field of the Item with Id 10 with this:
void Test(object o)
{
var file = "test.txt";
var stream = new FileStream(file, FileMode.Append);
for (int i = 0; i < 20; i++)
{
var item = new Item()
{
Id = i + 1,
Name = "Item No.: " + (i + 1),
Address = @"Address of Item\nis road " + (i + 1)
};
stream.Write(getBytes(item));
}
stream.Close();
int id;
var idArray = new byte[4];
stream = new FileStream(file, FileMode.Open, FileAccess.ReadWrite);
while(stream.Position < stream.Length)
{
stream.Read(idArray, 0, 4);
id = BitConverter.ToInt32(idArray, 0);
if(id == 10)
{
var address = Encoding.ASCII.GetBytes("New Address");
var addressArray = new byte[44];
Buffer.BlockCopy(address, 0, addressArray, 0, address.Length);
stream.Position += 16;
stream.Write(addressArray, 0, addressArray.Length);
break;
}
stream.Position += 60;
}
stream.Close();
}
appending is simple BUT the replacement isn't right at this moment. What I'm doing is. First get the byte[] from the string, then create another byte[] of appropriate length, then copy the original array into the new array and finally write.
Can this be done in a single shot?
EDIT
Another side question: I used these Buffer
, Encoding
, BitConverter
, etc. in another socket application to exchange array between clients and server. At that time those array, which were converted from string, had trailing sequences of \0
BUT now in my text file I don't see those \0
, why?
Another issue is I don't see Id in the file, in most of the cases that's replaced with rectangle and in other cases it's either blank or up arrow:
EDIT
For reference, what I've for deleting an entry and truncate the file is:
while(stream.Position < stream.Length)
{
stream.Read(idArray, 0, 4);
id = BitConverter.ToInt32(idArray, 0);
if (id == 10)
{
var rewritePosition = stream.Position - 4;
stream.Position += 60;
var remainder = new byte[stream.Length - stream.Position];
stream.Read(remainder, 0, remainder.Length);
stream.SetLength(stream.Length - 64);
stream.Position = rewritePosition;
stream.Write(remainder);
break;
}
}
stream.Close();