Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / считывание строк с конца файла / 13 сообщений из 13, страница 1 из 1
30.10.2006, 12:27
    #34090684
kruzz
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
считывание строк с конца файла
Помогите, пожалуйста новичку.
Задача такая, есть открытый <FOPEN()> файл, В нем нужно считать строки с конца файла к началу, как это организовать?
Пробовал в рсновном поиском FB-CR и FGETS(), пока ничего не получается.
Заранее благодарен.
...
Рейтинг: 0 / 0
30.10.2006, 13:03
    #34090868
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
считывание строк с конца файла
Создай курсор: MyFile(nLine i, cText c(200))
прочитай файл в курсор заполняя nLine номером строки
затем отсортируй курсор в обратном порядке nLine

а можешь весь файл загнать в переменную см. FREAD() а потом парси его хоть в шахматном порядке

А зачем надо файл задом наперед читать?
...
Рейтинг: 0 / 0
30.10.2006, 13:17
    #34090934
считывание строк с конца файла
kruzzПомогите, пожалуйста новичку.
Задача такая, есть открытый <FOPEN()> файл, В нем нужно считать строки с конца файла к началу, как это организовать?
Пробовал в рсновном поиском FB-CR и FGETS(), пока ничего не получается.
Заранее благодарен.
В такой постановке - никак.
Мои варианты:
1. считать все строки в массив и выдавать их, начиная с конца массива. Но это подходит только если строк немного, так как существует ограничение на максимальное число строк в массиве.
2. Создать таблицу/курсор, куда занести № п/п строки и смещение от начала файла(байт). Потом сканируем эту таблицу "снизу вверх", переходим на нужный байт и считываем нужную строку. Недостаток - необходимо два раза проходить по файлу: один раз для разметки, второй раз - для считывания.
3. Считать строки не в один массив, а в несколько массивов, создаваемых по мере необходимости. После сичтывания всех строк считываем элементы массивов в порядке обратном созданию массивов и заполнению строк. Позволяет обойти ограничения по размеру массива. Количество массивов ограничено размером доступной памяти.

Для "хороших" машин, ИМХО, лучше вариант №3, для старых машин - вариант №2...
...
Рейтинг: 0 / 0
30.10.2006, 13:17
    #34090935
kruzz
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
считывание строк с конца файла
Dima T
создать курсор, это временная таблица, я так понял?

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

читать с конца строки, это ведение статистики по последним командам из одной программы.
...
Рейтинг: 0 / 0
30.10.2006, 13:23
    #34090966
kruzz
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
считывание строк с конца файла
я тут нашел функцию, толко теперь не знаю, как ее подключить, пробовал, но у меня постоянно выдает ошибку.

*** FGETSB (_f_hndl)
* Функция аналогична FGETS(), но берет из файла не следующую, а предыдущую строку.
* для файлов, в которых переход на следующую строку производится комбинацией символов
* 0D 0A - то есть, Carriage Return и потом Line Feed
FUNCTION FGETSB
PARAMETERS _f_hndl && идентификатор файла
* объявление переменных
&&
PRIVATE _char
PRIVATE _string
Private _chrstoreceive
private _chrstofbegin
private _ischartoadd
_chrstoreceive = 254
_chrstofbegin = fseek(_f_hndl,0,1)
_string = ''
_char = ''
* Проверка не пуст ли файл.
if feof(_f_hndl) and _chrstofbegin = 0
_chrstoreceive = 0
endif
* НАЧАЛО
&& Предварительно перемещаем курсор в положение перед Carriage Return.
if _chrstofbegin>=2
_chrstofbegin = fseek(_f_hndl,-2,1)
_char = fread(_f_hndl,2)
if _char=(chr(13)+chr(10)) && Carriage return 0Dh + Line Feed 0Ah
_chrstofbegin = fseek(_f_hndl,-2,1)
else
_chrstofbegin = fseek(_f_hndl,0,1)
endif
endif
_char = ''
&& Теперь считываем строку
do while _chrstoreceive>0 and _chrstofbegin>0
_ischartoadd = .t.
_chrstofbegin = fseek(_f_hndl,-1,1)
_char = fread(_f_hndl,1)
_chrstofbegin = fseek(_f_hndl,-1,1)
if asc(_char)=10 && Line Feed 0Ah
loop
endif
if asc(_char)=13 && Carriage Return 0Dh
_chrstoreceive=0
= fgets(_f_hndl) && Это нужно для того, чтобы после импорта строки указатель в файле стоял после CarriageReturn и LineFeed, а не до. Для совместимости с fgets().
loop
endif
_string = _char + _string
_chrstoreceive = _chrstoreceive - 1
enddo

