2013-06-07 3 views
1

Мне нужна программа, которая считывает содержимое файла и записывает его в другой файл, но только символы, которые являются допустимыми символами utf-8. Проблема в том, что файл может поступать в любую кодировку, и содержимое файла может или не может соответствовать такой кодировке.Как проверить, действителен ли символ в C++

Я знаю, что это беспорядок, но это данные, с которыми я работаю. Файлы, которые мне нужно «очистить», могут быть такими же большими, как пара терабайт, поэтому мне нужна программа, которая будет настолько эффективной, насколько это возможно по-человечески. В настоящее время я использую программу, которую пишу на питоне, но для очистки 100 гб требуется неделя.

Я думал о чтении символов с помощью функций w_char, а затем управлял их целыми числами и отбрасывал все числа, которые не находятся в некотором диапазоне. Является ли это оптимальным решением?

Также каков наиболее эффективный способ читать и писать на C/C++?

EDIT: Проблема не в операциях ввода-вывода, эта часть вопроса предназначена для дополнительной помощи, чтобы иметь еще более быструю программу, но реальной проблемой является то, как быстро идентифицировать символ UTF. Кроме того, я уже пробовал palatalization и RAM диски.

+2

Неделя ??? Кормите этих мышей и быстрее поворачивайте колеса! – Duck

+0

Вы говорите, что проблема не в IO, но требуется неделя? Действительно ли Cpu использует 100% ядра? Если да, то, возможно, покажите ключевую часть источника. Программа, использующая fread() и т. Д. В C/C++, сделала бы это быстро, поэтому каждый, естественно, принимал проблемы с IO. Или вы больше спрашиваете, как написать все это на C++? – rlb

+0

@ rlb Вопрос должен был заключаться в том, как эффективно отбрасывать недействительные символы utf8 (ЦП переходит на 100% почти всю неделю, чтобы завершить его). Производительность ввода-вывода - это просто сделать ее еще быстрее (у меня есть время, и это программное обеспечение будет использоваться много, поэтому небольшие улучшения производительности равны нескольким дням). Я профилировал свой код на Python, и проблема связана с функциями обработки строк и кодированием/декодированием. Вот почему я спрашиваю, будет ли управление ими целыми числами правильным подходом (я также очень признателен за другие предложения). – Topo

ответ

1

Utf8 - это просто хороший способ кодирования символов и имеет очень четко определенную структуру, поэтому в принципе разумно просто читать кусок памяти и проверять его, содержит utf8. В основном это состоит в проверке того, что некоторые битовые шаблоны НЕ появляются, такие как C0, C1, F5-FF. (в зависимости от местоположения)

Простой в C (извините, не говорите на python), чтобы закодировать что-то, что является простым fopen/fread, и проверить битовые шаблоны каждого байта, хотя я бы рекомендовал найти некоторый код для вырезания/paste (например, http://utfcpp.sourceforge.net/, но я havent использовал эти точные процедуры), так как есть некоторые предостережения и особые случаи для обработки. Просто обрабатывайте входные байты как unsigned char и битмаскируйте их напрямую. Я бы вставлял то, что использовал, но не в офис.

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

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

Ссылки

http://en.wikipedia.org/wiki/UTF-8 хороший четкий обзор с таблицей, показывающей допустимые битовые шаблоны.

http://tools.ietf.org/html/rfc3629 гк описания utf8

http://www.unicode.org/ домашнюю страницу для юникода consortitum.

0

Ваш лучший выбор в зависимости от меня является parallilize. Если вы можете распараллелить очистку и очистить много содержимого одновременно, процесс будет более эффективным. Я бы рассмотрел структуру для параллелизации, например. mapreduce, где вы можете многопоточно выполнять задачу.

+0

На данный момент я делю очень большой файл на более мелкие (100 гб) файлы и каждый раз очищаю каждый. Но после профилирования программы более медленные части - это функции управления строкой python, поэтому я думаю, что более эффективная программа и более эффективное решение в порядке. – Topo

0

Я бы посмотрел файлы с отображением памяти. Это что-то в мире Microsoft, не уверен, существует ли он в unix и т. Д., Но, скорее всего, будет.

В основном вы открываете файл и указываете на него ОС, и он загружает файл (или его кусок) в память, к которой вы можете получить доступ, используя массив указателей. Для файла объемом 100 ГБ вы можете загружать, возможно, 1 ГБ за раз, обрабатывать и затем записывать в выходной файл с отображением памяти.

http://msdn.microsoft.com/en-us/library/windows/desktop/aa366556(v=vs.85).aspx

http://msdn.microsoft.com/en-us/library/windows/desktop/aa366542(v=vs.85).aspx

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

HTH, удачи!

+0

Спасибо. Я попробовал. Я использую gb RAM-диск для оптимизации ввода-вывода, но проблема не в операциях ввода-вывода, а в части «очистки» кода. – Topo

+0

Вероятно, вы получите более высокую пропускную способность с языком более низкого уровня, например, C/C++. Предположительно, python имеет некоторые накладные расходы. Я не думаю, что здесь есть какое-то простое решение, кроме как писать логику перевода, а затем тестировать/настраивать/тестировать, пока вы не получите производительность, которой вы довольны –

0

Unix/Linux и любые другие ОС, совместимые с POSIX, поддерживают карту памяти (mmap) toow.

+0

Спасибо, но это тот же ответ, что и @ Chris Leckie. Я попробовал. Я использую gb RAM-диск для оптимизации ввода-вывода, но проблема не в операциях ввода-вывода, а в части «очистки» кода. Через несколько минут я могу загрузить 100gb-файл в другой файл. Проблема заключается в управлении строкой python. – Topo

Смежные вопросы