| 网站首页 | 业界新闻 | 小组 | 交易 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
共有 1028 人关注过本帖
标题:请教如何对文本文件的实时监控与操作
只看楼主 加入收藏
ictest
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:280
专家分:114
注 册:2010-2-17
结帖率:73.33%
收藏
已结贴  问题点数:15 回复次数:5 
请教如何对文本文件的实时监控与操作
一个应用程序,每隔数秒就会向一个TXT文件里写入数百或数千行数据(每次写入的这数百或数千行数据可看成一个的数据段,N次写入就是N个数据段),每个数据段前面绝大部分都可以忽略不看,到最后都会生成如下格式的几行(注意:每次生成的这几行行数不定,中间的数据行(0~7)可能会有多有少,但头尾是一定有):

 Site    Sort     Bin
------------------------------------
    0         1         1
    1        31        31
    2         1         1
    3         1         1
    4        31        31
    5        31        31
    6         1         1
    7        31        31
=========================================================================

现在请教如下问题:
1、这个文本文件最终会有数百兆大小,会往里面写入数千的数据段,我想一次一次的实时得到每一个数据段的最后几行,如何实时监控这个TXT文件?不得缺少或重复得到。
2、如何操作才不影响原应用程序的运行,也就是说一定运行的要快,且占用内存要少。

附:最终生成的文本文件。(释放后大约150兆,100多万行,6~7百多个数据段),这还是截取了原文件的1/3,原文件压缩后十几兆,无法上传。

敬请版主和大神务必给予帮助。
附件: 游客没有浏览附件的权限,请 登录注册
搜索更多相关主题的帖子: 文本文件 实时 操作 写入 数据 
2019-07-20 16:45
风吹过b
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:282
帖 子:4609
专家分:28629
注 册:2008-10-15
收藏
得分:5 
提一个思路吧!

1、文件修改,可以使用 文件监控功能。详细自己百度。也可以自己开定时器,读文件大小来判断是否被修改了。建议监控。
2、文件读取的问题。  VB读文件就是慢。
   文件打开,使用 二进制模式,并且只使用只读模式来打开。不知道这种打开文件时,其他程序能否写入数据。
   因你文件前面是不会修改的,每次都是追加。

   定义读取用的变量, 如 A(4095) as byte   一次读4K
   打开文件(二进制,只读)
   Get #1,i*4096-1 , a
   然后对 数据进行分析,发现 chr(13)+chr(10) vbcrlf ,表示前面数据是一行。然后把前面的数据截取下来,处理。
   最后一段数据,附加到下一次的处理的第一段字符串的前面。
每次文件处理完成后,保存处理到的位置,下一次发现文件被修改后,从上一次的位置开始读取。

我不知道顺序文件的读取功能会不会造成文件锁定,如果顺序文件读取时,文件还能被其他程序写入,那也可以使用顺序文件来处理,但这个位置就不好处理了,每次都要从头读取。
而使用二进制文件,可以指定起始位置。

如果都卡在文件被锁定,无法写入数据,那你只有一个办法,每次发现文件被修改,把文件复制一份吧!
复制方式,第一次,使用 文件复制方法,第二次,自己定义复制,使用二进制文件打开,从上次复制文件结束后的位置开始复制,然后接着上一次的文件写入。这样耗时应该更短。

都复制都无法完整复制,那就只能上 1、虚拟内存盘,那个软件或文件想办法放到里面去。 2、上高速SSD。 3、使用C++开发,尽可能的提升读盘效率。



授人于鱼,不如授人于渔
早已停用QQ了
2019-07-20 20:34
wufuzhang
Rank: 9Rank: 9Rank: 9
来 自:广州
等 级:贵宾
威 望:21
帖 子:205
专家分:1341
注 册:2017-8-9
收藏
得分:5 
回复 楼主 ictest
我测试了一下,直接读取最后一个字段的数据,耗时4.4秒,估计不能满足你的要求。


程序代码:
Option Explicit

Private Declare Function timeGetTime Lib "winmm.dll" () As Long

Private Sub Command1_Click()
  Dim str As String
  Dim i As Long
  Dim t1, t2
  
  Open App.Path & "\1.txt" For Input As #1
  t1 = timeGetTime
  For i = 1 To 1077403
      Line Input #1, str
      If i > 1077381 Then
         Print str
      End If
  Next
  Close #1
  t2 = timeGetTime
  Print "耗时" & (t2 - t1) / 1000 & ""
