PureBasic - форум

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » PureBasic - форум » Вопросы по PureBasic » Обработка текстового файла


Обработка текстового файла

Сообщений 1 страница 7 из 7

1

Добрый день!
Требуется совет.
читаю текстовый файл построчно, строки обрабатываю и добавляю к переменной, затем записываю в файл.
что-то очень долго обрабатывается...
вопрос: как можно быстрее организовать сей процесс? Может загрузить файл в память и потом обрабатывать? (вносить изменения в памяти, а не увеличивать постоянно переменную)

0

2

1. Размер файла, размер доступной оперативной памяти, количество строк?
2. Что такое долго "в граммах"? 8-)
3. "...строки обрабатываю и добавляю к переменной,..." "...вносить изменения в памяти, а не увеличивать постоянно переменную..." абсолютно не понятно о чём речь!!!
    И при этом какова доля этого не понятного по отношению к вводу выводу по затраченному времени?

Отредактировано useful (22.08.2024 05:31:15)

0

3

Код:
    If ReadFile(0, xml$)
      ff$=""
      While Eof(0) = 0
        i+1
        t$ = GetGadgetText(1)+Chr(10)+i
        SetGadgetText(1, t$)
        t$ = ReadString(0)
        If FindString(t$,"<RNUMMOP>")
          t1$=t$+#CRLF$: t$=""
        Else
          If FindString(t$,"<OIDFRMOP>")
            tr$ = "<OIDFRMOP>1.2.643.5.1.13.13.12.2.36.3380.0.237713</OIDFRMOP>"
            tt$ = "<OIDFRMOP>1.2.643.5.1.13.13.12.2.36.3380.0.237694.729002</OIDFRMOP>"
            If FindString(t$,tt$)
              t$ = ReplaceString(t$,tt$,tr$)
              If FindString(t1$,"00383300013005001")
                t1$ = ReplaceString(t1$,"00383300013005001","00383300113006001")
              EndIf
            EndIf
            tt$ = "<OIDFRMOP>1.2.643.5.1.13.13.12.2.36.3380.0.237713.734872</OIDFRMOP>"
            If FindString(t$,tt$)
              t$ = ReplaceString(t$,tt$,tr$)
              If FindString(t1$,"00383300013005001")
                t1$ = ReplaceString(t1$,"00383300013005001","00383300113006001")
              EndIf
            EndIf
            tt$ = "<OIDFRMOP>1.2.643.5.1.13.13.12.2.36.3380.0.237713.735368</OIDFRMOP>"
            If FindString(t$,tt$)
              t$ = ReplaceString(t$,tt$,tr$)
              If FindString(t1$,"00383300013005001")
                t1$ = ReplaceString(t1$,"00383300013005001","00383300113006001")
              EndIf
            EndIf
          EndIf
          ff$+t1$+t$+#CRLF$
          t1$=""
        EndIf
      Wend
      ff$=Left(ff$, Len(ff$)-2)
      CloseFile(0)

файл ~6М, около 160000 строк, оперативки вполне достаточно 16 Гб

0

4

amer написал(а):

Требуется совет.

Если совет действительно требуется, то просьба отвечать на все вопросы.
На второй и третий ответов нет.
find - replace однозначно дорого, но без подробностей разбираться в вашем алгоритме точно лень.

И новый вопрос: в чём проблема скорости? Если это нужно делать иногда (однократно), то 5 секунд или 5 минут роли не играют.
Если, например, каждые 30 сек, то точно выбрасывать стандартные функции работы со строками, они однозначно "дорогие"

т.е. нужна более детально описанная задача.

Отредактировано useful (22.08.2024 09:12:33)

0

5

Не лучше воспользоваться библиотекой xml? https://www.purebasic.com/documentation/xml/index.html

Для чего постоянное чтение / запись в гаджет для каждой строки файла?

Код:
t$ = GetGadgetText(1)+Chr(10)+i
SetGadgetText(1, t$)

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

Код:
ff$+t1$+t$+#CRLF$

0

6

1. Самый быстрый способ ReadData(), но если строк оооочень много, иначе ускорение не будет заметно. Всё же чтение построчно проверяет символы переноса строк чтобы прочитать строку.
2.

Код:
If FindString(t$,tt$)
	t$ = ReplaceString(t$,tt$,tr$)

В этом коде не экономично используется позиция, точнее отсутствие её использования. FindString возвращает позицию найденного, а ReplaceString может начать замену от позиции, пругнув по указателю сразу к месту замены. К тому же можно указать флаг "Заменить один раз", если в строке только одно вхождение, тогда движок также ускорится не будучи продолжать поиск последующих вхождений. То есть:

Код:
pos = FindString(t$,tt$)
If pos
	t$ = ReplaceString(t$,tt$,tr$,#PB_String_CaseSensitive,pos)

3. Если файл ооочень большой, то вместо ff$+t1$+t$+#CRLF$ можно использовать иной способ построения: надо создать список NewList и для каждого добавляемого куска создавать элемент - AddElement(List()). В конце нужно объединить элементы используя CopyMemoryString()

Код:
Define Result.string ; используем структуру для строки, вместо переменной
; Здесь подсчитываем длину данных
Len = 0
ForEach ff$()
	Len + Len(ff$()) + 2 ; +2 это для символов #CRLF$, но можно просто сделать ListSize() и добавить ListSize() * 2
Next

*Result\s = Space(Len) ; создаём буфер для результирующей строки, куда будут помещены все элементы списка ff$()
*Point = @*Result\s ; получаем указатель на структуру
ForEach ff$()
	CopyMemoryString(ff$() + #CRLF$, @*Point) ; копируем память, то есть каждый элемент списка используя указатель указателя
Next

0

7

Спасибо всем! Учту Ваши комментарии )

0


Вы здесь » PureBasic - форум » Вопросы по PureBasic » Обработка текстового файла