Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Как обойтись без Eof

7.0K
28 апреля 2004 года
Eugene D
7 / / 28.04.2004
Есть текст файл, это запись массива допустим 65000*20. Если для переноса данных в массив использовать Do while EOF(), то очень долго получается. Но если знаешь колличество строк в этом файле(т.е. 65000), то используя For ... Next ... процесс загрузки ускоряется в десятки раз. Как узнать сколько строк в текст файле?
Или как правильно загрузить массив из текст файла?:roll:
266
28 апреля 2004 года
mhaturov
901 / / 23.10.2003
Цитата:
Originally posted by Eugene D
Есть текст файл, это запись массива допустим 65000*20. Если для переноса данных в массив использовать Do while EOF(), то очень долго получается. Но если знаешь колличество строк в этом файле(т.е. 65000), то используя For ... Next ... процесс загрузки ускоряется в десятки раз. Как узнать сколько строк в текст файле?
Или как правильно загрузить массив из текст файла?:roll:


Попрбуй подключить библиотеку scrrun.dll (Microsoft Scripting Runtime) и при помощи её объектов работать с файлом. Там есть такой объект, как текстовый поток. По-моему, при помощи его твою проблему можно решить.
Поколдуй с объектами этой библы, связанными с файлами. Должно всё получиться быстро и надёжно.

7.0K
28 апреля 2004 года
Eugene D
7 / / 28.04.2004
Цитата:
Originally posted by mhaturov

Попрбуй подключить библиотеку scrrun.dll (Microsoft Scripting Runtime) и при помощи её объектов работать с файлом. Там есть такой объект, как текстовый поток. По-моему, при помощи его твою проблему можно решить.
Поколдуй с объектами этой библы, связанными с файлами. Должно всё получиться быстро и надёжно.


Как эту библиотеку подключить? В Help ни чего ни про StreamText, ни про TextStream не упоминается.

266
28 апреля 2004 года
mhaturov
901 / / 23.10.2003
Цитата:
Originally posted by Eugene D

Как эту библиотеку подключить? В Help ни чего ни про StreamText, ни про TextStream не упоминается.


Project -> References, а там выбираешь Microsoft Scripting Runtime, либо явно указываешь файл scrrun.dll в system32
в теме http://forum.codenet.ru/showthread.php?threadid=15556&highlight=ErrDescr можешь найти примеры работы с текстом при помощи этой библиотеки (в примере процедуры лога ошибок).

258
28 апреля 2004 года
SergeySV
1.5K / / 19.03.2003
Цитата:
Originally posted by Eugene D
Есть текст файл, это запись массива допустим 65000*20. Если для переноса данных в массив использовать Do while EOF(), то очень долго получается. Но если знаешь колличество строк в этом файле(т.е. 65000), то используя For ... Next ... процесс загрузки ускоряется в десятки раз. Как узнать сколько строк в текст файле?
Или как правильно загрузить массив из текст файла?:roll:



Что-то странное.., это что же, постоянная проверка EOF так напрягает цикл, верится с трудом...

У меня например написана функция по слиянию файлов в один, считывает по кускам пока не дойдет до конца по EOF(). Не замечал никаких особенно тормозов, по скорости работает также как MS-DOS команда COPY file1+file2+file3 newfile:

Код:
Open fileOut For Binary Access Write As #1
  For i = 1 To UBound(fileImpList)
    loc1 = LOF(1)
    loc2 = 1
    ' открываем файл для чтения
    Open fileImpList(i%) For Binary Access Read As #2
    Do While Not EOF(2)
      Get #2, loc2, ss        ' Read
      Put #1, loc1 + loc2, ss ' Write
      loc2 = loc2 + 10000
    Loop
    Close #2    ' Close file.
  Next i
  Close #1      ' Close file.
7.0K
28 апреля 2004 года
Eugene D
7 / / 28.04.2004
Допустим есть Погода.txt, где записаны переменные, Температура, Влажность, Давление, НаправлениеВетра, СилаВетра, Осадки, и т.д. с интервалом 1 минута за 1 год 2 месяца 3 дня 4 часа и 56 минут, плюс где-то в середине могут быть пробелы данных. Весит где-то 17 Мб. первый раз закачиваю его используя EOF приличное время. Если закачивать его несколько раз на день то, это начинает раздражать. Поэтому в следующий раз, когда знаю сколько в нем линий использую такую конструкцию.

Dim Mv()
Type ВсяПогода
СилаВетра As Single
НаправлениеВетра As Single
Давление As Single
Влажность As Single
Температура As Single
Дата As Date
End Type

