цикл посредством всех загруженных блоков, цикл через все их типы и проверка, если они реализуют интерфейс.
что-то как:
Type ti = typeof(IYourInterface);
foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies()) {
foreach (Type t in asm.GetTypes()) {
if (ti.IsAssignableFrom(t)) {
// here's your type in t
}
}
}
В Windows расширения файлов обычно достаточно хороши:
# all C# and related files (projects, source control metadata, etc)
dir -r -fil *.cs* | ss foo
# exclude the binary types most likely to pollute your development workspace
dir -r -exclude *exe, *dll, *pdb | ss foo
# stick the first three lines in your $profile (refining them over time)
$bins = new-list string
$bins.AddRange( [string[]]@("exe", "dll", "pdb", "png", "mdf", "docx") )
function IsBin([System.IO.FileInfo]$item) { !$bins.Contains($item.extension.ToLower()) }
dir -r | ? { !IsBin($_) } | ss foo
Но, конечно, расширения файлов не идеальны. Никто не любит печатать длинные списки, и многие файлы в любом случае имеют неправильные имена.
Я не думаю, что Unix имеет какие-либо специальные двоичные или текстовые индикаторы в файловой системе. (Что ж, VMS сделала, но я сомневаюсь, что это источник ваших привычек grep.) Я посмотрел на реализацию Grep -I, и, очевидно, это просто эвристика быстрого и грязного, основанная на первом фрагменте файла. Оказывается, это стратегия, с которой у меня небольшой опыт . Итак, вот мой совет по выбору эвристической функции, подходящей для текстовых файлов Windows:
В качестве примера, вот быстрый детектор ASCII:
function IsAscii([System.IO.FileInfo]$item)
{
begin
{
$validList = new-list byte
$validList.AddRange([byte[]] (10,13) )
$validList.AddRange([byte[]] (31..127) )
}
process
{
try
{
$reader = $item.Open([System.IO.FileMode]::Open)
$bytes = new-object byte[] 1024
$numRead = $reader.Read($bytes, 0, $bytes.Count)
for($i=0; $i -lt $numRead; ++$i)
{
if (!$validList.Contains($bytes[$i]))
{ return $false }
}
$true
}
finally
{
if ($reader)
{ $reader.Dispose() }
}
}
}
Шаблон использования, на который я нацелен, - это где Предложение -object вставлено в конвейер между " Между тем, \ 00 довольно часто встречается в структурированных двоичных файлах (а именно, когда поле фиксированной длины в байтах нуждается в заполнении), так что это отличный простой черный список. VSS 6.0 использовал только эту проверку и сработал нормально.
Кроме того: файлы * .zip - это тот случай, когда проверка на \ 0 более рискованна. В отличие от большинства двоичных файлов, их структурированный блок «заголовок» (нижний колонтитул?) Находится в конце, а не в начале. Предполагая идеальное сжатие энтропии, вероятность отсутствия \ 0 в первых 1 КБ составляет (1-1 / 256) ^ 1024 или около 2%. К счастью, простое сканирование остальной части NTFS-чтения кластера 4 КБ снизит риск до 0,00001% без изменения алгоритма или записи другого особого случая.
Чтобы исключить недопустимый UTF-8, добавьте \ C0-C1 и \ F8 -FD и \ FE-FF (после того, как вы искали возможную спецификацию) в черный список. Очень неполно, поскольку вы фактически не проверяете последовательности, но достаточно близко для ваших целей. Если вы хотите получить что-то более интересное, то пора вызвать одну из библиотек платформы, например IMultiLang2 :: DetectInputCodepage.
Не знаю, почему \ C8 (200 десятичных) находится в списке Grep. Это не слишком длинная кодировка. Например, последовательность \ C8 \ 80 представляет Ȁ (U + 0200). Может быть, что-то специфическое для Unix.
Хорошо, после еще нескольких часов исследований я считаю, что нашел свое решение. Я не буду отмечать это как ответ.
Pro Windows Powershell имел очень похожий пример. Я совершенно забыл, что у меня есть этот отличный справочник. Пожалуйста, купите его, если вас интересует Powershell. В нем подробно описаны спецификации Get-Content и Unicode.
Этот ответ на аналогичные вопросы также был очень полезен при идентификации Unicode.
Вот сценарий. Сообщите мне, если вы знаете о каких-либо проблемах.
# The file to be tested
param ($currFile)
# encoding variable
$encoding = ""
# Get the first 1024 bytes from the file
$byteArray = Get-Content -Path $currFile -Encoding Byte -TotalCount 1024
if( ("{0:X}{1:X}{2:X}" -f $byteArray) -eq "EFBBBF" )
{
# Test for UTF-8 BOM
$encoding = "UTF-8"
}
elseif( ("{0:X}{1:X}" -f $byteArray) -eq "FFFE" )
{
# Test for the UTF-16
$encoding = "UTF-16"
}
elseif( ("{0:X}{1:X}" -f $byteArray) -eq "FEFF" )
{
# Test for the UTF-16 Big Endian
$encoding = "UTF-16 BE"
}
elseif( ("{0:X}{1:X}{2:X}{3:X}" -f $byteArray) -eq "FFFE0000" )
{
# Test for the UTF-32
$encoding = "UTF-32"
}
elseif( ("{0:X}{1:X}{2:X}{3:X}" -f $byteArray) -eq "0000FEFF" )
{
# Test for the UTF-32 Big Endian
$encoding = "UTF-32 BE"
}
if($encoding)
{
# File is text encoded
return $false
}
# So now we're done with Text encodings that commonly have '0's
# in their byte steams. ASCII may have the NUL or '0' code in
# their streams but that's rare apparently.
# Both GNU Grep and Diff use variations of this heuristic
if( $byteArray -contains 0 )
{
# Test for binary
return $true
}
# This should be ASCII encoded
$encoding = "ASCII"
return $false
Сохраните этот сценарий как isBinary.ps1
Этот сценарий исправил все текстовые или двоичные файлы, которые я пробовал.