LINQ-a-fi your file system and create a neat little Grep tool

After watching this Channel9 video http://channel9.msdn.com/shows/Going+Deep/Erik-Meijer-and-Bart-De-Smet-LINQ-to-Anything/

I was inspired to try out writing my own domain specific language (DSL) for the file system.  I started with writing my own Where and Select in a class, but soon discovered I did not need that.  All a really needed was a method to return IEnumerable and an abstraction to make using FileSystemInfo a bit easier to use with linq.  So I created LFileInfo (Linq FileInfo) for lack of a better name, and a StreamIndexer as a simple wrapper around a StreamReader to give me an Indexer (i.e. char c = file[12]) over a file.  The indexer was not really required and has nothing to do with linq-ing my LFileInfo class, but it make searching the file easier in Like() algo.  In effect, what we have here is another way to Grep (e.g. search) using Linq.  So we created our own DSL without writing any parser code or coming up with some new syntax.  We leverage the power of linq to build something fairly useful.

Sample usage of LFileInfo below. Other Test methods given in the LFileInfo class:

Console.WriteLine("\nGet number of files and total size under a dir.");
long totSize = 0;
long totFiles = 0;
var q = (from f in new LFileInfo(@"c:\temp").Children(true)
         let x = totSize += f.Length
         let y = totFiles++
         select f);

var list = q.ToList(); // Run the query.

Console.WriteLine("Total Size:{0:N} Total Files: {1}", totSize, totFiles);

 

// LFileInfo. Wraps a FileSystemInfo object to allow us to more simply "linq-a-fi" directory operations.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Diagnostics;

namespace WJS.Utils
{
    public class LFileInfo
    {
        private FileSystemInfo fi;
        private int level;
        private LFileInfo parent;
        private List<LFileInfo> children;

        public LFileInfo(string path)
        {
            if ((File.GetAttributes(path) & FileAttributes.Directory) == FileAttributes.Directory)
                fi = new DirectoryInfo(path);
            else
                fi = new FileInfo(path);
        }

        private LFileInfo(FileSystemInfo item)
        {
            fi = item;
        }
        public LFileInfo Parent
        {
            get { return this.parent; }
        }
        public FileSystemInfo FileSystemInfo
        {
            get { return this.fi; }
        }

        IEnumerable<LFileInfo> Children()
        {
            foreach (var c in Children(false))
                yield return c;
        }

        IEnumerable<LFileInfo> Children(bool recurse)
        {
            if (!this.IsDirectory)
                yield break;

            if (this.children != null)
            {
                // enum from from cache.
                foreach (var f in this.children)
                {
                    yield return f;
                    if (recurse && f.IsDirectory)
                    {
                        foreach (var l in f.Children(true))
                            yield return l;
                    }
                }
                yield break;
            }
            else
            {
                // Build cache from disk. Note, this is still lazy. We only
                // continue searching FAT, after yielding. GetFileSystemInfos()
                // is not lazy, so a directory read returns all fileinfos in that dir.
                this.children = new List<LFileInfo>();
                DirectoryInfo di = (DirectoryInfo)fi;
                //if (di.FullName.StartsWith(@"c:\temp\system", StringComparison.OrdinalIgnoreCase))
                //    Debugger.Break();
                var infos = di.GetFileSystemInfos();
                foreach (var f in infos)
                {
                    LFileInfo lfi = new LFileInfo(f);
                    lfi.level = this.level + 1;
                    lfi.parent = this;
                    this.children.Add(lfi);
                    yield return lfi;
                    if (recurse && f is DirectoryInfo)
                    {
                        DirectoryInfo di2 = (DirectoryInfo)f;
                        if (di2 != null)
                        {
                            LFileInfo nfi = new LFileInfo(di2);
                            nfi.level = this.level + 1;
                            nfi.parent = this;
                            var children = nfi.Children(recurse);
                            foreach (var f2 in children)
                                yield return f2;
                        }
                    }
                }
            }
        }

        public string Name
        {
            get { return fi.Name; }
        }

