Грузим текстовый файл

March 6th, 2008 Begemot Posted in Программирование

Задача: есть wxTextCtrl, пользователь должен уметь загружать в него свои текстовые файлы для просмотра и редактирования, своего рода notepad. Файлы у пользователя могут быть в ANSI, utf-8 и в одном из двух юникодов.

Есть wxTextCtrl::LoadFile() – думаю зашибись, повезло. Тестирую, юникод\утф-8 грузит, ANSI грузит только если там одни английские символы, если есть русские обламывается. Нахожу? что проблема в дебрях библиотеки, в попытке грузить файл как wxFFile::ReadAll(wxString * str, wxMBConv& conv = wxConvUTF8)

Спрашиваю в wx-dev@, вот ответ

TN> Is this a bug? If no, is there a any way to load ANSI files in unicode
TN> build?

Yes, use wxCSConv(wxFONTENCODING_CP1251) instead of default wxConvAuto
which only handles UTF-x encodings in 2.8 (in the trunk it falls back to
the system default encoding if the input doesn’t seem to be in UTF-8, but
not in 2.8).

Баг это или нет, я так и не понял. Но понял что wxTextCtrl::LoadFile() использовать нельзя, так как кодировку там задать нет возможности. Пришлось использовать напрямую wxFFile, с шаманством. Вот функция для загрузки файла

bool BegUtils::ReadFileToString(const wxString & FileName, wxString & Data)

{

wxFFile file(FileName);

if (!file.IsOpened() ) return false;

// пытаемся читать файл подразумевая что он юникодный

if (!file.ReadAll(&Data)) return false;

if (Data.IsEmpty() && file.Length()>0)

{ // Если строка пустая и длина у файла есть – то он наверняка был анси, читаем как анси

file.Seek(0);

if (!file.ReadAll(&Data, *wxConvCurrent)) return false;

}

return true;

}

Вроде как работает, правда будут проблемы при загрузки пустых юникодных файлов – на экране будет мусор (BOM), можно конечно проверять загруженную строку на равенство одному из них, но я забил.

Подозреваю что это довольно кривой метод, поэтому если кто знает как решить задачу “правильно”, с удовольствием послушаю.

Related:

6 Responses to “Грузим текстовый файл”

  1. Николай, что-то у меня в Опере в этой записи некоторое строки отображаются некорректно, в частности строка “Баг это или нет, я так и не понял. Но понял что wxTextCtrl::Load” здесь и заканчивается. В Firefox отображается корректно.

    Может быть, там тэг где-нибудь незакрытый?

  2. Да, похоже что WLW не идеал:( вроде подправил. Так нормально?

  3. alley_oop Says:

    Ага, сейчас, вроде, все нормально.

    Спасибо.

  4. Pretorean Says:

    а что скажешь про такое извращение ? )))
    это если файл внутри виртуальной файловой системы …

    wxString MainFrame::OpenFileToString(wxString location)
    {
    wxFileSystem fs;
    wxFSFile *fsfile = fs.OpenFile(location);
    wxInputStream *stream = fsfile->GetStream();
    wxTextInputStream text ( *stream);
    wxString result;
    while (!stream->Eof())
    {
    result += wxString(text.ReadLine() + wxT(“\n”));
    }
    return result;
    }

  5. А чего говорить, вроде нормально все, извращением не пахнет:)
    Я правда с виртуальной фс не работал, да и с потокоми не очень.

  6. Спасибо! Иначе убил-бы много времини.