Поиск данных в функциональном стиле
От: Аноним  
Дата: 16.10.09 20:32
Оценка:
Здравствуйте.

Ситуация следующая: мне нужно в файлах искать вхождения некоторых данных. Раньше файлы были маленькие и данных были в одном экземпляре (т.е. требовалось найти вхождение одних и тех же данных), сейчас же условия изменились и нужно найти разные данные, плюс к этому файлы очень сильно выросли (около 1Гб).
Задачу я решил (код ниже), но т.к. время время позволяет, то я решил попробовать написать в функциональном стиле, но как не пишу, всё равно получается, то, что есть.
Помогите, пожалуйста, переписать этот код. Я пытался и на F# (недавно начал изучать) и на C#, никак не выходит.

Для C# написал только такой код, а что дальше с ним делать — не понятно

        IEnumerable<byte> GetBytes(string fileName)
        {
            int bytesReaden;
            byte[]buffer = new byte[4096];

            using (var file = File.OpenRead(fileName))
                while ((bytesReaden = file.Read(buffer, 0, buffer.Length))>0)
                {
                    for (int i = 0; i < bytesReaden; i++)
                    {
                        yield return buffer[i];
                    }
                }
        }



А вот существующий код:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;

namespace TestProgram
{
    internal class Entry
    {
        public string Item;
        public int Offset;
    }

    internal class Program
    {
        private static void Main(string[] args)
        {
            string fileName = new StackTrace(true).GetFrame(0).GetFileName();
            var entries = new[]
                {
                    "Microsoft.Build.Conversion.v3.5.xml",
                    "Microsoft.Build.Engine.xml",
                    "Microsoft.Build.Framework.xml",
                    "Microsoft.Build.Utilities.v3.5.xml",
                    "Microsoft.VisualC.STLCLR.xml",
                    "System.AddIn.Contract.xml",
                    "System.AddIn.xml",
                    "System.Core.xml",
                    "System.Data.DataSetExtensions.xml",
                    "System.Data.Linq.xml",
                    "System.DirectoryServices.AccountManagement.xml",
                    "System.Management.Instrumentation.xml",
                    "System.Net.xml",
                    "System.ServiceModel.Web.xml",
                    "System.Web.Extensions.Design.xml",
                    "System.Web.Extensions.xml",
                    "System.Windows.Presentation.xml",
                    "System.WorkflowServices.xml",
                    "System.Xml.Linq.xml",
                };

            var list = new List<Entry>();
            list.AddRange(FindEntries(fileName, entries));
            Console.WriteLine("list: {0}", list.Count);
        }

        private static IEnumerable<Entry> FindEntries(string fileName, string[] entries)
        {
            var list = new List<Entry>();

            using (FileStream file = File.OpenRead(fileName))
            {
                foreach (string entryString in entries)
                {
                    file.Seek(0, SeekOrigin.Begin);

                    var buffer = new byte[4096];
                    int bytesReaden;
                    int offset = 0;

                    byte[] entryBytes = Encoding.ASCII.GetBytes(entryString);
                    int curPos = 0;

                    while ((bytesReaden = file.Read(buffer, offset, buffer.Length - offset)) > 0)
                    {
                        bytesReaden += offset;
                        for (int i = 0; i < bytesReaden - entryBytes.Length; i++)
                        {
                            bool match = true;
                            for (int j = 0; j < entryBytes.Length; j++)
                            {
                                if (buffer[i + j] != entryBytes[j])
                                {
                                    match = false;
                                    break;
                                }
                            }

                            if (match)
                            {
                                var entry = new Entry
                                    {
                                        Item = entryString,
                                        Offset = curPos + i
                                    };
                                i += entryBytes.Length;
                                list.Add(entry);
                            }
                        }
                        offset = entryBytes.Length;
                        curPos += bytesReaden - offset;
                        for (int i = 0; i < entryBytes.Length; i++)
                        {
                            buffer[i] = buffer[bytesReaden - entryBytes.Length + i];
                        }
                    }
                }
            }

            return list;
        }
    }
}

//"Microsoft.Build.Conversion.v3.5.xml",
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.