2015-07-22 2 views
13

Я читал поток, который испытывается с регулярным выражением:Синтаксический поток без отсечения

var deviceReadStream = fs.createReadStream("/path/to/stream"); 

deviceReadStream.on('data',function(data){ 
    if(data.match(aRegex)) 
    //do something 
}); 

Но поток разбивается на несколько chuncks, вполне возможно, что разрез делают меня пропустить матч , Итак, есть лучший образец для непрерывного тестирования потока с регулярным выражением?

более подробно

Поток является содержание в crashed filesystem. Я ищу подпись ext2 (0xef53). Поскольку я не знаю, как расщепляются куски, подпись может быть разделена и не обнаружена.

Итак, я использовал цикл, чтобы иметь возможность делимитировать себя, как разделяемые фрагменты, т. Е. Блоком файловой системы.

Но использование потоков кажется лучшим образцом, поэтому как я могу использовать потоки, определяя размер кусков?

+0

Каких данных вы уже поступаете; Какое регулярное выражение вы проверяете? – d0nut

+0

Если куски, которые вы получаете из потока, являются кратными тому, что, как ожидается, будут согласованы - вероятно, проблема не будет проблемой. Однако это кажется невероятно маловероятным, если у нас есть случайное регулярное выражение и случайные куски. Итак, что такое регулярное выражение и куски? – ndn

ответ

2

Во-первых, если вы решили использовать регулярное выражение с nodejs, попробуйте pcre. A node wrapper for pcre. Pcre может быть настроен на частичные совпадения, которые могут возобновляться через границы буфера.

Вы можете, однако, просто grep (или fgrep для нескольких статических строк) для смещения байта от терминала. Затем вы можете просмотреть его с помощью xxd и less, чтобы просмотреть его или dd, чтобы извлечь часть.

Например, чтобы получить смещение с Grep:

grep --text --byte-offset --only-matching --perl-regex "\xef\x53" recovery.img 

Обратите внимание, что опции командной строки Grep может варьироваться в зависимости от вашего дистрибутива.

Вы также можете посмотреть bgrep, хотя я не использовал его.

Мне посчастливилось сделать восстановление с использованием различных инструментов оболочки и скриптов.

Несколько других касательных комментариев:

  1. Имейте в виду порядок байт, что вы ищете.
  2. Сделайте снимок, так как вы делаете восстановление, если вы еще этого не сделали. Среди других опасностей, если устройство начинает терпеть неудачу, дальнейший доступ может ухудшить его.
  3. Справочные данные. ref
  4. Как вы упомянули, файлы могут быть фрагментированы. Тем не менее я бы ожидал, что разделы и файлы начнутся с границ сектора. Насколько я знаю, магия обычно не разделялась.
  5. Соблюдайте осторожность, чтобы не записывать непреднамеренно запись на устройство, которое вы восстанавливаете.
  6. Как вы знаете, если вы восстановите изображение, вы сможете смонтировать изображение с помощью шлейф-драйвера.
+0

Спасибо за ваш ответ, частичные совпадения, похоже, интересны, не могли бы вы привести пример использования? – Gael

+0

@Gael Похоже, что модуль узла pcre в настоящее время не отображает интерфейс DFA, который поддерживает возобновление. Открытый API может сказать вам, что конец строки вызвал частичное совпадение, но он не может возобновиться в следующем буфере. Это выглядит просто, чтобы расширить библиотеку, но тем временем вам нужен пример на другом языке? – user650881

6

Предполагая, что ваш код просто нужно искать 0xef53 подписи (как указано в «подробнее» части вашего вопроса ...

Один из способов сделать это и продолжать использовать регулярное выражение, это сохранить ссылку на предыдущий буфер данных, объединяет его с текущим буфером данных и запускает регулярное выражение. Это немного тяжело для использования процессора, поскольку он эффективно сканирует каждый буфер данных в два раза (и из-за конкатенации имеется большое количество памяти). легко читается, поэтому его следует поддерживать в будущем.

Посмотрите, пожалуйста, пример кода

var deviceReadStream = fs.createReadStream("/path/to/stream"); 
var prevData = ''; 

deviceReadStream.on('data',function(data){ 
    var buffer = prevData + data; 
    if(buffer.match(aRegex)) 
    //do something 

    prevData = data; 
}); 

Другим вариантом было бы более ручное сравнение символов, чтобы код мог поймать, когда подпись разбита на буферы данных. Вы можете увидеть решение этого вопроса в этом связанном вопросе Efficient way to search a stream for a string. Согласно сообщению в блоге верхнего ответа, код Haxe, который он написал, может быть создан для создания JavaScript, который вы затем можете использовать. Или вы можете написать свой собственный код для выполнения поиска, так как подпись, которую вы ищете, имеет длину всего 4 символа.

+0

Ваше решение подразумевает, что данные обрабатываются дважды. И если искомая последовательность длиннее двух кусков, проблема все еще здесь. Я думаю, что решение в вашей связанной записи с частичным поиском - это хороший способ следовать. Но больше не возможно использовать регулярные выражения, – Gael

+0

решение работает более двух кусков. Для каждого фрагмента используется предыдущий и текущий фрагмент. Таким образом, он всегда должен найти подпись, если только куски не содержат только 1 или 2 символа. Кажется маловероятным, что куски будут такими маленькими. –

+0

Он работает для моего примера, поскольку искомая последовательность, вероятно, будет меньше, чем куски, но с последовательностью с неопределенной длиной (например: /aaa.*bbb/, проблема не устранена. – Gael

0

Я бы посмотрел поток данных в виде движущегося окна размером 6 байт.

Например, если у вас есть следующий файл (в байтах): 23, 34, 45, 67, 76

Скользящее окно 2, проходящего через данные будут:

[23, 34] 
[34, 45] 
[45, 67] 
[67, 76] 

Я предлагаю идти над этими окнами, для вашей строки.

Обычно я не являюсь поклонником перебора байтов, когда вам действительно нужна строка underling. В UTF-8 есть случаи, когда это может вызвать некоторые проблемы, но при условии, что все на английском языке, все должно быть хорошо. Пример может быть улучшен, чтобы поддерживать эти случаи с помощью строки декодера

EDIT

Вот это utf8 версии

var Stream = require('stream'); 
var fs = require('fs'); 

var exampleStream = fs.createReadStream("./dump.dmp", {encoding: 'utf8'}); 
var matchCounter = 0; 

windowStream(exampleStream, 6).on('window', function(windowStr){ 
    if (windowStr === '0xEF53') { 
     ++matchCounter; 
    } 
}).on('end', function(){ 
    console.log('done scanning the file, found', matchCounter); 
}); 
function windowStream(inputStream, windowSize) { 
    var outStream = new Stream(); 
    var soFar = ""; 
    inputStream.on('data', function(data){ 
     Array.prototype.slice.call(data).forEach(function(char){ 
      soFar += char; 
      if (soFar.length === windowSize) { 
       outStream.emit('window', soFar); 
       soFar = soFar.slice(1); 
      } 
     }); 
    }); 
    inputStream.on('end', function(){ 
     outStream.emit('end'); 
    }); 
    return outStream; 
} 
Смежные вопросы