- 浏览: 3049191 次
- 性别:
- 来自: 海外
文章分类
- 全部博客 (430)
- Programming Languages (23)
- Compiler (20)
- Virtual Machine (57)
- Garbage Collection (4)
- HotSpot VM (26)
- Mono (2)
- SSCLI Rotor (1)
- Harmony (0)
- DLR (19)
- Ruby (28)
- C# (38)
- F# (3)
- Haskell (0)
- Scheme (1)
- Regular Expression (5)
- Python (4)
- ECMAScript (2)
- JavaScript (18)
- ActionScript (7)
- Squirrel (2)
- C (6)
- C++ (10)
- D (2)
- .NET (13)
- Java (86)
- Scala (1)
- Groovy (3)
- Optimization (6)
- Data Structure and Algorithm (3)
- Books (4)
- WPF (1)
- Game Engines (7)
- 吉里吉里 (12)
- UML (1)
- Reverse Engineering (11)
- NSIS (4)
- Utilities (3)
- Design Patterns (1)
- Visual Studio (9)
- Windows 7 (3)
- x86 Assembler (1)
- Android (2)
- School Assignment / Test (6)
- Anti-virus (1)
- REST (1)
- Profiling (1)
- misc (39)
- NetOA (12)
- rant (6)
- anime (5)
- Links (12)
- CLR (7)
- GC (1)
- OpenJDK (2)
- JVM (4)
- KVM (0)
- Rhino (1)
- LINQ (2)
- JScript (0)
- Nashorn (0)
- Dalvik (1)
- DTrace (0)
- LLVM (0)
- MSIL (0)
最新评论
-
mldxs:
虽然很多还是看不懂,写的很好!
虚拟机随谈(一):解释器,树遍历解释器,基于栈与基于寄存器,大杂烩 -
HanyuKing:
Java的多维数组 -
funnyone:
Java 8的default method与method resolution -
ljs_nogard:
Xamarin workbook - .Net Core 中不 ...
LINQ的恶搞…… -
txm119161336:
allocatestlye1 顺序为 // Fields o ...
最近做的两次Java/JVM分享的概要
上周回了一趟老家,没网上,只好做些不用上线的事。正好找了点时间来写合并MSN(Windows Live Messenger)的聊天记录的脚本。
MSN的聊天记录以XML文件的形式保存,默认保存在%My Documents%\My Received Files\username\History里。中文系统的话是默认保存在%我的文档%\我接受到的文件\username\历史记录里。保存路径可以在登录MSN后设置。
一般我在同一台机器上重装系统的话,会把聊天记录的目录转移到新装的系统上。但是我也经常要用不同的机器,偶尔也需要在不是我的机器上登录MSN。这么一来,聊天记录就散得到处都是了。每次整理数据的时候都想解决一下这个问题,不过每次都是懒了……
既然是XML,处理起来应该是非常方便的——不用自己从lexer和parser开始写解析用的程序。那么来看看一个MSN的聊天记录文件大概长什么样:
可以看到该文件引用了一个XSLT文件来做渲染。事实上在MSN里浏览聊天记录的时候显示的就是通过该XSLT转换过的XML记录。
这个XML文件的根节点是Log,属性包括FirstSessionID和LastSessionID两个。Log下面的子节点主要是一个或多个Message节点,其中的Session属性表示会话序号,前面提到根节点的两个属性对应文件中所有Session值的状况;也可能存在另外两种节点,下文会提到。
合并记录的关键就在于那些Session值,其它内容都不用修改,直接复制过来就行。脚本应该根据日期正确的把聊天记录按顺序排起来,并重新计算各个Message(和另外两种节点)中的Session值,然后更新Log的FirstSessionID/LastSessionID,最后写出文件。
用Ruby来处理XML文件,我还是习惯性选择用Nokogiri来做。这里用的版本是Nokogiri 1.2.3。通过Nokogiri.parse得到一个Document对象doc后,通过doc/'Log/Message'就可以得到根节点下的所有Message节点了。我以为根节点下只有Message节点,试着写了个实验用脚本,发现合并了之后结果居然比其中一个源还要小,肯定出问题了。
于是就另外写了个脚本来看聊天记录的XML文件里根节点下到底有哪些类型的节点:
extract_node_names.rb:
对某个文件运行该脚本,结果是:
原来除了Message节点外还有Invitation和InvitationResponse两种节点,对应传输文件的信息。或许我还没碰到所有类型的节点……不过只要这些节点有Session和DateTime属性就能用同样的方式去处理,所以倒不用怎么担心。
OK,那就写个简单的脚本来解决这个合并记录的问题:
cat_msn_logs.rb:
(__END__之后的是我用来提醒自己用的东西……请忽略)
我用的Nokogiri 1.2.3看来在包装libxml2的时候什么地方没弄好,我一开始试的时候只要多处理几个XML文件就会出现segfault。我觉得很纳闷,想了些办法后发现是GC过后就出问题。于是干脆暂时把GC禁用掉,那样segfault只会出现在所有XML文件都处理完了之后,也就不影响使用了。我一直怀疑我是不是有什么该调用的清理用方法没调用导致segfault,hmm
除了Nokogiri带来的问题外,在实际使用过程中还发现了一个问题:
我一直以为这些聊天记录的XML文件中Log的FirstSessionID总是1,而LastSessionID跟文件中出现的Session数一样。后来发现原来MSN会在文件超过2MB后开新的文件,并把原来的文件重命名为“original_filename_without_extension - ArchiveYYYYMMDD.xml”的形式。这样,新开的XML文件中FirstSessionID就不是从1开始了。很不幸我的记录里有一个同学的记录就超过了2M,害我手动处理了 = =
我觉得处理新开文件的情况挺麻烦的。首先我得把Archive文件和当前文件中的内容合并到一起,再跟另外一边的源合并到一起。然后要模仿MSN的做法,在写出的时候记录是否达到了2MB,达到则新开个文件继续写。但是怎么记录已写出的文件大小呢?难道我要在重新计算好各节点的Session值之后,添加回到根节点时对每个节点调用Nokogiri::XML::Element#to_s然后数byte数?好烦啊 T T
本来想再把这个问题考虑进去,顺便重构一下再发出来的。想想还是先发个出来收集些建议再修改比较有效率。求改进建议 <(_ _)>
不拆应该不影响MSN的正常使用,但是超过1M的记录直接用浏览器打开的时候就已经很卡了(例如说通过IE调用MSXML来打开,它会自动处理XSLT,所以能正常显示出来;FF之类的也行)。所以我还是想按照MSN的方式来拆分,不想留下合并的痕迹。
先输出大文件再拆,但是“再拆”的时候还是得把文件读进来,解析XML,然后再来……还是回到起点了啊。关键是MSN在拆分聊天记录的时候是不会在Session的中间断开的,这是因为它是在写新记录的时候读以前的记录,发现那个文件超过2MB了就开新文件;而以前的记录肯定是以某个完整的Session结束的(一关闭聊天窗口就保存了一次,也就结束了一个Session)。我还是得想办法以Session为单位获取输出的文本的大小才行
这么说 msn 认识巨大的聊天记录喽? 那不用拆了 ……
就等着你来救火啊~~
我得看看Nokogiri有没有更新过,试试新版本会不会还segfault。会的话看来得动手弄个patch了 = =
先输出大文件再拆,但是“再拆”的时候还是得把文件读进来,解析XML,然后再来……还是回到起点了啊。关键是MSN在拆分聊天记录的时候是不会在Session的中间断开的,这是因为它是在写新记录的时候读以前的记录,发现那个文件超过2MB了就开新文件;而以前的记录肯定是以某个完整的Session结束的(一关闭聊天窗口就保存了一次,也就结束了一个Session)。我还是得想办法以Session为单位获取输出的文本的大小才行
MSN的聊天记录以XML文件的形式保存,默认保存在%My Documents%\My Received Files\username\History里。中文系统的话是默认保存在%我的文档%\我接受到的文件\username\历史记录里。保存路径可以在登录MSN后设置。
一般我在同一台机器上重装系统的话,会把聊天记录的目录转移到新装的系统上。但是我也经常要用不同的机器,偶尔也需要在不是我的机器上登录MSN。这么一来,聊天记录就散得到处都是了。每次整理数据的时候都想解决一下这个问题,不过每次都是懒了……
既然是XML,处理起来应该是非常方便的——不用自己从lexer和parser开始写解析用的程序。那么来看看一个MSN的聊天记录文件大概长什么样:
<?xml version="1.0"?> <?xml-stylesheet type='text/xsl' href='MessageLog.xsl'?> <Log FirstSessionID="1" LastSessionID="1"><Message Date="5/31/2009" Time="7:50:34 AM" DateTime="2009-05-30T23:50:34.699Z" SessionID="1"><From><User FriendlyName="三工"/></From><To><User FriendlyName="Ravenex"/></To><Text Style="color:windowtext; ">http://www.engadget.com/2009/05/30/sonys-psp-go-leaks-out-before-e3-is-obviously-a-go/</Text></Message></Log>
可以看到该文件引用了一个XSLT文件来做渲染。事实上在MSN里浏览聊天记录的时候显示的就是通过该XSLT转换过的XML记录。
这个XML文件的根节点是Log,属性包括FirstSessionID和LastSessionID两个。Log下面的子节点主要是一个或多个Message节点,其中的Session属性表示会话序号,前面提到根节点的两个属性对应文件中所有Session值的状况;也可能存在另外两种节点,下文会提到。
合并记录的关键就在于那些Session值,其它内容都不用修改,直接复制过来就行。脚本应该根据日期正确的把聊天记录按顺序排起来,并重新计算各个Message(和另外两种节点)中的Session值,然后更新Log的FirstSessionID/LastSessionID,最后写出文件。
用Ruby来处理XML文件,我还是习惯性选择用Nokogiri来做。这里用的版本是Nokogiri 1.2.3。通过Nokogiri.parse得到一个Document对象doc后,通过doc/'Log/Message'就可以得到根节点下的所有Message节点了。我以为根节点下只有Message节点,试着写了个实验用脚本,发现合并了之后结果居然比其中一个源还要小,肯定出问题了。
于是就另外写了个脚本来看聊天记录的XML文件里根节点下到底有哪些类型的节点:
extract_node_names.rb:
require 'rubygems' require 'nokogiri' fname = ARGV[0] doc = Nokogiri.parse File.read(fname) log = doc.root children = log.children names = children.inject({}) do |acc, e| n = e.node_name acc[n] ||= e acc end p names.keys puts names.keys.each do |k| puts "#{k}:" puts names[k].to_xml('gbk'), '' end
对某个文件运行该脚本,结果是:
["Message", "Invitation", "InvitationResponse"] Message: <Message Date="7/14/2009" Time="9:23:10 PM" DateTime="2009-07-14T13:23:10.898Z" SessionID="1"> <From> <User FriendlyName="Hg"/> </From> <To> <User FriendlyName="RednaxelaFX"/> </To> <Text Style="font-family:Segoe UI; color:#000000; ">现在有验证机制了么</Text> </Message> Invitation: <Invitation Date="7/14/2009" Time="9:43:34 PM" DateTime="2009-07-14T13:43:34.678 Z" SessionID="1"> <From> <User FriendlyName="RednaxelaFX"/> </From> <File>C:\Documents and Settings\RednaxelaFX\Desktop\amazon090714.txt</File> <Text Style="color:#545454; ">RednaxelaFX sends C:\Documents and Settings\RednaxelaFX\Desktop\New File.txt</Text> </Invitation> InvitationResponse: <InvitationResponse Date="7/14/2009" Time="9:43:49 PM" DateTime="2009-07-14T13:4 3:49.529Z" SessionID="1"> <From> <User FriendlyName="Hg"/> </From> <File>C:\Documents and Settings\RednaxelaFX\Desktop\amazon090714.txt</File> <Text Style="color:#545454; ">Transfer of "New File.txt" is complete.</Text> </InvitationResponse>
原来除了Message节点外还有Invitation和InvitationResponse两种节点,对应传输文件的信息。或许我还没碰到所有类型的节点……不过只要这些节点有Session和DateTime属性就能用同样的方式去处理,所以倒不用怎么担心。
OK,那就写个简单的脚本来解决这个合并记录的问题:
cat_msn_logs.rb:
require 'rubygems' require 'nokogiri' require 'fileutils' # Convert a Nokogiri::XML::Document into # an array of arrays, grouped by SessionID. # The inner arrays begin with the DateTime of # their first Element, used later for sorting. def group_log_by_sid(xml_log) xml_log.root.children.inject({}) {|acc, node| sid = node['SessionID'] (acc[sid] ||= [ DateTime.parse(node['DateTime']) ]) << node acc }.values end # Join two arrays of Element groups into one, # sorted by DateTime, and removing redundant # entries. def join_groups(grp1, grp2) groups = (grp1 + grp2). sort_by {|g| g[0] }. inject([]) {|acc, g| (acc.empty? || acc.last[0] != g[0]) ? acc << g : acc }. map {|g| g.shift; g } # fix SessionIDs groups.each_with_index do |grp, idx| sid = (idx + 1).to_s grp.each {|n| n['SessionID'] = sid } end end # Save a Nokogiri::XML::Document to file, # with no formatting, and UTF-8 encoding. def save_log(xml_log, fpath) File.open(fpath, 'w') do |f| # need to pass in save_options to # strip excessive whitespace/formatting xml_log.write_to( f, # io 'utf-8', # encoding Nokogiri::XML::Node::SaveOptions::AS_XML) end end # Join the two designated MSN logs into one. def join_logs(fname, src_dir1, src_dir2, dest_dir) log1, log2 = [ src_dir1, src_dir2 ].map do |d| File.open(File.join(d, fname), 'r') do |f| Nokogiri.parse f end end nodes = join_groups(*( [ log1, log2 ].map {|log| group_log_by_sid log })) root = log1.root root['FirstSessionID'] = '1' root['LastSessionID'] = nodes.length.to_s root.inner_html = '' nodes.flatten.each {|n| root.add_child n } save_log log1, File.join(dest_dir, fname) end # command-line arguments: # src_dir1, # src_dir2, # dest_dir (optional, defaults to src_dir1) # # variables to keep track of: # src_dir1 : String # src_dir2 : String # dest_dir : String # fname : String if __FILE__ == $0 src_dir1, src_dir2, dest_dir = ARGV.map {|p| File.expand_path p } dest_dir ||= src_dir1 FileUtils.makedirs dest_dir # check if files with the same name exist in both dirs, src_entries1, src_entries2 = [ src_dir1, src_dir2 ].map do |d| Dir.entries(d).grep(/\.xml/i) end in_both_dirs = src_entries1 & src_entries2 [ [ src_dir1, src_entries1 ], [ src_dir2, src_entries2 ] ].each do |g| src_dir = g[0] entries = g[1] unless src_dir.downcase == dest_dir.downcase (entries - in_both_dirs).each do |f| FileUtils.copy_file( File.join(src_dir, f), # src File.join(dest_dir, f), # dest true # preserve ) end end end # disable GC due to memory leak issues in Nokogiri GC.start GC.disable # otherwise, join the logs in_both_dirs.each do |f| print "processing #{f}..." join_logs f, src_dir1, src_dir2, dest_dir puts 'ok' end #GC.enable end __END__ # the following code may be used later in refactoring # not used... #~ def read_xml_file(fpath) #~ Nokogiri.parse File.read(fpath) #~ end # not used... #~ def log_session_range(xml_log) #~ root = xml_log.root #~ root['FirstSessionID'].to_i..root['LastSessionID'].to_i #~ end # not used... #~ def node_sid(xml_node) #~ xml_node['SessionID'].to_i #~ end # not used... #~ def set_node_sid(xml_node, sid) #~ xml_node['SessionID'] = sid.to_s #~ end # not used... #~ def node_datetime(xml_node) #~ DateTime.parse xml_node['DateTime'] #~ end edge cases not handled: / - Archive(\d{8})\.xml/
(__END__之后的是我用来提醒自己用的东西……请忽略)
我用的Nokogiri 1.2.3看来在包装libxml2的时候什么地方没弄好,我一开始试的时候只要多处理几个XML文件就会出现segfault。我觉得很纳闷,想了些办法后发现是GC过后就出问题。于是干脆暂时把GC禁用掉,那样segfault只会出现在所有XML文件都处理完了之后,也就不影响使用了。我一直怀疑我是不是有什么该调用的清理用方法没调用导致segfault,hmm
除了Nokogiri带来的问题外,在实际使用过程中还发现了一个问题:
我一直以为这些聊天记录的XML文件中Log的FirstSessionID总是1,而LastSessionID跟文件中出现的Session数一样。后来发现原来MSN会在文件超过2MB后开新的文件,并把原来的文件重命名为“original_filename_without_extension - ArchiveYYYYMMDD.xml”的形式。这样,新开的XML文件中FirstSessionID就不是从1开始了。很不幸我的记录里有一个同学的记录就超过了2M,害我手动处理了 = =
我觉得处理新开文件的情况挺麻烦的。首先我得把Archive文件和当前文件中的内容合并到一起,再跟另外一边的源合并到一起。然后要模仿MSN的做法,在写出的时候记录是否达到了2MB,达到则新开个文件继续写。但是怎么记录已写出的文件大小呢?难道我要在重新计算好各节点的Session值之后,添加回到根节点时对每个节点调用Nokogiri::XML::Element#to_s然后数byte数?好烦啊 T T
本来想再把这个问题考虑进去,顺便重构一下再发出来的。想想还是先发个出来收集些建议再修改比较有效率。求改进建议 <(_ _)>
评论
6 楼
RednaxelaFX
2009-08-14
升级到Nokogiri 1.3.3之后更糟糕了……在Windows上用Nokogiri难道就是个错误么 T T
换回Hpricot再试……
换回Hpricot再试……
5 楼
RednaxelaFX
2009-08-14
night_stalker 写道
这么说 msn 认识巨大的聊天记录喽? 那不用拆了 ……
不拆应该不影响MSN的正常使用,但是超过1M的记录直接用浏览器打开的时候就已经很卡了(例如说通过IE调用MSXML来打开,它会自动处理XSLT,所以能正常显示出来;FF之类的也行)。所以我还是想按照MSN的方式来拆分,不想留下合并的痕迹。
4 楼
night_stalker
2009-08-14
RednaxelaFX 写道
先输出大文件再拆,但是“再拆”的时候还是得把文件读进来,解析XML,然后再来……还是回到起点了啊。关键是MSN在拆分聊天记录的时候是不会在Session的中间断开的,这是因为它是在写新记录的时候读以前的记录,发现那个文件超过2MB了就开新文件;而以前的记录肯定是以某个完整的Session结束的(一关闭聊天窗口就保存了一次,也就结束了一个Session)。我还是得想办法以Session为单位获取输出的文本的大小才行
这么说 msn 认识巨大的聊天记录喽? 那不用拆了 ……
3 楼
RednaxelaFX
2009-08-14
night_stalker 写道
前天我写的扩展也碰到一个莫名其妙的 segfault,一 puts 就 segfault,不 puts 就很正常。最后才发现是 GC 的问题: 在扩展中创建了 ruby 对象,但是忘记 mark 了,puts 正好触发 GC,就挂了 …… 后来添加了一个 mark 就没事了。
我觉得问题应该不难 …… 先输出一个大文件,再写个脚本拆。
我觉得问题应该不难 …… 先输出一个大文件,再写个脚本拆。
就等着你来救火啊~~
我得看看Nokogiri有没有更新过,试试新版本会不会还segfault。会的话看来得动手弄个patch了 = =
先输出大文件再拆,但是“再拆”的时候还是得把文件读进来,解析XML,然后再来……还是回到起点了啊。关键是MSN在拆分聊天记录的时候是不会在Session的中间断开的,这是因为它是在写新记录的时候读以前的记录,发现那个文件超过2MB了就开新文件;而以前的记录肯定是以某个完整的Session结束的(一关闭聊天窗口就保存了一次,也就结束了一个Session)。我还是得想办法以Session为单位获取输出的文本的大小才行
2 楼
night_stalker
2009-08-14
前天我写的扩展也碰到一个莫名其妙的 segfault,一 puts 就 segfault,不 puts 就很正常。最后才发现是 GC 的问题: 在扩展中创建了 ruby 对象,但是忘记 mark 了,puts 正好触发 GC,就挂了 …… 后来添加了一个 mark 就没事了。
我觉得问题应该不难 …… 先输出一个大文件,再写个脚本拆。
我觉得问题应该不难 …… 先输出一个大文件,再写个脚本拆。
1 楼
lwwin
2009-08-14
2M 说明你们聊得很凶^^~
发表评论
-
字符串的一般封装方式的内存布局 (0): 拿在手上的是什么
2013-11-04 18:22 21495(Disclaimer:未经许可请 ... -
字符串的一般封装方式的内存布局
2013-11-01 12:55 0(Disclaimer:未经许可请 ... -
RubyConf notes
2011-11-08 19:10 0symmetric coroutine Fiber#trans ... -
ShanghaiOnRails第八次线下活动——你不需要知道的Ruby实现
2010-11-12 15:39 2843上个月底正好赶上参加了ShanghaiOnRails 第八次线 ... -
JRuby的运行模式
2010-11-01 11:21 0// 老的JRuby还是用org.jruby.evaluato ... -
你不需要知道的Ruby草稿
2010-10-27 11:25 0一些Ruby实现 Ruby 1.8 树遍历解释 Ruby 1 ... -
Ruby里的fiber/coroutine例子
2010-01-26 18:33 0Ruby 1.9开始支持fiber。与“fiber”一词的一般 ... -
JRuby使用技巧收集
2009-12-28 09:35 0java.lang.Thread.new { puts &qu ... -
特殊类型的eigenclass
2009-12-17 03:39 0Fixnum的实例没有eigenclass true、fals ... -
奇怪的参数
2009-12-08 02:25 0默认参数与闭包的组合 真正的问题不是只是默认参数看起来很诡异, ... -
MacRuby的执行模式
2009-12-07 07:41 0mailing-list macruby-devel http ... -
Rubinius的执行模型
2009-12-05 15:22 0Rubinius wants to help YOU make ... -
Ruby 1.8和1.9中String#hash的实现
2009-11-22 18:23 01.8 string.c int rb_str_hash(s ... -
To囧:拿你来测测Watir...
2009-11-21 22:38 3443iaimstar 写道@RednaxelaFX 你最近ruby ... -
[标题党] MagLev中GC类的真相……
2009-11-21 14:46 0注意到本文的标题:我是说“GC类”的真相,不是说GC的真相哦~ ... -
小试rubyzip的一个脚本
2009-11-17 20:42 3458呼,今天开始3天都是新人培训,总算可以抽点时间发一帖。 现在在 ... -
爬一下Google和百度看口碑对它们做的SEO效果如何
2009-11-09 00:27 0#!/usr/bin/env ruby require ... -
把Mechanize的html_parser改回到Hpricot
2009-11-08 14:45 3116记得我最初开始用Nokogir ... -
使用新的RubyInstaller
2009-11-07 02:37 0Hpricot的安装需要编译,需要devkit -
Ruby metaprogramming tech notes
2009-09-28 15:39 0class Builder def self.build ...
相关推荐
arcmap-数据处理-批量合并GDB的python脚本
通过“SQL脚本文件合并工具”,我们可以将分散的SQL脚本整合到一起,形成一个大的SQL脚本文件,这样在SQL*Plus中只需要运行一次,就能完成所有脚本的执行,避免了反复打开、执行单个文件的繁琐步骤。 合并过程可能...
然后,运行“001合并.bat”脚本,根据脚本的提示或者“合并缓存视频注意事项.txt”中的说明进行操作。在脚本执行完成后,将得到一个完整的MP4视频文件,可直接播放。 总的来说,这个压缩包提供了一个便捷的工具,...
利于将多个分散的sal脚本合并为一个sql文件。
聊天记录查看工具是此脚本的另一个亮点。它允许用户查看微信聊天记录,包括文本、语音消息、图片等多元化的通信内容。这可能通过解析SQLite数据库中的消息记录表实现,将数据结构化后展示出来。值得注意的是,它还...
标题中的"SQL脚本文件合并工具.zip"表明这是一个压缩文件,里面包含了一个名为"SQL脚本文件合并工具.exe"的应用程序。这个.exe文件是Windows操作系统下的可执行文件,用户可以通过双击运行它来执行SQL脚本的合并任务...
【压缩包子文件的文件名称列表】: "B站视频合并脚本"表明压缩包中只有一个文件,那就是合并脚本本身。这可能是一个文本文件,如.sh (bash脚本) 或.py (Python脚本),需要在终端或命令行环境中运行。运行前,用户需要...
本示例提供的`merge_test.rar`压缩包包含了一个自动合并`boot.bin`和`app.bin`的批处理脚本(`.bat`文件),这对于开发和调试过程中的固件打包非常有用。这个脚本不仅能够将两个二进制文件合并,还能够追加版本号,...
脚本可能需要读取预设的聊天模板或随机生成消息,然后在聊天窗口中输入并发送。这需要理解应用的UI结构,定位到输入框和发送按钮,并利用AutoJS的文本操作API来完成。 **5. UI元素识别** AutoJS使用UIAutomator库来...
在这个场景中,我们主要关注的是如何使用shell脚本处理QQ聊天记录,将其按照不同的QQ号码分开存储,并实现倒序排列。这涉及到Linux shell脚本编程的一些核心概念和技术,下面将详细介绍。 首先,让我们了解什么是...
- 调整HTML中的引用,使其指向合并后的资源和脚本。 - 如果有Mobile特有的配置或代码,可以通过条件判断来决定在Web或Mobile环境下执行哪部分代码。 3. **优化和适配**: 合并后,为了确保在不同设备上的兼容性...
文件合并脚本 python 文件合并脚本 python
用户可能需要在MySQL数据库中运行这些脚本来准备聊天记录的存储环境。 总的来说,这个Openfire聊天记录插件是一个实用的工具,能够帮助用户保存和管理他们的聊天对话,无论是私人的一对一交流还是多人的群组讨论。...
此VBA脚本主要用于Excel工作表中实现跨页数据的合并操作。在处理包含多页的数据时,经常会遇到需要将某些单元格(尤其是标题行)跨页合并的情况,以保持报表或表格的清晰性和可读性。该脚本通过遍历每一页的页眉...
"WINCC中使用C脚本获得操作记录的方法" WINCC是一种工业自动化软件,能够帮助用户实时监控和控制工业过程。然而,在某些情况下,用户需要记录操作员的操作,以便进行事故分析或性能优化。这时,WINCC提供了一些对象...
本教程将详细介绍如何通过三种不同的方法合并Hex文件,并利用批处理脚本(BAT)来自动化这个过程。 1. **简单复制合并**: 这种方法是最直观的,适用于不关心数据重叠的情况。你只需将一个Hex文件的内容追加到另一...
从macOS上的WeChat提取聊天记录的脚本macOS的WeChat Deciphers此工具包包含三个DTrace脚本,用于与macOS上的WeChat.app混淆。 eavesdropper.d实时记录对话。 这显示了所有要保存到数据库的内容。 dbcracker.d揭示了...
本压缩包中的资源,名为"将所在目录的BAT文件合并成一个BAT文件,通过选择运行其中之一.bat",正是这样一个批处理脚本,它的目的是将当前目录下的所有BAT文件整合到一个单一的批处理文件中,用户可以通过这个新生成...
7、实现查看相应的聊天室聊天记录功能 8、实现各终端实时同步聊天消息功能(就像QQ群、微信群) 9、实现多终端同时登录、加入聊天室功能,理论上终端数量没有上限 这是一个shell脚本编码学习项目,没有什么实际用途...
### Excel 文件与工作表合并脚本知识点解析 #### 脚本概述 此脚本主要实现了Excel文件及其内部工作表的合并功能。整个脚本由三个部分组成:`SubMergeWorkbooks`(用于合并多个Excel文件)、`FunctionLastRow`(获取...