<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title type="html"><![CDATA[Серый форум &mdash; VBScript: работа с большими текстовыми файлами]]></title>
	<link rel="self" href="http://forum.script-coding.com/extern.php?action=feed&amp;tid=1322&amp;type=atom" />
	<updated>2008-04-02T10:57:04Z</updated>
	<generator>PunBB</generator>
	<id>http://forum.script-coding.com/viewtopic.php?id=1322</id>
		<entry>
			<title type="html"><![CDATA[Re: VBScript: работа с большими текстовыми файлами]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=10207#p10207" />
			<content type="html"><![CDATA[<p>Ещё один пример, попроще. Я взял для примера большой файл лога 1С v7.7 (1cv7.mlg). Расширение файла надо переименовывать в &quot;txt&quot;.<br /><strong>C:\Temp\Schema.ini</strong><br /></p><div class="codebox"><pre><code>[1cv7.txt]
ColNameHeader=False
Format=Delimited(;)
TextDelimiter=none
CharacterSet=ANSI
Col1=Date Text
Col2=Time Text
Col3=User Text
Col4=Mode Text
Col5=Field5 Text
Col6=Field6 Text
Col7=Field7 Text
Col8=Field8 Text
Col9=Field9 Text
Col10=Field10 Text</code></pre></div><p>Собственно пример:<br /></p><div class="codebox"><pre><code>Set objRec = CreateObject(&quot;ADODB.Recordset&quot;)
strFile = &quot;1cv7.txt&quot;
strQuery = &quot;SELECT S.[Date], S.[Time], S.[Mode] FROM [&quot; &amp; strFile &amp; &quot;] AS S&quot; &#039;WHERE S.[User] = &#039;kos&#039;&quot;
strIni = &quot;C:\Temp&quot; &#039;Schema.ini
strConn = &quot;Provider=Microsoft.Jet.OLEDB.4.0;Data Source=&quot; &amp; strIni &amp; &quot;;Extended Properties=&quot;&quot;text;&quot;&quot;&quot;
Const adOpenStatic = 3
Const adLockOptimistic = 3
Const adCmdText = 1

objRec.Open strQuery, strConn, adOpenStatic, adLockOptimistic, adCmdText
&#039;While Not objRec.EOF
&#039;    strRes = vbNullString
&#039;    For i=0 To objRec.Fields.Count-1
&#039;        strRes = strRes &amp; CStr(objRec.Fields(i).Value) &amp; vbTab
&#039;    Next
&#039;    WScript.Echo Trim(strRes)
&#039;    objRec.MoveNext
&#039;Wend
WScript.Echo objRec.RecordCount
objRec.Close
Set objRec = Nothing</code></pre></div><p>Файл лога имел размер 630 915 078 байт, все записи (строки) без условий выбираются примерно за 80 сек. (5 223 755 строк). С условиями (WHERE): 164 117 строк примерно за 70 сек., 2 228 строк примерно за 44 сек., ноль строк примерно за те же 44 сек.<br />WinXP SP2, 512Мб памяти, Celeron D 3.0GHz.</p><p>Замечание от <strong>fps</strong>: для небольших объемов (&lt;100 МБ) ReadAll() и затем, при надобности, разбор регекспами получается быстрее и проще в реализации. Пример подобной обработки <a href="http://forum.script-coding.com/viewtopic.php?id=1301">здесь</a>. Но с гигабайтами так уже не поработаешь.</p>]]></content>
			<author>
				<name><![CDATA[The gray Cardinal]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=2</uri>
			</author>
			<updated>2008-04-02T10:57:04Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=10207#p10207</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[VBScript: работа с большими текстовыми файлами]]></title>
			<link rel="alternate" href="http://forum.script-coding.com/viewtopic.php?pid=10206#p10206" />
			<content type="html"><![CDATA[<p><strong>ADOFromText.wsf</strong><br /></p><div class="codebox"><pre><code>&lt;?XML version=&quot;1.0&quot; standalone=&quot;yes&quot; ?&gt;
&lt;job id=&quot;ADOFromText&quot;&gt;
    &lt;?job error=&quot;True&quot; debug=&quot;True&quot; ?&gt;
    &lt;runtime&gt;
        &lt;description&gt;This script XOR-filtering lines from Source file by part lines from Filter file, then save result lines in Result file&lt;/description&gt;
        &lt;named name=&quot;PathToSchema&quot;   helpstring=&quot;Path to schema&quot;             type=&quot;string&quot; required=&quot;true&quot; /&gt;
        &lt;named name=&quot;SourceFile&quot;     helpstring=&quot;Name of source file&quot;        type=&quot;string&quot; required=&quot;true&quot; /&gt;
        &lt;named name=&quot;SourcePathDiff&quot; helpstring=&quot;Diff part of source&#039;s path&quot; type=&quot;string&quot; required=&quot;true&quot; /&gt;
        &lt;named name=&quot;FilterFile&quot;     helpstring=&quot;Name of filter file&quot;        type=&quot;string&quot; required=&quot;true&quot; /&gt;
        &lt;named name=&quot;FilterPathDiff&quot; helpstring=&quot;Diff part of filter&#039;s path&quot; type=&quot;string&quot; required=&quot;true&quot; /&gt;
        &lt;named name=&quot;ResultFile&quot;     helpstring=&quot;Name of result file&quot;        type=&quot;string&quot; required=&quot;true&quot; /&gt;
        
        &lt;example&gt;Example: ADOFromText.wsf /PathToSchema:&quot;c:\temp&quot; /SourceFile:&quot;SourceFile.txt&quot; /SourcePathDiff:&quot;c:\Install&quot; /FilterFile:&quot;FilterFile.txt&quot; /FilterPathDiff:&quot;\\server\Installation$&quot; /ResultFile:&quot;ResultFile.txt&quot;&lt;/example&gt;
    &lt;/runtime&gt;
    
    &lt;reference object=&quot;ADODB.Connection&quot; /&gt;
    
    &lt;object id=&quot;objRecordSetResult&quot; progid=&quot;ADODB.Recordset&quot; /&gt;
    &lt;object id=&quot;objFSO&quot;             progid=&quot;Scripting.FileSystemObject&quot; /&gt;
    
    &lt;script language=&quot;VBScript&quot;&gt;
        &lt;![CDATA[
            Option Explicit
            
            Dim objNamedArgs : Set objNamedArgs = WScript.Arguments.Named
            
            If objFSO.FileExists(objFSO.BuildPath(objNamedArgs.Item(&quot;PathToSchema&quot;), objNamedArgs.Item(&quot;ResultFile&quot;))) Then
                objFSO.DeleteFile objFSO.BuildPath(objNamedArgs.Item(&quot;PathToSchema&quot;), objNamedArgs.Item(&quot;ResultFile&quot;))
            End If

            objRecordSetResult.Open &quot;SELECT S.[FileName], S.[Path], S.[DateTimeModified], S.[Size] INTO [&quot; &amp; _
                objNamedArgs.Item(&quot;ResultFile&quot;) &amp; &quot;] &quot; &amp; _
                &quot;FROM [&quot; &amp; objNamedArgs.Item(&quot;SourceFile&quot;) &amp; &quot;] AS S LEFT JOIN [&quot; &amp; _
                objNamedArgs.Item(&quot;FilterFile&quot;) &amp; &quot;] AS F ON &quot; &amp; _
                &quot;S.[FileName] = F.[FileName] AND &quot; &amp; _
                &quot;MID(S.[Path], &quot; &amp; CStr(Len(objNamedArgs.Item(&quot;SourcePathDiff&quot;)) + 1) &amp; &quot;) = &quot; &amp; _
                &quot;MID(F.[Path], &quot; &amp; CStr(Len(objNamedArgs.Item(&quot;FilterPathDiff&quot;)) + 1) &amp; &quot;) AND &quot; &amp; _
                &quot;S.[DateTimeModified] = F.[DateTimeModified] AND S.[Size] = F.[Size] &quot; &amp; _
                &quot;WHERE F.[FileName] IS NULL&quot;, _
                &quot;Provider=Microsoft.Jet.OLEDB.4.0;Data Source=&quot; &amp; objNamedArgs.Item(&quot;PathToSchema&quot;) &amp; &quot;;Extended Properties=&quot;&quot;text;&quot;&quot;&quot;, _
                adOpenStatic, adLockOptimistic, adCmdText
            
            Set objNamedArgs = Nothing
            
            WScript.Quit 0
        ]]&gt;
    &lt;/script&gt;
&lt;/job&gt;</code></pre></div><p><strong>Schema.ini</strong><br /></p><div class="codebox"><pre><code>[HomeComp.txt]
ColNameHeader=False
Format=Delimited(;)
TextDelimiter=none
CharacterSet=ANSI
Col1=FileName Text
Col2=Path Text
Col3=DateTimeModified DateTime
Col4=Size Long

[JobComp.txt]
ColNameHeader=False
Format=Delimited(;)
TextDelimiter=none
CharacterSet=ANSI
Col1=FileName Text
Col2=Path Text
Col3=DateTimeModified DateTime
Col4=Size Long

[ResultFile.txt]
ColNameHeader=False
Format=Delimited(;)
TextDelimiter=none
DateTimeFormat=mm.dd.yy hh:nn
CharacterSet=ANSI
Col1=FileName Text
Col2=Path Text
Col3=DateTimeModified DateTime
Col4=Size Long</code></pre></div><p>Пример файла <strong>JobComp.txt</strong><br /></p><div class="codebox"><pre><code>IM000001.JPG;C:\Install\My Archivies\ФОТКИ\28-05-06 (Н.Я.День рожденье);28.05.2006 17:17;1437280
IM000002.JPG;C:\Install\My Archivies\ФОТКИ\28-05-06 (Н.Я.День рожденье);28.05.2006 17:26;1453600
IM000003.JPG;C:\Install\My Archivies\ФОТКИ\28-05-06 (Н.Я.День рожденье);28.05.2006 17:27;1576192
IM000006.JPG;C:\Install\My Archivies\ФОТКИ\28-05-06 (Н.Я.День рожденье);28.05.2006 17:30;1483488
IM000007.JPG;C:\Install\My Archivies\ФОТКИ\28-05-06 (Н.Я.День рожденье);28.05.2006 17:34;1335840
IM000008.JPG;C:\Install\My Archivies\ФОТКИ\28-05-06 (Н.Я.День рожденье);28.05.2006 17:37;1516512
IM000009.JPG;C:\Install\My Archivies\ФОТКИ\28-05-06 (Н.Я.День рожденье);28.05.2006 17:38;1672512
IM000010.JPG;C:\Install\My Archivies\ФОТКИ\28-05-06 (Н.Я.День рожденье);28.05.2006 17:38;1521632
IM000011.JPG;C:\Install\My Archivies\ФОТКИ\28-05-06 (Н.Я.День рожденье);28.05.2006 17:39;1367072</code></pre></div><p>Пример файла <strong>HomeComp.txt</strong><br /></p><div class="codebox"><pre><code>IM000001.JPG;D:\Other\ФОТКИ\28-05-06 (Н.Я.День рожденье);28.05.2006 17:17;1437280
IM000002.JPG;D:\Other\ФОТКИ\28-05-06 (Н.Я.День рожденье);28.05.2006 17:26;1453600
IM000005.JPG;D:\Other\ФОТКИ\28-05-06 (Н.Я.День рожденье);28.05.2006 17:29;1606784
IM000006.JPG;D:\Other\ФОТКИ\28-05-06 (Н.Я.День рожденье);28.05.2006 17:30;1483488
IM000010.JPG;D:\Other\ФОТКИ\28-05-06 (Н.Я.День рожденье);28.05.2006 17:38;1521632
IM000011.JPG;D:\Other\ФОТКИ\28-05-06 (Н.Я.День рожденье);28.05.2006 17:39;1367072</code></pre></div><p>Для примера: все указанные файлы находятся в [c:\0001]. Тогда вызов <strong>ADOFromText.wsf</strong> осуществляется командой:<br /></p><div class="quotebox"><blockquote><p>cscript.exe //nologo &quot;c:\0001\ADOFromText.wsf&quot; /PathToSchema:&quot;c:\0001&quot; /SourceFile:&quot;JobComp.txt&quot; /SourcePathDiff:&quot;C:\Install\My Archivies&quot; /FilterFile:&quot;HomeComp.txt&quot; /FilterPathDiff:&quot;D:\Other&quot; /ResultFile:&quot;ResultFile.txt&quot;</p></blockquote></div><p>Результирующий файл <strong>ResultFile.txt</strong><br /></p><div class="codebox"><pre><code>IM000003.JPG;C:\Install\My Archivies\ФОТКИ\28-05-06 (Н.Я.День рожденье);05.28.06 17:27;1576192
IM000007.JPG;C:\Install\My Archivies\ФОТКИ\28-05-06 (Н.Я.День рожденье);05.28.06 17:34;1335840
IM000008.JPG;C:\Install\My Archivies\ФОТКИ\28-05-06 (Н.Я.День рожденье);05.28.06 17:37;1516512
IM000009.JPG;C:\Install\My Archivies\ФОТКИ\28-05-06 (Н.Я.День рожденье);05.28.06 17:38;1672512</code></pre></div><p><em>Примечания:</em></p><p>Собственно, вся функциональность лежит в использовании запроса<br /></p><div class="quotebox"><blockquote><p>RecordSet.Open &quot;SELECT &lt;поля&gt; INTO &quot;ResultFile&quot; FROM &quot;SourceFile&quot; LEFT JOIN &quot;FilterFile&quot; ON &lt;Связь полей&gt;, &lt;Соединение&gt;,…</p></blockquote></div><p>Мы извлекаем <em>все</em> записи из &quot;SourceFile&quot;, связанного с &quot;FilterFile&quot; (<strong>LEFT JOIN</strong>) по указанному условию &lt;Связь полей&gt;. Нас интересуют равенство полей [FileName], [DateTimeModified] и [Size] (<strong>S.[FileName] = F.[FileName]</strong>, …). Из полей [Path] при сравнении мы исключаем несовпадающие начальные части, указанные в параметрах скрипта (<strong>MID(S.[Path], &quot; &amp; CStr(Len(objNamedArgs.Item(&quot;SourcePathDiff&quot;)) + 1) &amp; &quot;)=…</strong>). Также, из полученного набора мы исключаем записи, в которых значения полей из правой таблицы — пустые (для примера взято поле [File]: <strong>WHERE F.[FileName] IS NULL</strong>). И, наконец, помещаем полученный набор записей в результирующую таблицу &quot;ResultFile&quot; (<strong>INTO [&quot; &amp; objNamedArgs.Item(&quot;ResultFile&quot;) &amp; &quot;]</strong>).</p><p>Как правило, стоит заключать строки в кавычки, как и положено в CSV, хотя это и необязательно. В примере я не использовал их и для выходного файла (<strong>Schema.ini</strong>:TextDelimiter=none).</p><p>Формат дата/время желательно представлять с секундами В примере я не использовал секунды и для выходного файла (<strong>Schema.ini</strong>:DateTimeFormat=mm.dd.yy hh:nn) <em>[в скобках замечу, что мне не удалось использовать указание такого формата для <strong>входных</strong> файлов, приводило к ошибке]</em>.</p><p>Вместо<br /></p><div class="codebox"><pre><code>If objFSO.FileExists(objFSO.BuildPath(objNamedArgs.Item(&quot;PathToSchema&quot;), objNamedArgs.Item(&quot;ResultFile&quot;))) Then
    objFSO.DeleteFile objFSO.BuildPath(objNamedArgs.Item(&quot;PathToSchema&quot;), objNamedArgs.Item(&quot;ResultFile&quot;))
End If</code></pre></div><p>можно использовать &quot;DROP TABLE [&quot; &amp; objNamedArgs.Item(&quot;ResultFile&quot;) &amp; &quot;]&quot;, однако это приводит и к удалению из схемы информации о соответствующей таблице <img src="//forum.script-coding.com/img/smilies/smile.png" width="15" height="15" />, а она у нас не совсем стандартная (-кавычки, -секунды), так что, для простоты, пользуем простое удаление результирующего файла <em>[также отмечу, что операция DELETE для Text Driver не поддерживается в принципе]</em>.</p><p>Часть параметров из <strong>Schema.ini</strong> можно указывать в строке подключения, как свойства:<br /></p><div class="codebox"><pre><code>Provider=Microsoft.Jet.OLEDB.4.0;Data Source=c:\txtFilesFolder\;Extended Properties=&quot;text;HDR=Yes;FMT=Delimited&quot;</code></pre></div><p>Полного описания я, к сожалению, не нашёл.</p><p><a href="http://msdn2.microsoft.com/en-us/library/ms974559.aspx">Much ADO About Text Files</a></p><p>Автор статьи - <strong>alexii</strong>.</p>]]></content>
			<author>
				<name><![CDATA[The gray Cardinal]]></name>
				<uri>http://forum.script-coding.com/profile.php?id=2</uri>
			</author>
			<updated>2008-04-02T10:46:06Z</updated>
			<id>http://forum.script-coding.com/viewtopic.php?pid=10206#p10206</id>
		</entry>
</feed>
