-1

I have a file which is in this format:

AA
AA AA AA
AA AA AA AA AA AA
AA AA AA
file.txt
0

Where AA represents a one or two digit number (the length of each doesn't have to be 2), and file.txt is the name of a file. I need a very fast method to obtain the file name. Also, I need to replace the final 0 with 1. If there is no 0 in the file at the end (its optional), I need to append 1 on a new line. Here is my current code:

StringBuilder sb = new StringBuilder("\r\n1");
string txt = File.ReadAllText(args[0]);
string[] lines = txt.Split('\n');
string name = lines[4];

if (lines.Length != 6) // Check if EOF is 0 or not.
    txt += sb.ToString();
else
    txt = txt.Substring(0, txt.Length - 1) + '1'; // Replace 0 with 1.

File.WriteAllText(args[0], txt);
Console.WriteLine(name);

However, I was wondering if there was even a faster way to do this (without having to load the file in memory maybe). I have to process tons of files like this, so saving tenths would be extremely useful.

TheBoyan
  • 6,802
  • 3
  • 45
  • 61
dnclem
  • 2,818
  • 15
  • 46
  • 64

3 Answers3

1

Loading the complete file into memory will most likely be your fastest choice if filesize is below min(MemoryPageSize, FSBlockSize), typically 4K

So assuming You have the contents of the file in a string, methinks using something like

int n;
if (content.EndsWith("\r\n0")
{
  n=content.Length-3;
  content=content.Substring(0,n+2)+"1";
}
else
{
  n=content.Length;
  content=content+"\r\n1";
}

and write the String out to the file. This will save you from the rather expensive Split()

for the filename we continue as follows:

int p=content.LastIndexOf('\n',n);
String filename=content.Substring(p+1,n-p);
Eugen Rieck
  • 64,175
  • 10
  • 70
  • 92
1
var lines = new List<string>(File.ReadAllLines(args[0]));
string name = lines[4];

if (lines.Length != 6) // Check if EOF is 0 or not.
    lines.Add("1");
else
    lines[5] = "1";

File.WriteAllLines(args[0], lines);
Console.WriteLine(name);
Ivo
  • 8,172
  • 5
  • 27
  • 42
1

If you're looking for speed, then you want to use FileStream.Read to a temporary buffer. Here is something I threw together that might help point you in a slightly different but faster direction:

StringBuilder filename = new StringBuilder();
using (FileStream stream = new FileStream(args[0], FileMode.Open, FileAccess.Read))
{
    byte[] buffer = new byte[1];
    while (stream.Read(buffer, 0, 1) > 0)
    {
        char c = (char) buffer[0];
        if (char.IsLetter(c) || char.IsPunctuation(c))
            filename.Append(c);
    }
}
Nick
  • 5,875
  • 1
  • 27
  • 38
  • I forgot to mention, the numbers AA are actually in hexadecimal so they can include A-F. If that happens, the filename won't always come correctly. – dnclem Dec 23 '11 at 15:46
  • If that's the case you would have to do some conversion of hext to string – MethodMan Dec 23 '11 at 19:57