Function inp(FileName as String, NumderOfLines as Long)
Dim Погода As ВсяПогода
ReDim Mv(1 To 6, 1 To NumderOfLines)
Open FileName For Input As #1
For i = 1 To NumderOfLines
With Погода
Input #1, .Дата, .Температура, .Влажность, .Давление, .НаправлениеВетра, .СилаВетра
Mv(1, i) = .Дата
Mv(2, i) = .Температура
Mv(3, i) = .Влажность
Mv(4, i) = .Давление
Mv(5, i) = .НаправлениеВетра
Mv(6, i) = .СилаВетра
End With
Next
Close #1
End Function

For Next справляется с этой задачей, за долю секунды.
Вот есть подсказка загнать файл целиком в переменную, а затем в массив. Есть еще предложение использовать Slim. Но так как мне надо обрабатывать данные (поджимает время), просто нет времени разбираться в тонкостях програмирования, вот и прошу, подскажите ,если кто знает, как бысро не известный файл перевести в массив?
648
28 апреля 2004 года
Tiraspolsky
220 / / 23.07.2003
Попробуй использовать объект TextStream. Как подключить библиотеку Microsoft Scripting Runtime тебе уже подсказали.
7.0K
28 апреля 2004 года
Eugene D
7 / / 28.04.2004
Цитата:
Originally posted by Tiraspolsky
Попробуй использовать объект TextStream. Как подключить библиотеку Microsoft Scripting Runtime тебе уже подсказали.


Зачем мне текстстрим? Использовать метод ReadAll?
Можно и так, LOF загрузит.
Используя EOF загрузка идет более 7 минут, только, что проверял, а их несколько десятков файлов может потребоваться перезагрузить.

