0

I want to know wether my byte array ends on carriage return and if not I want to add it.

Thats what I have tried

byte[] fileContent = File.ReadAllBytes(openFileDialog.FileName);
byte[] endCharacter = fileContent.Skip(fileContent.Length - 2).Take(2).ToArray();

if (!(endCharacter.Equals(Encoding.ASCII.GetBytes(Environment.NewLine))))
{
    fileContent = fileContent.Concat(Encoding.ASCII.GetBytes(Environment.NewLine)).ToArray();
}

But I don't get it... Is this the right approach? If so, what's wrong with equals? Even if my byte array ends with {10,13}, the If statement never detects it.

Nelly
  • 522
  • 6
  • 15

2 Answers2

3

In this case, Equals checks for reference equality; while endCharacter and Encoding.ASCII.GetBytes(Environment.NewLine) may have the same contents, they are not the same array, so Equals returns false.

You're interested in value equality, so you should instead individually compare the values at each position in the arrays:

newLine = Encoding.ASCII.GetBytes(Environment.NewLine);
if (endCharacter[0] != newLine[0] && endCharacter[1] != newLine[1])
{
    // ...
}

In general, if you want to compare arrays for value equality, you could use something like this method, provided by Marc Gravell.

However, a much more efficient solution to your problem would be to convert the last two bytes of your file into ASCII and do a string comparison (since System.String already overloads == to check for value equality):

string endCharacter = Encoding.ASCII.GetString(fileContent, fileContent.Length - 2, 2);
if (endCharacter == Environment.NewLine)
{
    // ...
}

You may also need to be careful about reading the entire file into memory if it's likely to be large. If you don't need the full contents of the file, you could do this more efficiently by just reading in the final two bytes, inspecting them, and appending directly to the file as necessary. This can be achieved by opening a System.IO.FileStream for the file (through System.IO.File.Open).

Community
  • 1
  • 1
Will Vousden
  • 32,488
  • 9
  • 84
  • 95
  • 1
    Hey will, thanks for your answer. So I see I understood equals wrong. To make an extra function for array comparison for only one time use does not make sense to me. The other way (doing it by string) works fine. But if ound another way: if (!(endCharacter.SequenceEqual(Encoding.ASCII.GetBytes(Environment.NewLine)))){...} – Nelly Jan 31 '14 at 12:10
0

I found the solution, I must take SequenceEqual (http://www.dotnetperls.com/sequenceequal) in place of Equals. Thanks to everyone!

byte[] fileContent = File.ReadAllBytes(openFileDialog.FileName);
byte[] endCharacter = fileContent.Skip(fileContent.Length - 2).Take(2).ToArray();

if (!(endCharacter.SequenceEqual(Encoding.ASCII.GetBytes(Environment.NewLine))))
{
     fileContent = fileContent.Concat(Encoding.ASCII.GetBytes(Environment.NewLine)).ToArray();
     File.AppendAllText(openFileDialog.FileName, Environment.NewLine);
} 
Nelly
  • 522
  • 6
  • 15