        public string Extension
        {
            get { return fi.Extension; }
        }

        public string FullName
        {
            get { return fi.FullName; }
        }

        public int Level
        {
            get { return this.level; }
        }

        public long Length
        {
            get
            {
                if (IsDirectory)
                    return 0;
                return ((FileInfo)fi).Length;
            }
        }

        public bool IsFile
        {
            get { return !IsDirectory; }
        }

        public bool IsDirectory
        {
            get
            {
                return (fi is DirectoryInfo);
            }
        }

        private bool CanRead
        {
            get
            {
                try
                {
                    using (var f = File.OpenRead(fi.FullName))
                    {
                        return true;
                    }
                }
                catch
                {
                    return false;
                }
            }
        }

        public string ReadAllText()
        {
            if (IsFile)
                return File.ReadAllText(fi.FullName);
            else
                return null;
        }

        public string[] ReadAllLines()
        {
            if (IsFile)
                return File.ReadAllLines(fi.FullName);
            else
                return null;
        }

        public byte[] ReadAllBytes()
        {
            if (IsFile)
                return File.ReadAllBytes(fi.FullName);
            else
                return null;
        }

        public bool Like(string pattern, bool caseSensitive)
        {
            StreamIndexer si = new StreamIndexer(this.fi.FullName);
            int matchIndex = 0;
            bool result = Like(si, pattern, caseSensitive, ref matchIndex);
            return result;
        }

        /// <summary>
        /// Uses a stream wrapper that exposes an iterator to allow reading a file by index.
        /// </summary>
        private static bool Like(StreamIndexer input, string pattern, bool caseSensitive, ref int startIndex)
        {
            if (input == null) throw new ArgumentNullException("input");
            if (pattern == null)
                return false;

            // Setup case function.
            Func<char, char, bool> equal;
            if (caseSensitive)
                equal = (char c1, char c2) =>
                {
                    bool r = c1 == c2;
                    return r;
                };
            else
                equal = (char c1, char c2) =>
                {
                    bool r = char.ToLower(c1) == char.ToLower(c2);
                    return r;
                };

            // Do pattern matching.
            int i = 0;
            int j = 0;
            while (i < input.Length && j < pattern.Length && pattern[j] != ‘*’)
            {
                if ( (!equal(pattern[j], (char)input[i])) && (!equal(pattern[j], ‘?’)) )
                {
                    return false;
                }
                i++;
                j++;
            }

            // If we have reached the end of the pattern without finding a wildcard,
            // the match must fail if the string is longer or shorter than the pattern.
            if (j == pattern.Length)
                return input.Length == pattern.Length;

            int cp = 0;
            int mp = 0;
            while (i < input.Length)
            {
                if (j < pattern.Length && pattern[j] == ‘*’)
                {
                    if (++j >= pattern.Length) //Nothing more in pattern so we match.
                    {
                        startIndex = i-1;
                        return true;
                    }
                    mp = j;
                    cp = i + 1;
                }
                else if (j < pattern.Length && ( equal(pattern[j], (char)input[i]) || pattern[j] == ‘?’))
                {
                    j++;
                    i++;
                }
                else
                {
                    j = mp;
                    i = cp++;
                }
            }

            while (j < pattern.Length && pattern[j] == ‘*’)
            {
                j++;
            }

            startIndex = i;
            return j >= pattern.Length;
        }
        public static int IndexOfAny(string source, string ofAny)
        {
            if (source == null || ofAny == null) return 0;
            for(int i=0; i<source.Length; i++)
            {
                char c = source[i];
                foreach (char c2 in ofAny)
                {
                    if (c == c2) return i;
                }
            }
            return -1;
        }