End Sub


附件: 游客没有浏览附件的权限,请 登录注册

不经历千百遍的调试,怎能体会成功时那一刹那的喜悦。
2019-07-20 20:49
xuminxz
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:22
帖 子:480
专家分:1462
注 册:2011-5-8
收藏
得分:5 
每次建立一个新文本文件,建立新文件前将原文本文件数据写入数据库中。如要以文本文件的形式,查看全部或某一时段的数据;可将相应数据读出写入到文本文件中。

dBase有人接盘了。
2019-07-21 08:57
ictest
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:280
专家分:114
注 册:2010-2-17
收藏
得分:0 
感觉这个问题实现有些困难,我想换一个思路。
这台计算机是通过PCI的GPIB卡与另一台设备连接,它们之间有数据通讯。当然数据没那么多,我想获取由这台计算机(也就是本机)发送的GPIB信号,如何获取呢?
从来没搞过这种硬件性质的,能给段类似这个功能的源文件学习学习吗?
2019-07-22 13:02
风吹过b
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:282
帖 子:4609
专家分:28629
注 册:2008-10-15
收藏
得分:0 
程序代码:
Dim filename As String
Dim path As String
Dim jg() As String         '结果数组
Dim jgj As Long

Dim RFWz As Long         '文件读取的位置

Const SS = " Site Failed tests/Executed tests"
Const SE = "========================================================================="

Const 分段大小 = 4096       '4k

Private Sub readfile()
Dim fs As Long
Dim fr As Long
fr = FreeFile()

Dim b  As String * 分段大小        '读出来的字串
Dim fj() As String      '分解数据
Dim sqc As String       '前一次的数据
Dim i As Long           '循环变量
Dim jjg As Boolean      '是否记录内容

If RFWz = 0 Then RFWz = 1
Open path & filename For Binary Access Read As #fr
fs = LOF(fr)
Do While RFWz < fs

    Get #fr, RFWz, b                '不足的部分不会读。因是按 vbcrlf 分段,所以不影响最终结果
    RFWz = Seek(fr)
   
    fj = Split(b, vbCrLf)
    fj(0) = sqc & fj(0)
    For i = 0 To UBound(fj)
        If fj(i) = SS Then
            jjg = True
            jgj = jgj + 1
            ReDim Preserve jg(jgj)
        End If
        If jjg Then
            jg(jgj) = jg(jgj) & vbCrLf & fj(i)
        End If
        If fj(i) = SE Then
            jjg = False
        End If
    Next i
Loop
Close #1
End Sub




Private Sub Command1_Click()

Dim t1 As Date
Dim t2 As Date
Dim t3 As Date

Label2.Caption = ""
Label3.Caption = ""
t1 = Now()
Label1.Caption = t1
DoEvents
Call readfile
Text1.Text = jg(jgj)
t2 = Now()
Label2.Caption = t2
t3 = t2 - t1
Label3.Caption = t3

End Sub

Private Sub Form_Load()
path = App.path
If Right(path, 1) <> "\" Then
    path = path & "\"
End If
filename = "1.txt"
'Erase jg
jgj = 0
End Sub


--------------------------------
测试运行时间,约4秒,没去计算具体的时间
但在读文件的过程中,后台可以继续写这个文件,新增部分不会被读取到。估计与VB打开文件后,在缓冲区写了文件大小有关。
我测试时,使用 copy 命令直接再复制一份,不影响当前打开的文件执行。

然后我的程序里,随着文件增大,如果没有退出程序,就会从新增部分直接开始读,已读过了的部分不会再读了。
所以每增加一份(139M),继续运行读盘时间也约是 4秒 。

你这一个文件里包含了 944 节的内容,我这个代码会把这 944节的每节最后汇总起来。
---------------------
如果你系统每次写盘间隔在 5秒以上,那么可以这样读。


授人于鱼,不如授人于渔
早已停用QQ了
2019-07-22 13:47
快速回复:请教如何对文本文件的实时监控与操作
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.073969 second(s), 9 queries.
Copyright©2004-2020, BCCN.NET, All Rights Reserved