RETURN _string
* End of FGETSB
...
Рейтинг: 0 / 0
30.10.2006, 13:29
    #34090991
считывание строк с конца файла
kruzzDima T
создать курсор, это временная таблица, я так понял?

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

читать с конца строки, это ведение статистики по последним командам из одной программы.
5 Мб для современных 512 Мб оперативки (минимальный стандарт) - несерьезно...
Курсор, кстати, тоже находится в памяти (в этом его принципиальное отличие от таблицы).

2 Dima T:
Длина строки не определена. Она вполне может быть как намного меньше, так и намного больше указанных Вами 200 символов. Поэтому лучше, чтобы сText было мемо-полем.
...
Рейтинг: 0 / 0
30.10.2006, 14:11
    #34091186
считывание строк с конца файла
kruzzя тут нашел функцию, толко теперь не знаю, как ее подключить, пробовал, но у меня постоянно выдает ошибку.

*** FGETSB (_f_hndl)
* Функция аналогична FGETS(), но берет из файла не следующую, а предыдущую строку.
* для файлов, в которых переход на следующую строку производится комбинацией символов
* 0D 0A - то есть, Carriage Return и потом Line Feed
FUNCTION FGETSB
PARAMETERS _f_hndl && идентификатор файла
* объявление переменных
&&
PRIVATE _char
PRIVATE _string
Private _chrstoreceive
private _chrstofbegin
private _ischartoadd
_chrstoreceive = 254
_chrstofbegin = fseek(_f_hndl,0,1)
_string = ''
_char = ''
* Проверка не пуст ли файл.
if feof(_f_hndl) and _chrstofbegin = 0
_chrstoreceive = 0
endif
* НАЧАЛО
&& Предварительно перемещаем курсор в положение перед Carriage Return.
if _chrstofbegin>=2
_chrstofbegin = fseek(_f_hndl,-2,1)
_char = fread(_f_hndl,2)
if _char=(chr(13)+chr(10)) && Carriage return 0Dh + Line Feed 0Ah
_chrstofbegin = fseek(_f_hndl,-2,1)
else
_chrstofbegin = fseek(_f_hndl,0,1)
endif
endif
_char = ''
&& Теперь считываем строку
do while _chrstoreceive>0 and _chrstofbegin>0
_ischartoadd = .t.
_chrstofbegin = fseek(_f_hndl,-1,1)
_char = fread(_f_hndl,1)
_chrstofbegin = fseek(_f_hndl,-1,1)
if asc(_char)=10 && Line Feed 0Ah
loop
endif
if asc(_char)=13 && Carriage Return 0Dh
_chrstoreceive=0
= fgets(_f_hndl) && Это нужно для того, чтобы после импорта строки указатель в файле стоял после CarriageReturn и LineFeed, а не до. Для совместимости с fgets().
loop
endif
_string = _char + _string
_chrstoreceive = _chrstoreceive - 1
enddo

RETURN _string
* End of FGETSB
Для того, чтобы начать пользоваться этой функцией необходимо перейти на конец файла (или конец любой строки). А затем вызывать эту функцию... В твоем случае надо будет вызывать в цикле.
К сожалению, проверка на достижение начала файла в этой функции (согласно представленному тексту) не реализована, поэтому будь готов самостоятельно отлавливать это событие...
...
Рейтинг: 0 / 0
30.10.2006, 14:20
    #34091226
Dima T
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
считывание строк с конца файла
kruzzя тут нашел функцию, толко теперь не знаю, как ее подключить, пробовал, но у меня постоянно выдает ошибку.
...