        /// <summary>
        /// Return true if input string matches pattern.
        /// </summary>
        public static bool Like(string input, string pattern, bool caseSensitive)
        {
            if (pattern == null && input == null)
                return true;
            if (pattern == null || input == null)
                return false;

            // Convert both string and pattern to lower case for comparison.
            if (!caseSensitive)
            {
                pattern = pattern.ToLower();
                input = input.ToLower();
            }

            // If pattern doesn’t actually contain any wildcards, use simple equality.
            if (IndexOfAny(pattern, "*?") == -1)
                return input == pattern;

            // Otherwise do pattern matching.
            int i = 0;
            int j = 0;
            while (i < input.Length && j < pattern.Length && pattern[j] != ‘*’)
            {
                if ((pattern[j] != input[i]) && (pattern[j] != ‘?’))
                {
                    return false;
                }
                i++;
                j++;
            }

            // If we have reached the end of the pattern without finding a wildcard,
            // the match must fail if the string is longer or shorter than the pattern.
            if (j == pattern.Length)
                return input.Length == pattern.Length;

            int cp = 0;
            int mp = 0;
            while (i < input.Length)
            {
                if (j < pattern.Length && pattern[j] == ‘*’)
                {
                    if (++j >= pattern.Length)
                    {
                        return true;
                    }
                    mp = j;
                    cp = i + 1;
                }
                else if (j < pattern.Length && (pattern[j] == input[i] || pattern[j] == ‘?’))
                {
                    j++;
                    i++;
                }
                else
                {
                    j = mp;
                    i = cp++;
                }
            }

            while (j < pattern.Length && pattern[j] == ‘*’)
            {
                j++;
            }

            return j >= pattern.Length;
        }

        // Some sample tests. Remove Test methods from final code.
        public static void Test1()
        {
            // Get all directories under a root.
            Console.WriteLine("\nAll directories under a root.");
            var q = from f in new LFileInfo(@"c:\temp").Children()
                    where (f.IsDirectory)
                    select f;
            foreach(var f in q)
                Console.WriteLine(f.FullName);
        }

        public static void Test2()
        {
            // Get directories that don’t have any files. The power of linq really shows here.
            Console.WriteLine("\nAll directories with no files.");
            var q = (from f in new LFileInfo(@"c:\temp").Children(true)
                    where f.IsDirectory && !f.Children().Any(e=>e.IsFile)
                    select f);

            foreach(var f in q)
                Console.WriteLine("{0} {1} Level:{2}", f.IsDirectory, f.FullName, f.Level);
        }

        public static void Test3()
        {
            // Get number of files and total size under a dir.
            Console.WriteLine("\nGet number of files and total size under a dir.");
            string dir = @"c:\temp";
            long totSize = 0;
            long totFiles = 0;
            var q = (from f in new LFileInfo(dir).Children(true)
                     let x = totSize += f.Length
                     let y = totFiles++
                     orderby f.Name, f.IsFile, f.Level
                     select f);

            foreach (var f in q)
                Console.WriteLine("{0} {1} Level:{2}", f.IsDirectory, f.FullName, f.Level);

            Console.WriteLine("Total Size:{0:N} Total Files: {1}", totSize, totFiles);
        }
        public static void Test5()
        {
            Console.WriteLine("\nAll files over 1MB:");
            var q = from f in new LFileInfo(@"c:\temp").Children(true)
                    where f.Length > 1024 * 1024
                    select f;
            foreach(var f in q)
                Console.WriteLine("{0}\t\t\tLen: {1:N}", f.FullName, f.Length);
        }

        // Print a dir tree to the console.
        public static void Test6(string path)
        {
            //string currDir = System.AppDomain.CurrentDomain.BaseDirectory;
            //string pDir = new DirectoryInfo(currDir).Parent.Parent.FullName;

            LFileInfo dir = new LFileInfo(path);
            PrintTree(dir);
        }

        // Use Like pattern matching to search files.
        public static void Test7()
        {          
            var q = from f in new LFileInfo(@"c:\temp").Children(true)
                    where LFileInfo.Like(f.Name, "*.txt", false)
                    where f.Like("* where *", true)
                    select f;

            var list = q.ToList();
            Console.WriteLine("\nFile matching pattern: {0}", list.Count());
            foreach (var f in list)
                Console.WriteLine("{0} Ext:{1}", f.Name, f.Extension);
        }

        /// <summary>
        /// Print a dir tree starting from entry.
        /// </summary>
        private static void PrintTree(LFileInfo entry)
        {
            string pad = "";
            if (entry.Level > 0) pad = new string(‘.’, (entry.Level) * 2);
            if (entry.IsDirectory) pad += "+";
            Console.WriteLine(pad + entry.Name);

            if (entry.IsDirectory)
            {
                var children = entry.Children().OrderBy(e => e.IsDirectory);
                foreach (LFileInfo lf in children)
                    PrintTree(lf);
            }
        }
    }
}

 

// StreamIndexer class to wrap a StreamReader and expose an indexer.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

namespace WJS.Utils
{
    public class StreamIndexer
    {
        private StreamReader sr;
        public StreamIndexer(string path)
        {
            sr = new StreamReader(path);
        }

        public long Length
        {
            get { return sr.BaseStream.Length; }
        }

        public void Close()
        {
            sr.Close();
        }

        public IEnumerable<Char> Characters()
        {
            int ch = 0;
            while ((ch = sr.Read()) >= 0)
            {
                yield return (char)ch;
            }
        }

        public int this[int index]
        {
            get
            {
                sr.BaseStream.Seek(index, SeekOrigin.Begin);
                return sr.Read();
            }
        }
    }
}

Advertisements
This entry was posted in Uncategorized. Bookmark the permalink.

10 Responses to LINQ-a-fi your file system and create a neat little Grep tool

  1. Dorothy says:

    <a href="http://www.jacobs2004.net/search/%83G%83%8B%83%81%83X+%8CC">エルメス 靴</a> <a href="http://www.wiptonline.com/search/%83G%83%8B%83%81%83X+%83R%83C%83%93%83P%81%5B%83X">エルメス コインケース</a> <a href="http://www.jacobs2004.net/search/%83G%83%8B%83%81%83X+%83%7C%83%8A%81%5B%83h">エルメス ポリード</a> <a href="http://www.wiptonline.com/search/%83G%83%8B%83%81%83X+%83L%81%5B%83z%83%8B%83_%81%5B">エルメス キーホルダー</a> <a href="http://www.jacobs2004.net/search/%83G%83%8B%83%81%83X+%83J%83t%83F">エルメス カフェ</a> <a href="http://www.minamin.ne.jp/search/%83v%83%89%83_+%8Cg%91%D1%83X%83g%83%89%83b%83v">プラダ 携帯ストラップ</a> <a href="http://www.minamin.ne.jp/search/%83v%83%89%83_+%83g%81%5B%83g%83o%83b%83N">プラダ トートバック</a> <a href="http://www.wiptonline.com/search/%83G%83%8B%83%81%83X+%83O%83%8D%81%5B%83u%83z%83%8B%83_%81%5B">エルメス グローブホルダー</a> <a href="http://www.jacobs2004.net/search/%83G%83%8B%83%81%83X+%83G%81%5B%83%8B%83o%83b%83O">エルメス エールバッグ</a> <a href="http://www.jacobs2004.net/search/%83G%83%8B%83%81%83X+%83x%83A%83%93">エルメス ベアン</a> <a href="http://www.jacobs2004.net/search/%83G%83%8B%83%81%83X+%8D%CC%97p">エルメス 採用</a> <a href="http://www.jacobs2004.net/search/%83%81%83%5D%83%93%83G%83%8B%83%81%83X">メゾンエルメス</a> <a href="http://www.wiptonline.com/search/%83G%83%8B%83%81%83X+%83J%83t%83F">エルメス カフェ</a> <a href="http://www.minamin.ne.jp/search/%83v%83%89%83_+%8B%81%90l">プラダ 求人</a> <a href="http://www.wiptonline.com/search/%83G%83%8B%83%81%83X+%8E%9E%8Cv">エルメス 時計</a> <a href="http://www.wiptonline.com/search/%83%8D%83R%83V%81%5B%83%89+%83G%83%8B%83%81%83X">ロコシーラ エルメス</a> <a href="http://www.jacobs2004.net/search/%83n%83%8F%83C+%83G%83%8B%83%81%83X">ハワイ エルメス</a> <a href="http://www.jacobs2004.net/search/%83G%83%8B%83%81%83X+%8E%9E%8Cv">エルメス 時計</a> <a href="http://www.minamin.ne.jp/search/%83v%83%89%83_+%83r%83W%83l%83X%83o%83b%83O">プラダ ビジネスバッグ</a> <a href="http://www.minamin.ne.jp/search/%83v%83%89%83_+%90%C2%8ER">プラダ 青山</a> <a href="http://www.wiptonline.com/search/%83G%83%8B%83%81%83X+%83L%81%5B%83P%81%5B%83X">エルメス キーケース</a> <a href="http://www.jacobs2004.net/search/%83%89%83C%83J+%83G%83%8B%83%81%83X">ライカ エルメス</a> <a href="http://www.wiptonline.com/search/%83G%83%8B%83%81%83X+%83u%81%5B%83c">エルメス ブーツ</a> <a href="http://www.jacobs2004.net/search/%83G%83%8B%83%81%83X+%83L%81%5B%83z%83%8B%83_%81%5B">エルメス キーホルダー</a> <a href="http://www.minamin.ne.jp/search/%83v%83%89%83_+%95%5C%8EQ%93%B9">プラダ 表参道</a> <a href="http://www.jacobs2004.net/search/%83G%83%8B%83%81%83X+%83i%83C%83%8B%82%CC%92%EB">エルメス ナイルの庭</a> <a href="http://www.minamin.ne.jp/search/%83h%83R%83%82+%83v%83%89%83_">ドコモ プラダ</a> <a href="http://www.minamin.ne.jp/search/%83v%83%89%83_%82%F0%92%85%82%BD%88%AB%96%82">プラダを着た悪魔</a> <a href="http://www.jacobs2004.net/search/%83G%83%8B%83%81%83X+%83s%83R%83%5E%83%93">エルメス ピコタン</a> <a href="http://www.jacobs2004.net/search/%83G%83%8B%83%81%83X+%98r%8E%9E%8Cv">エルメス 腕時計</a> 

  2. Unknown says:

    http://www.batteryfast.com/dell/latitude-d830.htm dell latitude d830 battery http://www.batteryfast.com/dell/latitude-d531.htm dell latitude d531 battery http://www.batteryfast.com/dell/precision-m65.htm dell precision m65 battery http://www.batteryfast.com/dell/312-039.htm dell 312-039 battery http://www.batteryfast.com/dell/inspiron-1520.htm dell inspiron 1520 battery http://www.batteryfast.com/dell/inspiron-1720.htm dell inspiron 1720 battery http://www.batteryfast.com/dell/vostro-1500.htm dell vostro 1500 battery http://www.batteryfast.com/dell/vostro-1700.htm dell vostro 1700 battery http://www.batteryfast.com/gateway/8msb.htm gateway 8msb battery http://www.batteryfast.com/gateway/8msbg.htm gateway 8msbg battery http://www.batteryfast.com/gateway/m680.htm gateway m680 battery http://www.batteryfast.com/gateway/m360.htm gateway m360 battery http://www.batteryfast.com/gateway/m460.htm gateway m460 battery http://www.batteryfast.com/hp/hstnn-db11.htm hp hstnn-db11 battery http://www.batteryfast.com/hp/nc8230.htm hp nc8230 battery http://www.batteryfast.com/hp/nc8200.htm hp nc8200 battery http://www.batteryfast.com/hp/nw8200.htm hp nw8200 battery http://www.batteryfast.com/hp/nx8200.htm hp nx8200 battery http://www.batteryfast.com/hp/nc8430.htm hp nc8430 battery http://www.batteryfast.com/hp/pb992a.htm hp pb992a battery http://www.batteryfast.com/hp/dv2000.htm hp dv2000 battery http://www.batteryfast.com/hp/dv2100.htm hp dv2100 battery http://www.batteryfast.com/hp/dv2200.htm hp dv2200 battery http://www.batteryfast.com/hp/dv6000.htm hp dv6000 battery http://www.batteryfast.com/hp/v3000.htm hp v3000 battery http://www.batteryfast.com/hp/v6000.htm hp v6000 battery http://www.batteryfast.com/hp/hstnn-db42.htm hp hstnn-db42 battery http://www.batteryfast.com/hp/dv9000.htm hp dv9000 battery http://www.batteryfast.com/hp/dv9200.htm hp dv9200 battery http://www.batteryfast.com/hp/dv9100.htm hp dv9100 battery http://www.batteryfast.com/hp/dv9500.htm hp dv9500 battery http://www.batteryfast.com/hp/dv9600.htm hp dv9600 battery http://www.batteryfast.com/hp/dv9700.htm hp dv9700 battery http://www.batteryfast.com/hp/hstnn-lb33.htm hp hstnn-lb33 battery http://www.batteryfast.com/hp/hstnn-ib44.htm hp hstnn-ib44 battery http://www.batteryfast.com/hp/510.htm hp 510 battery http://www.batteryfast.com/hp/530.htm hp 530 battery http://www.batteryfast.com/hp/hstnn-fb44.htm hp hstnn-fb44 battery http://www.batteryfast.com/hp/hstnn-c29c.htm hp hstnn-c29c battery http://www.batteryfast.com/hp/nc6000.htm hp nc6000 battery http://www.batteryfast.com/hp/nx5000.htm hp nx5000 battery http://www.batteryfast.com/hp/nw8000.htm hp nw8000 battery http://www.batteryfast.com/hp/nc8000.htm hp nc8000 battery http://www.batteryfast.com/hp/v1000.htm hp v1000 battery

  3. Unknown says:

    http://www.batteryfast.co.uk/gateway/4s2p.htm gateway 4s2p battery http://www.batteryfast.co.uk/dell/xps-1330.htm dell xps 1330 battery http://www.batteryfast.co.uk/dell/xps-m1330.htm dell xps m1330 battery http://www.batteryfast.co.uk/dell/d820.htm dell d820 battery http://www.batteryfast.co.uk/dell/inspiron-6000.htm dell inspiron 6000 battery http://www.batteryfast.co.uk/dell/inspiron-9200.htm dell inspiron 9200 battery http://www.batteryfast.co.uk/dell/inspiron-9300.htm dell inspiron 9300 battery http://www.batteryfast.co.uk/dell/inspiron-9400.htm dell inspiron 9400 battery http://www.batteryfast.co.uk/dell/e1705.htm dell e1705 battery http://www.batteryfast.co.uk/dell/d5318.htm dell d5318 battery http://www.batteryfast.co.uk/hp/nc8200.htm hp nc8200 battery http://www.batteryfast.co.uk/hp/nc8200.htm hp nc8200 battery http://www.batteryfast.co.uk/hp/nc8230.htm hp nc8230 battery http://www.batteryfast.co.uk/hp/7400.htm hp 7400 battery http://www.batteryfast.co.uk/hp/nc8200.htm hp nc8200 battery http://www.batteryfast.co.uk/hp/nc8230.htm hp nc8230 battery http://www.batteryfast.co.uk/hp/7400.htm hp 7400 battery http://www.batteryfast.co.uk/hp/dv9000.htm hp dv9000 battery http://www.batteryfast.co.uk/hp/dv9200.htm hp dv9200 battery http://www.batteryfast.co.uk/hp/dv9100.htm hp dv9100 battery http://www.batteryfast.co.uk/hp/dv9500.htm hp dv9500 battery http://www.batteryfast.co.uk/hp/dv9600.htm hp dv9600 battery http://www.batteryfast.co.uk/hp/dv9000.htm hp dv9000 battery http://www.batteryfast.co.uk/hp/dv9600.htm hp dv9600 battery http://www.batteryfast.co.uk/hp/dv2000.htm hp dv2000 battery http://www.batteryfast.co.uk/hp/dv2100.htm hp dv2100 battery http://www.batteryfast.co.uk/hp/dv2200.htm hp dv2200 battery http://www.batteryfast.co.uk/hp/dv6000.htm hp dv6000 battery http://www.batteryfast.co.uk/hp/v3000.htm hp v3000 battery http://www.batteryfast.co.uk/hp/v6000.htm hp v6000 battery http://www.batteryfast.co.uk/hp/dv2000.htm hp dv2000 battery http://www.batteryfast.co.uk/hp/dv2100.htm hp dv2100 battery http://www.batteryfast.co.uk/hp/dv2200.htm hp dv2200 battery http://www.batteryfast.co.uk/hp/dv6000.htm hp dv6000 battery http://www.batteryfast.co.uk/hp/v3000.htm hp v3000 battery http://www.batteryfast.co.uk/hp/v6000.htm hp v6000 battery http://www.batteryfast.co.uk/dell/inspiron-1300.htm dell inspiron 1300 battery http://www.batteryfast.co.uk/dell/inspiron-b120.htm dell inspiron b120 battery http://www.batteryfast.co.uk/dell/inspiron-b130.htm dell inspiron b130 battery http://www.batteryfast.co.uk/dell/inspiron-1300.htm dell inspiron 1300 battery http://www.batteryfast.co.uk/dell/inspiron-b120.htm dell inspiron b120 battery http://www.batteryfast.co.uk/dell/inspiron-b130.htm dell inspiron b130 battery http://www.batteryfast.co.uk/dell/inspiron-1720.htm dell inspiron 1720 battery http://www.batteryfast.co.uk/dell/inspiron-1525.htm dell inspiron 1525 battery http://www.batteryfast.co.uk/dell/1501.htm dell 1501 battery http://www.batteryfast.co.uk/dell/e1505.htm dell e1505 battery

  4. Unknown says:

    探偵 調査

    素行調査

    身辺調査

    妻浮気

    悩み相談

    探偵紹介

    探偵事務所

    行動調査

    追跡調査

    結婚式

    パティオ

    アダルトショップ

    オナホール

    TENGA

    バイブ

    コスプレ

    大人のおもちゃ

    アダルトグッズ

    アダルトグッズ

    大人のおもちゃ

    おとなのおもちゃ

    エアコン取付

    ガーデンファニチャー

    システムキッチン

    洗面化粧台

    洗面台

    エッセンシャルオイル

    医学翻訳

    大人のおもちゃ

    アダルトショップ 

    エネマグラ

    オナホール 

    仮性包茎

    アナル

    電マ

  5. Unknown says:

    ダッチワイフ

    まつげエクステ

    アダルト グッズ

    英会話 学習

    競馬予想

    フラワーアレンジ

    ブリザーブドフラワー

    バラ

    供花

    誕生花

    誕生日プレゼント 花

    北欧家具

    アロマオイル

    ブライダルエステ 東京

    大人のおもちゃ通販

    結婚式

    結婚式準備

    結婚式の髪型

    ウェディングドレス

    av 通販

    アダルト ダウンロード

    熟女 アダルト

    巨乳 アダルト

    素人 アダルト

    ニューハーフ アダルト

    FX ランキング

    FX 比較

    キャッシング 申込

    債務整理

    興信所 料金

    行方調査

    素行調査

    不倫調査

    フィリピン 行方調査

    お見合いパーティー

    お見合いパーティー

    音楽・ライブ・レストラン

  6. William says:

    I have also fixed a bug in the cache logic, where it was not iterating children fully. So the first time the query would run, but the second time on same LFileInfo instance would not show same results.

  7. William says:

    @stilgar. Thanks for the catch. A copy/paste/edit bug. Sample should exec now.

  8. Stilgar says:

    I haven\’t compiled the code but my guess is that the first example will print just zeros because the query is never executed.

  9. William says:

    @stilgar, yes, just using let here to count during the query.

  10. Stilgar says:

    Are you only using let in
     
    var q = (from f in new LFileInfo(@"c:\\temp").Children(true)         let x = totSize += f.Length         let y = totFiles++         select f);
     
    to be able to do totSize += f.Length in the middle of the query?
     

Comments are closed.