Win32: Записать в файл без буферизации?

Этот ответ будет делать ряд предположений, потому что вы были неточными в течение всего вашего вопроса.

Я собираюсь предположить, что и исходный и требуемый URL используют «http», а не «https». Вы идете вперед и назад между двумя в вашем вопросе.

Я собираюсь предположить, что атрибут href в тегах заключен в двойные кавычки как в оригинале, так и в результате. Ваш вопрос имеет двойные в оригинале и одиночные в результате.

Я собираюсь предположить, что, хотя ваш вопрос имеет «search? Q = new-doctor» в желаемом результате, вы на самом деле хотите «search? Q = news-doctor», когда на входе есть «news-doctor.html». «

Я собираюсь предположить, что часть даты исходного URL-адреса всегда представляет собой год из 4 цифр, за которым следует косая черта, за которой следует месяц из 2 цифр.

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

Функция, которую мы собираемся использовать, чтобы получить желаемый результат, является preg_replace () .

$urlTarget = "http://www.example.net";
$myDomain = "http://www.mydmoain.net";

$data = "Some parents believe that baby walkers can help their baby's growth and development, especially helping the children to walk faster. However, is it true that baby walkers can help child development? Or even dangerous? Let's take a look at the pros and cons of baby walkers below";

$resultUrl = preg_replace("@".$urlTarget."/\d{4}/\d{2}/(.*)\.(.*)\"\>@", $myDomain."/search?q=$1\">", $data);

echo $resultUrl;

Распределение регулярных выражений:

@: начальный разделитель. Не используя типичные /, чтобы нам не пришлось избегать косых черт в URL

$urlTarget: мы хотим сопоставлять только URL, начинающиеся с " http: //www.example .net "

/\d{4}: косая черта, за которой следуют ровно 4 цифры

/\d{2}: косая черта, за которой следуют ровно 2 цифры

/(.*): Косая черта, за которой следует любое количество любых символов (символы находятся в группе захвата, поэтому мы можем ссылаться на них при замене)

\.: точка (экранированная) (используется для разделения файла на имя и extension)

(.*): любое количество любых символов (в вашем примере расширение «html»)

\">: двойная кавычка (экранированная), за которой следует большая чем >, чтобы поймать конец тега

@: конечный разделитель

DEMO

12
задан Cristi Diaconescu 28 July 2014 в 12:24
поделиться

3 ответа

Я был укушен этим также в контексте входа катастрофического отказа.

FILE_FLAG_WRITE_THROUGH только гарантии, что данные Вы отправляете, отправляются в файловую систему прежде WriteFile возвраты; это не гарантирует, что на самом деле отправляется на физическое устройство. Так, например, если Вы выполняете a ReadFile после a WriteFile на дескрипторе с этим флагом Вам гарантируют это, чтение возвратит байты, которые Вы записали, получило ли это данные из кэша файловой системы или из базового устройства.

Если Вы хотите гарантировать, что данные были записаны в устройство, то Вам нужно FILE_FLAG_NO_BUFFERING, со всей сопутствующей дополнительной работой. Те записи должны быть выровненные, например, потому что буфер идет полностью вниз в драйвер устройства перед возвратом.

База знаний имеет краткую, но информативную статью о различии.

В Вашем случае, если родительский процесс собирается пережить ребенка, то Вы можете:

  1. Используйте CreatePipe API для создания наследуемого, неименованного канала.
  2. Использовать CreateFile создать файл с FILE_FLAG_NO_BUFFERING набор.
  3. Обеспечьте перезаписываемый дескриптор канала ребенку как его STDOUT.
  4. В родительском процессе читайте из читаемого дескриптора канала в выровненные буферы и запишите им в файл.
12
ответ дан 2 December 2019 в 07:22
поделиться

Возможно, вы могли бы удовлетвориться FlushFileBuffers :

Очищает буферы указанного файла и заставляет все буферизованные данные быть записано в файл.

Обычно функции WriteFile и WriteFileEx записывают данные во внутренний буфер, который операционная система регулярно записывает на диск или в канал связи. Функция FlushFileBuffers записывает всю буферизованную информацию для указанного файла на устройство или конвейер.

Они предупреждают, что вызов flush для большой очистки буферов неэффективен - и лучше просто отключить кеширование (например, ответ Тима ):

Из-за при кэшировании диска в системе функция FlushFileBuffers может быть неэффективной при использовании после каждой записи на дисковое устройство, когда многие записи выполняются отдельно.Если приложение выполняет несколько операций записи на диск и ему также необходимо обеспечить запись важных данных на постоянный носитель, приложение должно использовать небуферизованный ввод-вывод вместо частого вызова FlushFileBuffers . Чтобы открыть файл для небуферизованного ввода-вывода, вызовите функцию CreateFile с флагами FILE_FLAG_NO_BUFFERING и FILE_FLAG_WRITE_THROUGH . Это предотвращает кэширование содержимого файла и сбрасывает метаданные на диск при каждой записи. Для получения дополнительной информации см. CreateFile .

Если это не высокопроизводительная ситуация и вы не будете выполнять очистку слишком часто, то FlushFileBuffers может быть достаточно (и проще).

2
ответ дан 2 December 2019 в 07:22
поделиться

Размер, который вы видите в Проводнике, может не полностью соответствовать тому, что файловая система знает о файле, поэтому это не лучший способ его измерения. Так уж получилось, что FlushFileBuffers заставит файловую систему обновить информацию, которую просматривает Проводник; закрытие и повторное открытие может закончиться тем же самым.

Помимо проблем с кэшированием диска, упомянутых другими, сквозная запись делает именно то, на что вы надеялись. Просто выполнение «каталога» в каталоге может не отображать актуальную информацию.

Ответы, предполагающие, что сквозная запись записывает только «в файловую систему», не совсем верны. Он записывает их в кеш файловой системы, но также отправляет данные на диск. Сквозная запись может означать, что последующее чтение выполняется из кэша, но это не означает, что мы пропустили шаг и не записываем его на диск. Внимательно прочитайте аннотацию статьи. Это сбивает с толку почти всех.

2
ответ дан 2 December 2019 в 07:22
поделиться
Другие вопросы по тегам:

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