Вот нашел способ быстро узнать сколько линий.:)
Dim ARead
Dim OneLine() As String
Open FileName For Input As #1
ARead = input(LOF(1), #1)
Close #1
OneLine = Split(ARead, vbCrLf)
NomberOfLines&=UBound(OneLine())+1

Кто-нибудь подскажет самый быстрый способ, как массив из 341250*6(это данные реального файла) значений(значения имеют тип string, data, single), записанный в ASCII text файл, перезаписать в оперативную память с помощью VB?

258
29 апреля 2004 года
SergeySV
1.5K / / 19.03.2003
Цитата:
Originally posted by Eugene D

Зачем мне текстстрим? Использовать метод ReadAll?
Можно и так, LOF загрузит.
Используя EOF загрузка идет более 7 минут, только, что проверял, а их несколько десятков файлов может потребоваться перезагрузить.

Вот нашел способ быстро узнать сколько линий.:)
Dim ARead
Dim OneLine() As String
Open FileName For Input As #1
ARead = input(LOF(1), #1)
Close #1
OneLine = Split(ARead, vbCrLf)
NomberOfLines&=UBound(OneLine())+1

Кто-нибудь подскажет самый быстрый способ, как массив из 341250*6(это данные реального файла) значений(значения имеют тип string, data, single), записанный в ASCII text файл, перезаписать в оперативную память с помощью VB?



Не очень понятно что тебе надо: Как массив переписать в операт. память ?!?!?

Но думаю в этом топике ты найдешь кое-что интересное: http://forum.codenet.ru/showthread.php?s=&threadid=16392

319
29 апреля 2004 года
xelos
577 / / 27.02.2003
Цитата:
Originally posted by Eugene D

Зачем мне текстстрим? Использовать метод ReadAll?
Можно и так, LOF загрузит.
Используя EOF загрузка идет более 7 минут, только, что проверял, а их несколько десятков файлов может потребоваться перезагрузить.

Вот нашел способ быстро узнать сколько линий.:)
Dim ARead
Dim OneLine() As String
Open FileName For Input As #1
ARead = input(LOF(1), #1)
Close #1
OneLine = Split(ARead, vbCrLf)
NomberOfLines&=UBound(OneLine())+1

Кто-нибудь подскажет самый быстрый способ, как массив из 341250*6(это данные реального файла) значений(значения имеют тип string, data, single), записанный в ASCII text файл, перезаписать в оперативную память с помощью VB?


реализовать свой тип данных (структуру) со всеми нужными полями и записывать и читать всю структуру целиком, а не по отдельному полю.

1.9K
29 апреля 2004 года
Putch
64 / / 22.02.2003
Чтото вообще путаница какаято
задавайте же вопросы по человечески

Вот как загнать содержимое файла в оперативку:
dim Mass() as byte
open "file.txt" for binary as #1
redim Mass(0 to lof(1)-1)as binary
get mas,,1
close #1

-загонит моментально





каков вопрос таков ответ

если не то пишите дальше разберемся
7.0K
29 апреля 2004 года
Eugene D
7 / / 28.04.2004
Цитата:
Originally posted by Putch
Чтото вообще путаница какаято
задавайте же вопросы по человечески

Вот как загнать содержимое файла в оперативку:
dim Mass() as byte
open "file.txt" for binary as #1
redim Mass(0 to lof(1)-1)as binary
get mas,,1
close #1

-загонит моментально





каков вопрос таков ответ

если не то пишите дальше разберемся



Двумерный массив, где в строке 6 значений разделенных пробелом или запятой или точкой с запятой, сохранен в текст файле. Задача вернуть значения из этого текст файла обратно в двумерный массив.

1.9K
29 апреля 2004 года
Putch
64 / / 22.02.2003
Цитата:
Originally posted by Eugene D


Двумерный массив, где в строке 6 значений разделенных пробелом или запятой или точкой с запятой, сохранен в текст файле. Задача вернуть значения из этого текст файла обратно в двумерный массив.







ну можно сначала все в память а потом в памяти перебирать и делить на строки и столбцы

-это будет быстрее

319
30 апреля 2004 года
xelos
577 / / 27.02.2003
Цитата:
Originally posted by Eugene D


Двумерный массив, где в строке 6 значений разделенных пробелом или запятой или точкой с запятой, сохранен в текст файле. Задача вернуть значения из этого текст файла обратно в двумерный массив.


можно движок какой-нить бд использовать... через access мона...

258
30 апреля 2004 года
SergeySV
1.5K / / 19.03.2003
Цитата:
Originally posted by Putch






ну можно сначала все в память а потом в памяти перебирать и делить на строки и столбцы

-это будет быстрее



Насчет разделения на столбцы можешь почитать эту дискуссию, там конечно они с другой целью строку анализируют но общие идеи оптимизации универсальны и поучительны: http://www.sql.ru/forum/actualthread.aspx?bid=4&tid=87645&hl=Mid

7.0K
01 мая 2004 года
Eugene D
7 / / 28.04.2004
Извзиняюсь, Уважаемые, оговорил EOF видимо не за что...
Написал тест код:
Код:
Type Ss
    Sa As String
    Sb As Single
    Sc As Single
    Sd As Single
    Se As Single
    SsDate As Date
End Type

Sub TestTxt()
Dim FRead As Variant, FileName As String, i As Long, T As Variant
Dim OneLine() As String, NomberOfLines As Long, Mass()
Dim SsTest As Ss
ReDim Mass(1 To 6, 1 To 1000000)
FileName = "C:\TestSs.txt"

    For i = 1 To 1000000
        Mass(1, i) = #2/2/2003 5:34:46 PM#
        Mass(2, i) = "Test"
        Mass(3, i) = 3.45
        Mass(4, i) = 4.5
        Mass(5, i) = 5.6789
        Mass(6, i) = 6.789
    Next
   
    T = Timer
Open FileName For Output As #1
    For i = 1 To 1000000
        Write #1, Mass(1, i); Mass(2, i); Mass(3, i); Mass(4, i); Mass(5, i); Mass(6, i)
    Next
Close #1
Debug.Print "WriteMassToFile ="; Timer - T
Erase Mass()

    T = Timer
ReDim Mass(1 To 6, 1 To 1000000)
Open FileName For Input As #1
i = 1
Do While Not EOF(1)
    With SsTest
        Input #1, .SsDate, .Sa, .Sb, .Sc, .Sd, .Se
        Mass(1, i) = .SsDate
        Mass(2, i) = .Sa
        Mass(3, i) = .Sb
        Mass(4, i) = .Sc
        Mass(5, i) = .Sd
        Mass(6, i) = .Se
        i = i + 1
    End With
Loop
Close #1
Debug.Print "DoInputMass ="; Timer - T

Erase Mass()
    T = Timer
Open FileName For Input As #1
    FRead = Input(LOF(1), #1)
Close #1
    OneLine = Split(FRead, vbCrLf)
Debug.Print "SplitLinesCount ="; Timer - T; UBound(OneLine())
Erase OneLine()

    T = Timer
i = 0
NomberOfLines = 1
Sd:
    NomberOfLines = InStr(NomberOfLines + 1, FRead, vbCrLf)
    If NomberOfLines <> 0 Then i = i + 1: GoTo Sd
Debug.Print "InStrLinesCount ="; Timer - T; i

    T = Timer
ReDim Mass(1 To 6, 1 To 1000000)
Open FileName For Input As #1
For i = 1 To 1000000
    With SsTest
        Input #1, .SsDate, .Sa, .Sb, .Sc, .Sd, .Se
        Mass(1, i) = .SsDate
        Mass(2, i) = .Sa
        Mass(3, i) = .Sb
        Mass(4, i) = .Sc
        Mass(5, i) = .Sd
        Mass(6, i) = .Se
    End With
Next
Close #1
Debug.Print "ForInputMass ="; Timer - T
End Sub


Результат:

WriteMassToFile = 9,3125
DoInputMass = 16,95313
SplitLinesCount = 25,73828 1000000
InStrLinesCount = 0,390625 1000000
ForInputMass = 16,99414

Буду искать, своем коде, что так ест время.

[SIZE=3]Спасибо, Всем![/SIZE]
258
01 мая 2004 года
SergeySV
1.5K / / 19.03.2003
Мда, это уже ближе к правде

А вообще конечно тема оптимизации работы со строками(массивами) в памяти, очень широкая и глубокая :) в MSDN говорят есть несколько статей на тему оптимизации работы в VB со строками в памяти.
7.0K
01 мая 2004 года
Eugene D
7 / / 28.04.2004
Redim Preserve...вот где собака порылась ...
Не знаешь ведь каким размером сразу массив сделать.
Если к указаному коду добавить, вот такой:
Код:
T = Timer
ReDim Mass(1 To 6, 1 To 1)
Open FileName For Input As #1
i = 1
Do While Not EOF(1)
ReDim Preserve Mass(1 To 6, 1 To i)
    With SsTest
        Input #1, .SsDate, .Sa, .Sb, .Sc, .Sd, .Se
        Mass(1, i) = .SsDate
        Mass(2, i) = .Sa
        Mass(3, i) = .Sb
        Mass(4, i) = .Sc
        Mass(5, i) = .Sd
        Mass(6, i) = .Se
        i = i + 1
    End With
Loop
Close #1
Debug.Print "PreserveInputMass ="; Timer - T

То для 100 000 циклов(на 1 000 000 циклов, как в предыдущем тесте, не хватило терпения) результат будет:
PreserveInputMass = 29,17969(!)
И видимо, с каждым шагом, время срабатывания ReDim Preserve увеличивается.

Как же все таки загрузить массив из текст файла, если не известно количество строк? Есть ли изящное решение?
499
02 мая 2004 года
madjahed
149 / / 14.01.2004
Цитата:
Originally posted by Eugene D
Есть текст файл, это запись массива допустим 65000*20. Если для переноса данных в массив использовать Do while EOF(), то очень долго получается. Но если знаешь колличество строк в этом файле(т.е. 65000), то используя For ... Next ... процесс загрузки ускоряется в десятки раз. Как узнать сколько строк в текст файле?
Или как правильно загрузить массив из текст файла?:roll:


Сначала узнай размер файла
Полчается где то такой код:
Do
.....
.....
i=i+1
while(i<FileSize)

258
02 мая 2004 года
SergeySV
1.5K / / 19.03.2003
Цитата:
Originally posted by Eugene D
Redim Preserve...вот где собака порылась ...
Не знаешь ведь каким размером сразу массив сделать.
Если к указаному коду добавить, вот такой:
Код:
T = Timer
ReDim Mass(1 To 6, 1 To 1)
Open FileName For Input As #1
i = 1
Do While Not EOF(1)
ReDim Preserve Mass(1 To 6, 1 To i)
    With SsTest
        Input #1, .SsDate, .Sa, .Sb, .Sc, .Sd, .Se
        Mass(1, i) = .SsDate
        Mass(2, i) = .Sa
        Mass(3, i) = .Sb
        Mass(4, i) = .Sc
        Mass(5, i) = .Sd
        Mass(6, i) = .Se
        i = i + 1
    End With
Loop
Close #1
Debug.Print "PreserveInputMass ="; Timer - T

То для 100 000 циклов(на 1 000 000 циклов, как в предыдущем тесте, не хватило терпения) результат будет:
PreserveInputMass = 29,17969(!)
И видимо, с каждым шагом, время срабатывания ReDim Preserve увеличивается.

Как же все таки загрузить массив из текст файла, если не известно количество строк? Есть ли изящное решение?



Ну да, в таких ситуациях я обычно сначала делаю цикл на узнавание вернх. границы, а уже потом один раз объявляешь массив и пошел почитать в уже в массив в цикле.

Думаю просто прокрутить цикл i=i+1 до конца файла по строчно будет не долго. проверь

Если все же скорость не устроит, тогда можно пожертвовать объемом против скорости, замнеив этот точный цикл на какое-нибудь приближенное макс. значение кол-ва строк. Можно из размера файла и макс. кол-во символов в строке сделать приблизительную оценка, которая будет точно больше, так сказать с запасом. Ну пропадет у тебя лишние 200-300 кб. ничего страшного, зато лишних вычислений будет меньше.

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог