Как обойтись без Eof
Или как правильно загрузить массив из текст файла?:roll:
Есть текст файл, это запись массива допустим 65000*20. Если для переноса данных в массив использовать Do while EOF(), то очень долго получается. Но если знаешь колличество строк в этом файле(т.е. 65000), то используя For ... Next ... процесс загрузки ускоряется в десятки раз. Как узнать сколько строк в текст файле?
Или как правильно загрузить массив из текст файла?:roll:
Попрбуй подключить библиотеку scrrun.dll (Microsoft Scripting Runtime) и при помощи её объектов работать с файлом. Там есть такой объект, как текстовый поток. По-моему, при помощи его твою проблему можно решить.
Поколдуй с объектами этой библы, связанными с файлами. Должно всё получиться быстро и надёжно.
Попрбуй подключить библиотеку scrrun.dll (Microsoft Scripting Runtime) и при помощи её объектов работать с файлом. Там есть такой объект, как текстовый поток. По-моему, при помощи его твою проблему можно решить.
Поколдуй с объектами этой библы, связанными с файлами. Должно всё получиться быстро и надёжно.
Как эту библиотеку подключить? В Help ни чего ни про StreamText, ни про TextStream не упоминается.
Как эту библиотеку подключить? В Help ни чего ни про StreamText, ни про TextStream не упоминается.
Project -> References, а там выбираешь Microsoft Scripting Runtime, либо явно указываешь файл scrrun.dll в system32
в теме http://forum.codenet.ru/showthread.php?threadid=15556&highlight=ErrDescr можешь найти примеры работы с текстом при помощи этой библиотеки (в примере процедуры лога ошибок).
Есть текст файл, это запись массива допустим 65000*20. Если для переноса данных в массив использовать Do while EOF(), то очень долго получается. Но если знаешь колличество строк в этом файле(т.е. 65000), то используя For ... Next ... процесс загрузки ускоряется в десятки раз. Как узнать сколько строк в текст файле?
Или как правильно загрузить массив из текст файла?:roll:
Что-то странное.., это что же, постоянная проверка EOF так напрягает цикл, верится с трудом...
У меня например написана функция по слиянию файлов в один, считывает по кускам пока не дойдет до конца по EOF(). Не замечал никаких особенно тормозов, по скорости работает также как MS-DOS команда COPY file1+file2+file3 newfile:
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.
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. Но так как мне надо обрабатывать данные (поджимает время), просто нет времени разбираться в тонкостях програмирования, вот и прошу, подскажите ,если кто знает, как бысро не известный файл перевести в массив?
Попробуй использовать объект 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?
Зачем мне текстстрим? Использовать метод 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
Зачем мне текстстрим? Использовать метод 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?
реализовать свой тип данных (структуру) со всеми нужными полями и записывать и читать всю структуру целиком, а не по отдельному полю.
задавайте же вопросы по человечески
Вот как загнать содержимое файла в оперативку:
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
-загонит моментально
каков вопрос таков ответ
если не то пишите дальше разберемся
Чтото вообще путаница какаято
задавайте же вопросы по человечески
Вот как загнать содержимое файла в оперативку:
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 значений разделенных пробелом или запятой или точкой с запятой, сохранен в текст файле. Задача вернуть значения из этого текст файла обратно в двумерный массив.
Двумерный массив, где в строке 6 значений разделенных пробелом или запятой или точкой с запятой, сохранен в текст файле. Задача вернуть значения из этого текст файла обратно в двумерный массив.
ну можно сначала все в память а потом в памяти перебирать и делить на строки и столбцы
-это будет быстрее
Двумерный массив, где в строке 6 значений разделенных пробелом или запятой или точкой с запятой, сохранен в текст файле. Задача вернуть значения из этого текст файла обратно в двумерный массив.
можно движок какой-нить бд использовать... через access мона...
ну можно сначала все в память а потом в памяти перебирать и делить на строки и столбцы
-это будет быстрее
Насчет разделения на столбцы можешь почитать эту дискуссию, там конечно они с другой целью строку анализируют но общие идеи оптимизации универсальны и поучительны: http://www.sql.ru/forum/actualthread.aspx?bid=4&tid=87645&hl=Mid
Написал тест код:
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]
А вообще конечно тема оптимизации работы со строками(массивами) в памяти, очень широкая и глубокая :) в MSDN говорят есть несколько статей на тему оптимизации работы в VB со строками в памяти.
Не знаешь ведь каким размером сразу массив сделать.
Если к указаному коду добавить, вот такой:
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 увеличивается.
Как же все таки загрузить массив из текст файла, если не известно количество строк? Есть ли изящное решение?
Есть текст файл, это запись массива допустим 65000*20. Если для переноса данных в массив использовать Do while EOF(), то очень долго получается. Но если знаешь колличество строк в этом файле(т.е. 65000), то используя For ... Next ... процесс загрузки ускоряется в десятки раз. Как узнать сколько строк в текст файле?
Или как правильно загрузить массив из текст файла?:roll:
Сначала узнай размер файла
Полчается где то такой код:
Do
.....
.....
i=i+1
while(i<FileSize)
Redim Preserve...вот где собака порылась ...
Не знаешь ведь каким размером сразу массив сделать.
Если к указаному коду добавить, вот такой:
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 кб. ничего страшного, зато лишних вычислений будет меньше.