Как пробовал? Какую ошибку?
...
Рейтинг: 0 / 0
31.10.2006, 11:21
    #34093438
kruzz
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
считывание строк с конца файла
Dima T
Примерно в месте
&& Теперь считываем строку
просто прекращает работу и очищает почти все переменные
...
Рейтинг: 0 / 0
31.10.2006, 11:44
    #34093556
GoshaS
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
считывание строк с конца файла
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
local lcFile, loFile, lcZnach, lnRecNo
lcFile=GETFILE('txt')
loFile=FOPEN(lcFile)
IF loFile> 0 
   lnRecNo= 0 
   CREATE CURSOR c_tmp (nRecNo n( 16 , 0 ), znach M)
   DO WHILE !FEOF(loFile) 
        lcZnach = FGETS(loFile,  300 )
        lnRecNo=lnRecNo+ 1 
        insert into c_tmp (nRecNo, znach) values (lnRecNo, lcZnach)
   ENDDO 
ELSE 
   MESSAGEBOX('Невозможно открыть файл')
ENDIF 
FCLOSE(loFile)
ну потом этот курсор крути как хочешь. Хоть в обратном порядке, хоть чет-нечет и пр. :)
...
Рейтинг: 0 / 0
31.10.2006, 23:33
    #34095953
ORAselect
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
считывание строк с конца файла
А FSEEK не проще использовать, предварительно считав с дескриптора длину файла и длину строки?!

Установить на последний байт, а затем в цикле сдвигаться вверх на 1 строку, запоминать позицию, читать строку, возвращаться в запомненную позицию, снова уходить вверх на длину строки и так пока не выгреб кол-во записей. Оно тоже есть в дескрипторе. Кстати, читать строку в буфер целиком, а не побайтно и уже буфер крутить.
...
Рейтинг: 0 / 0
01.11.2006, 12:55
    #34097148
kruzz
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
считывание строк с конца файла
GoshaS
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
local lcFile, loFile, lcZnach, lnRecNo
lcFile=GETFILE('txt')
loFile=FOPEN(lcFile)
IF loFile> 0 
   lnRecNo= 0 
   CREATE CURSOR c_tmp (nRecNo n( 16 , 0 ), znach M)
   DO WHILE !FEOF(loFile) 
        lcZnach = FGETS(loFile,  300 )
        lnRecNo=lnRecNo+ 1 
        insert into c_tmp (nRecNo, znach) values (lnRecNo, lcZnach)
   ENDDO 
ELSE 
   MESSAGEBOX('Невозможно открыть файл')
ENDIF 
FCLOSE(loFile)
ну потом этот курсор крути как хочешь. Хоть в обратном порядке, хоть чет-нечет и пр. :)

а как потом к нему обращаться?

ORAselect
вроде FSEEK только в одну сторону работает?
...
Рейтинг: 0 / 0
01.11.2006, 13:37
    #34097377
считывание строк с конца файла
kruzz GoshaS
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
local lcFile, loFile, lcZnach, lnRecNo
lcFile=GETFILE('txt')
loFile=FOPEN(lcFile)
IF loFile> 0 
   lnRecNo= 0 
   CREATE CURSOR c_tmp (nRecNo n( 16 , 0 ), znach M)
   DO WHILE !FEOF(loFile) 
        lcZnach = FGETS(loFile,  300 )
        lnRecNo=lnRecNo+ 1 
        insert into c_tmp (nRecNo, znach) values (lnRecNo, lcZnach)
   ENDDO 
ELSE 
   MESSAGEBOX('Невозможно открыть файл')
ENDIF 
FCLOSE(loFile)
ну потом этот курсор крути как хочешь. Хоть в обратном порядке, хоть чет-нечет и пр. :)

а как потом к нему обращаться?


Как к обычной таблице. Например:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
.......
select c_tmp
go bottom
do while !bof()
  ? c_tmp.nRecno
  skip - 1 
enddo
.........
...
Рейтинг: 0 / 0
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / считывание строк с конца файла / 13 сообщений из 13, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]