Рекурсивный поиск файла в .NET

Это решает проблему:

val turnsType = object : TypeToken>() {}.type
val turns = Gson().fromJson>(pref.turns, turnsType)

Первая строка создает выражение object , которое спускается с TypeToken, а затем получает Java Type. Тогда методу Gson().fromJson нужен либо тип, указанный для результата функции (который должен соответствовать созданному TypeToken). Две версии этой работы, как указано выше, или:

val turns: List = Gson().fromJson(pref.turns, turnsType)

Чтобы упростить создание TypeToken, вы можете создать вспомогательную функцию, которая должна быть inline так что он может использовать параметры reified type :

inline fun  genericType() = object: TypeToken() {}.type

, который затем может быть использован одним из следующих способов:

val turnsType = genericType>()
// or
val turnsType: List = genericType()

И весь процесс может быть завернут в функцию расширения для экземпляра Gson:

inline fun  Gson.fromJson(json: String) = this.fromJson(json, object: TypeToken() {}.type)

Чтобы вы могли просто позвонить Gson и не беспокоиться о TypeToken вообще:

val turns = Gson().fromJson(pref.turns)
// or
val turns: Turns = Gson().fromJson(pref.turns)

Здесь Котлин использует вывод типа с одной стороны задания или другой, и генерирует обобщенные данные для встроенной функции для прохождения через полный тип (без стирания) и используя это для построения TypeToken, а также делает звоните в Gson

19
задан Saif Khan 13 January 2009 в 04:54
поделиться

3 ответа

Как насчет этого? Это избегает исключения, часто выдаваемого встроенным рекурсивным поиском (т.е. Вы получаете доступ запрещен к единственной папке, и Ваш целый поиск умирает), и лениво оценен (т.е. это возвращает результаты, как только это находит их, вместо того, чтобы буферизовать результаты 2000 года). Ленивое поведение позволяет Вам создать быстро реагирующий UIs и т.д. и также работает хорошо с LINQ (особенно First(), Take(), и т.д.).

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
static class Program { // formatted for vertical space
    static void Main() {
        foreach (string match in Search("c:\\", "*.xml")) {
            Console.WriteLine(match);
        }
    }
    static IEnumerable<string> Search(string root, string searchPattern) {
        Queue<string> dirs = new Queue<string>();
        dirs.Enqueue(root);
        while (dirs.Count > 0) {
            string dir = dirs.Dequeue();

            // files
            string[] paths = null;
            try {
                paths = Directory.GetFiles(dir, searchPattern);
            } catch { } // swallow

            if (paths != null && paths.Length > 0) {
                foreach (string file in paths) {
                    yield return file;
                }
            }

            // sub-directories
            paths = null;
            try {
                paths = Directory.GetDirectories(dir);
            } catch { } // swallow

            if (paths != null && paths.Length > 0) {
                foreach (string subDir in paths) {
                    dirs.Enqueue(subDir);
                }
            }
        }
    }
}
21
ответ дан 30 November 2019 в 01:54
поделиться
System.IO.Directory.GetFiles(@"c:\", "*.xml", SearchOption.AllDirectories);
54
ответ дан 30 November 2019 в 01:54
поделиться

Похоже, библиотека recls - обозначает rec ursive ls - теперь имеет чистый .NET реализация . Я только что прочитал об этом в статье доктора Добба .

Будет использоваться как:

using Recls;
using System;
static class Program { // formatted for vertical space
    static void Main() {
        foreach(IEntry e in FileSearcher.Search(@"c:\", "*.xml|*.csv|*.xls")) {
            Console.WriteLine(e.Path);
        }
    }
5
ответ дан 30 November 2019 в 01:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: