Страница 2 из 3

Работа с текстовым файлов как с строкой

Добавлено: 16 Сентябрь 2018, 20:22
RaFaeL
У меня была задачка по работе с текстовым файлом, и там файлы как раз могли встречаться с разными вариантами конца строки, делал примерно так - грузим сначала файл в строку, делаем поиск <13,10>, если что-то нашли значит это "виндовый" формат, шлем в драйвер "EOF=2,13,10", переоткрываем, читаем по записям. Не нашли - шлем "1,10". Исходники утеряны, пример кода не смогу привести

Работа с текстовым файлов как с строкой

Добавлено: 16 Сентябрь 2018, 20:52
Игорь Столяров
RaFaeL писал(а): 16 Сентябрь 2018, 20:22Исходники утеряны, пример кода не смогу привести
Ну тут всё сводится к простому определению "типа" текстового файла для параметров драйвера.
Т.е. Choose(InString('<13,10>' ... А хотелось бы ASCII драйвер не юзать. Совсем.
vic7tar писал(а): 16 Сентябрь 2018, 20:10<-> наоборот.
Наверно да. Где-то в чертогах разума сидит ещё, что в DOS у клавиши ENTER был код 13. :)

Я вот подозревал, что всё непросто - потому и спросил ...
Если отбросить совсем футуристические варианты, то видимо действительно нужно искать перенос строки как <10>,
но но при этом убирать из строки возможный последний символ <13> и контролировать хвостик строки (конец файла). :)

Работа с текстовым файлов как с строкой

Добавлено: 17 Сентябрь 2018, 9:04
finsoftrz

Код: Выделить всё

LoadFile PROCEDURE (pName)

loc:szFile          CSTRING(FILE:MaxFileName)
loc:hFile           LONG
loc:dwSize          UNSIGNED
loc:lpFileSizeHigh  ULONG
loc:dwBytesRead     ULONG
loc:bRead           BOOL

loc:StrBuf          &CString

loc:ok  byte

   CODE

      loc:szFile=pName
      loc:hFile = CreateFile(loc:szFile,GENERIC_READ,0,0,OPEN_EXISTING,0,0)
      if loc:hFile <> INVALID_HANDLE_VALUE
         loc:dwSize = GetFileSize(loc:hFile,loc:lpFileSizeHigh)
         if loc:dwSize > 0
            loc:StrBuf &= new(CSTRING(loc:dwSize))
            loc:bRead = ReadFile(loc:hFile,ADDRESS(loc:StrBuf),SIZE(loc:StrBuf),loc:dwBytesRead,0)
            loc:ok=1
         end
         CloseHandle(loc:hFile)
      end


Работа с текстовым файлов как с строкой

Добавлено: 17 Сентябрь 2018, 9:05
finsoftrz
Прототипы.

Код: Выделить всё

     MODULE('WINAPI')      
    CreateFile(*CSTRING,ULONG,ULONG,LONG,ULONG,ULONG,UNSIGNED=0),UNSIGNED,RAW,PASCAL,NAME('CreateFileA')
       GetFileSize(UNSIGNED,*ULONG),ULONG,PASCAL,NAME('GetFileSize')
       ReadFile(UNSIGNED,LONG,ULONG,*ULONG,LONG),BOOL,PASCAL,RAW,NAME('ReadFile')
       WriteFile(UNSIGNED,<*?>,ULONG,*ULONG,<*?>),BOOL,PASCAL,RAW,PROC
       CloseHandle(UNSIGNED),BOOL,PASCAL,PROC,NAME('CloseHandle')
     END

Работа с текстовым файлов как с строкой

Добавлено: 17 Сентябрь 2018, 11:42
vic7tar
finsoftrz писал(а): 17 Сентябрь 2018, 9:04loc:StrBuf &= new(CSTRING(loc:dwSize))
loc:StrBuf &= new(CSTRING(loc:dwSize + 1))

Работа с текстовым файлов как с строкой

Добавлено: 13 Октябрь 2018, 17:25
Игорь Столяров
Спасибо всем, кто принял участие в обсуждении, теперь прекрасно можно
построчно обрабатывать и печатать текстовые файлы, без ASCII драйвера. :)

1. Считаем, что перенос строк это <13,10>;
2. Юзаем безопасный SUB, вместо индексированной строки;
3. Обрабатываемую строку не модифицируем

Код: Выделить всё

!   xStr_ - собственно сама строка для печати

Loc:SLen  Long   ! Длина строки (и флаг завершения печати)
Loc:Start Long   ! Позиция первого символа
Loc:CRLF  Long   ! Позиция символов переноса строки

   Code

   Loc:SLen  = Len(Clip(xStr_))   ! Длина строки
   Loc:Start = 1                  ! Начнём с начала

     Loop
       Loc:CRLF = InString('<13,10>', xStr_, 1, Loc:Start)  ! Найти позицию переноса

       If Loc:CRLF = 0             ! Если нет переноса -> печать хвостика и выход
          Loc:CRLF = Loc:SLen + 1  ! До конца файла
          Loc:SLen = -1            ! Установить флаг для завершения обработки
       end

       PRINT( Sub(xStr_, Loc:Start, Loc:CRLF - Loc:Start) )

       Loc:Start = Loc:CRLF + 2             ! Сдвиг позиции за перенос
       If Loc:Start > Loc:SLen then Break.  ! Если вылезли за размер строки
     end

Работа с текстовым файлов как с строкой

Добавлено: 17 Октябрь 2018, 8:49
morkovin
Файл в строку:
StringTheory от CapeSoft
Loadfile (String FileName, Long Offset=0, Long Length=0, Long RemoveBOM=false)
Description
Loads a file off the disk, and places it in the current string value. The maximum size of the file is limited only by the maximum size of a string in Clarion (which is a around two gigabytes.) The existing contents of the object are discarded before the file is loaded.

Работа с текстовым файлов как с строкой

Добавлено: 17 Октябрь 2018, 9:03
morkovin
Там же (в StringTheory) есть и парсинг CSV-файлов. Я активно это использую. Работает очень шустро. Выглядит примерно так:

Код: Выделить всё

        SETCURSOR(CURSOR:Wait)
        str.LoadFile('1.CSV')
        str.Split('<13,10>','"')
      loop x = 1 to str.Records()
        Lne.SetValue(Str.GetLine(x))
        Lne.Split(';','"','"',true)
        klk:F = LEFT(Lne.GetLine(1))   ! первое поле в строке
        klk:I = LEFT(Lne.GetLine(2))    ! второе поле
        klk:O = LEFT(Lne.GetLine(3))
        klk:DATEBIRTH=deformat(Lne.GetLine(4), @D06.)
        klk:POL=LOWER(Lne.GetLine(5))
        klk:POLIS=Lne.GetLine(6)
        klk:ADRESSPROP=Lne.GetLine(7)
        klk:ID_OsnObuch=1 !Lne.GetLine(8)
          .... и т. д.
         klk:KodPodrazd=Lne.GetLine(36)
         klk:MestoRojd=Lne.GetLine(37)
         klk:ADRESSDOM=Lne.GetLine(38)
            IF  Access:klk_abit.TryInsert()=Level:Benign THEN
            CLEAR(KLK:Record)
        END
      END
     SETCURSOR()      

Работа с текстовым файлов как с строкой

Добавлено: 17 Октябрь 2018, 9:28
Игорь Столяров
morkovin писал(а): 17 Октябрь 2018, 9:03Там же (в StringTheory) есть и парсинг CSV-файлов.
Это уже больше похоже на "ручную" обработку файла BASIC драйвером, а не ASCII.
Что кстати, тоже в моих планах есть, но следующим актом марлезонского балета … ;)

И, кстати, т.к. BASIC драйвер построен на ASCII - то и тупит он точно также … поэтому не удивительно,
что в различных наборах шаблонов пытаются его заменить на работу со строкой в памяти.
Логично, разумно и очень эффективно (скорость обработки на больших текстовых файлов возрастает на порядок).

Работа с текстовым файлов как с строкой

Добавлено: 17 Октябрь 2018, 9:32
morkovin
обработку файла BASIC драйвером, а не ASCII
Мне не приходится объявлять никакие BASIC- и ASCII-файлы в словаре

Работа с текстовым файлов как с строкой

Добавлено: 17 Октябрь 2018, 9:40
Игорь Столяров
morkovin писал(а): 17 Октябрь 2018, 9:32 Мне не приходится объявлять никакие BASIC- и ASCII-файлы в словаре
Объявлять структуру текстовых файлов в словаре - это конечно же анахронизм, но по ходу работы программы,
в различных процедурах приходится (точнее раньше приходилось) объявлять различные текстовые файлы для обработки.
Например, дёрнуть страничку с сайта и распарсить и т.д.
Много есть задач с обработкой текстовых файлов, так или иначе ...

Работа с текстовым файлов как с строкой

Добавлено: 17 Октябрь 2018, 10:06
morkovin
объявлять различные текстовые файлы для обработки
Главный объект в StringTheory - это "строка" (с динамическим выделением памяти)
Объявил нужные объекты:
st StringTheory
st1 StringTheory
....
и дальше делай с ними любые манипуляции
st.SetValue('hello world')

st.LoadFile('c:\windows\win.ini')
st.ToBlob(IniData.Text)

st1.FromBlob(IniData.Text)
myBlobContents = st1.GetValue()

и др.

Работа с текстовым файлов как с строкой

Добавлено: 17 Октябрь 2018, 10:20
Игорь Столяров
morkovin писал(а): 17 Октябрь 2018, 10:06Главный объект в StringTheory - это "строка"
Не вызывает сомнений. Вы описываете, как пользоваться готовым инструментом для работы со строками.
А я пытаюсь этот инструмент реализовать … ;)

Работа с текстовым файлов как с строкой

Добавлено: 17 Октябрь 2018, 11:07
morkovin
А я пытаюсь этот инструмент реализовать …
Не опоздал? :)
Там всё в исходных кодах. Бери и рихтуй.

Работа с текстовым файлов как с строкой

Добавлено: 17 Октябрь 2018, 11:13
Игорь Столяров
morkovin писал(а): 17 Октябрь 2018, 11:07Там всё в исходных кодах. Бери и рихтуй.
Та в принципе, не такая уж сложная задача, на самом деле-то … ;)
Намного интересней разобраться и сделать, чем копаться в чужих классах, где куча всего разного (и мне не нужного). :)