python共享内存mmap,
背景:通常,在UNIX下使用诸如sed和awk之类的shell命令来处理文本文件。对于处理大文件,CPU、IO等因素影响服务器,也给服务器造成一定压力。对于sed的解释,我们可以看到sed是如何工作的。本文将介绍如何通过python的mmap模块处理大文件,并比较它们的区别。
注:mmap是一种在虚拟内存中映射文件的方法,即把文件或其他对象映射到一个进程的地址空间,在一个进程的虚拟地址空间中实现文件磁盘地址与一个虚拟地址的映射关系。系统中mmap的理论解释可以在百度维基百科和维基百科找到,还有mmap功能的介绍。这里的解释是针对Python中mmap模块的使用。
使用:1、创建:创建并返回一个mmap对象m。
M=mmap.mmap (fileno,length [,flags [,prot [,access [,offset]])fileno:文件描述符,可以是file对象的FileNo()方法,也可以来自os.open()。在调用mmap()之前打开文件,当不再需要它时关闭它。
Os。O _ RDONLY以只读方式打开只读。
Os。O_WRONLY以只写方式打开只写。
Os。O_RDWR以读写方式打开读写。
Os。O_APPEND作为APPEND打开。
Os。创建并打开一个新文件
如果指定的文件存在,Os.o _ exclos.o _ create OS.o _ excl返回一个错误。
Os。O_TRUNC打开一个文件,并截断其长度为零(必须有写权限)
Os。O_BINARY以二进制模式打开文件(不转换)
Os。O_NOINHERIT阻止创建共享文件描述符。
os。短暂的
Os。用o _ create创建临时文件。
Os。O_RANDOM缓存被优化,但是从磁盘的随机访问不受限制。
Os。O_SEQUENTIAL cache优化,但对磁盘的顺序访问没有限制
Os。O_TEXT将文件作为文本(转换)视图代码打开。
Length:映射文件部分的大小(以字节为单位),如果该值为0,则映射整个文件,如果该大小大于文件的当前大小,则文件将被扩展。
Flags: map _ private:这个内存映射只对这个进程可用;Mmap。MAP_SHARED:与其他进程共享内存映射,映射到同一个文件的所有进程都可以看到其中一个进程所做的更改;
Prot: mmap.prot _ read,mmap.prot _ write和mmap。PROT _写 mmap。PROT_READ最后一个意思是同时读和写。
access:mmap中有可选参数。访问的价值是
ACCESS_READ:读取权限。
ACCESS_WRITE:写权限,默认。
ACCESS_COPY:复制访问,更改不会写入文件。使用flush将更改写入文件。
2.方法:mmap对象的方法,对象m。
m.close()
关闭m对应的文件;
m.find(str,start=0)
从起始下标开始,在M中从左到右寻找子串str的最早下标;
m.flush([offset,n])
将M中偏移量的n个字节刷到相应的文件中;
m.move(dstoff,srcoff,n)
等于m[dstoff:dst off n]=m[srcoff:Sr coff n],从Sr coff复制n个字节到dst off复制n个字节可能会覆盖重叠部分。
阅读硕士
返回一个字符串,从M对应的文件中最多读取N个字节,将M对应的文件的位置指针后移;
m .读取字节()
返回一个1字节的字符串,从M对应的文件中读取1个字节,抛出异常ValueError如果在到达EOF时调用read _ byte();
m.readline()
返回从对应于M的文件的当前位置到下一个 \n 的字符串,如果调用readline()时文件在EOF中,则返回空字符串。
M.resize(n) ***有问题,所以无法执行***
将M的长度改为N,M的长度与M对应的文件长度无关;
m.seek(位置,方式=0)
对文件对象进行查找操作,以改变对应于m的文件的当前位置;
m.size()
返回m对应的文件长度(不是m对象的len (m)长度);
泰尔先生
m返回相应文件的当前位置;
m.write
将str写到m对应的文件的当前位置,抛出ValueError如果m对应的文件的当前位置到m末尾的剩余空间小于len(str);
m .写入字节(字节)
将1个字节(对应一个字符)写到m对应的文件的当前位置,实际上m.write_byte(ch)等于m.write(ch)。如果m对应的文件的当前位置在m的末尾,即m对应的文件的当前位置到m末尾所剩空间小于1字节,write()抛出异常ValueError,write_byte()不做任何处理。方法使用说明:介绍上面常用的方法。
测试文本:test.txt,mmap对象m
- MySQL dump 10.13发行版5.6.19,适用于osx10.7 (x86_64)
-
-主机:本地主机数据库:测试
- -
-服务器版本5.6.19
/*!40101 SET @ OLD _ CHARACTER _ SET _ CLIENT=@ @ CHARACTER _ SET _ CLIENT */;
/*!40101 SET @ OLD _ CHARACTER _ SET _ RESULTS=@ @ CHARACTER _ SET _ RESULTS */;
/*!40101 SET @ OLD _ COLLATION _ CONNECTION=@ @ COLLATION _ CONNECTION */;
/*!40101集合名称utf8 */;
/*!40103 SET @ OLD _ TIME _ ZONE=@ @ TIME _ ZONE */;
/*!40103 SET TIME _ ZONE= 00:00 */;
/*!40014 SET @ OLD _ UNIQUE _ CHECKS=@ @ UNIQUE _ CHECKS,UNIQUE _ CHECKS=0 */;
/*!40014 SET @ OLD _ FOREIGN _ KEY _ CHECKS=@ @ FOREIGN _ KEY _ CHECKS,FOREIGN _ KEY _ CHECKS=0 */;
/*!40101 SET @ OLD _ SQL _ MODE=@ @ SQL _ MODE,SQL _ MODE= NO _ AUTO _ VALUE _ ON _ ZERO */;
/*!40111 SET @ OLD _ SQL _ NOTES=@ @ SQL _ NOTES,SQL _ NOTES=0 */;查看代码
: m.close()关闭对象。
导入操作系统,mmap
M=mmap.mmap (os.open (test.txt ,os.o _ rdwr),0) #创业内存映射对象,
M.read(10) #可以使用该方法
- MySQL d
M.close() #关闭对象
m.read(10) #方法不可用。
回溯(最近一次呼叫):
模块中文件 stdin 的第1行
错误:mmap关闭或无效: m. find (str,start=0),从起始位置查找第一个str。
M.find(SET ,0) #查找第一个集合从头开始出现的字符串。
17 : m.read (n)返回从m对象文件中读取的n字节的字符串,会将m对象的位置指针后移,后续的读取会继续读下去。
读取一个10字节的字符串
- MySQL d
M.read(10) #读取前10个字节后,接下来的10个字节的数据。
Ump10.13 : m.read _ byte(),返回1字节字符串,从m对应的文件中读取1字节。
读取第一个字节
-
M.read_byte() #读取第二字节
-
M.read_byte() #读取第三字节
: m.readline():返回从m对应的文件当前位置到下一个 \n 的字符串,或者在调用readline()时文件处于EOF时返回空字符串。
M.readline() #读取正线
- MySQL转储10.13发行版5.6.19,适用于osx10.7 (x86_64)\n
M.readline() #读取下一个正行
-\ n : m.size():返回m对应的文件长度(不是m对象的len(m)长度)
M.size() #整个文件的大小
72 : m.tell():返回m对应文件的当前光标位置。
M.tell() #当前光标的位置为0
0
读取10个字节
- MySQL d
M.tell() #当前光标位置10
0 : m. seek (pos,how=0),改变m对应文件的当前位置。
M.seek(10) #当前光标位于10。
M.tell() #读取当前光标位置
10
M.read(10) #读取当前光标后的10字节内容
UMP 10.13 :m . move(dstoff,srcoff,n):等于m[dst off:dst offn]=m[srcoff:Sr coff n],从Sr coff复制n个字节到dst off复制n个字节。
切片101至108的M[101:108] #个值
-
切片1至8的M[1:8] #个值
- MySQL
m .将(1,101,8) #从101移动到后面的8个字节(108),将后面的8个字节(8)从1替换。效果:m[1:8]=m[101:108]
M[1:8] #被替换
--:M . Write(str):将STR写入M对应文件的当前光标位置(覆盖对应长度)。如果从M对应文件的当前光标位置到M末尾的剩余空间小于len(str),则抛出ValueError。
M.tell() #当前光标位置
0
M.write(zhoujy) #写入str,如果写入的大小大于原文件,则报错。M.write_byte(byte)不会报错。M.tell() #写入后光标位置
6.M. seek (0) #复位,光标从头开始。m.read(10) #查看10个字节以确定它是否已被成功修改。
Zhoujy-d: m.flush():将m中偏移量的N个字节刷入相应的文件。
注意:对于m的修改操作,可以当成一个列表进行切片操作,但是对于切片操作的修改需要改成同样长度的字符串,否则都会报错。如m中的10个字符串进行修改,必须改成10个字符的长度。
3,应用说明:
1):读文件,访问_读取
:读取整个文件
#!/usr/bin/python
# -*-编码:utf-8 -*-
导入内存映射
导入上下文库
f=打开( test.txt , r )
使用上下文库。关闭(mmap。mmap(f . fileno(),0,access=mmap .ACCESS_READ))作为男:
#阅读线需要循环才能读取整个文件
虽然正确:
line=m.readline().条状()
打印行
#光标到最后位置(读完),就退出
if m.tell()==m.size():
破裂效果:
~$ python untitled.py 1
-周周转储10.13发行版5.6.19,适用于osx10.7 (x86_64)
-
-主机:本地主机数据库:测试
- -
-服务器版本5.6.19
/*!40101周jy SET @ OLD _ CHARACTER _ SET _ CLIENT=@ @ CHARACTER _ SET _ CLIENT */周jy;
/*!40101 SET @ OLD _ CHARACTER _ SET _ RESULTS=@ @ CHARACTER _ SET _ RESULTS */;
/*!40101 SET @ OLD _ COLLATION _ CONNECTION=@ @ COLLATION _ CONNECTION */;
/*!40101集合名称utf8 */;
/*!40103 SET @ OLD _ TIME _ ZONE=@ @ TIME _ ZONE */;
/*!40103 SET TIME _ ZONE= 00:00 */ZHOUJY;
/*!40014 SET @ OLD _ UNIQUE _ CHECKS=@ @ UNIQUE _ CHECKS,UNIQUE _ CHECKS=0 */;
/*!40014 SET @ OLD _ FOREIGN _ KEY _ CHECKS=@ @ FOREIGN _ KEY _ CHECKS,FOREIGN _ KEY _ CHECKS=0 */;
/*!40101 SET @ OLD _ SQL _ MODE=@ @ SQL _ MODE,SQL _ MODE= NO _ AUTO _ VALUE _ ON _ ZERO */;
/*!40111 SET @ OLD _ SQL _ NOTES=@ @ SQL _ NOTES,SQL _ NOTES=0 */;查看代码
:逐步读取指定字节数文件
#!/usr/bin/python
# -*-编码:utf-8 -*-
导入内存映射
导入上下文库
用打开( test.txt , r )作为女:
使用上下文库。关闭(mmap。mmap(f . fileno(),0,access=mmap .ACCESS_READ))作为男:
打印读取10个字节的字符串:,m.read(10)
打印支持切片,对读取到的字符串进行切片操作:,m[2:10]
打印读取之前光标后的10个字符串,m.read(10)效果:
~$ python untitled.py
读取10个字节的字符串:-周
支持切片,对读取到的字符串进行切片操作:周教育行业标准
读取之前光标后的10个字符串-转储一视图代码
2):查找文件,访问_读取
:从整个文件查找所有匹配的
#!/usr/bin/python
# -*-编码:utf-8 -*-
导入内存映射
导入上下文库
word=ZHOUJY
打印查找:,单词
f=打开( test.txt , r )
使用上下文库。关闭(mmap。mmap(f . fileno(),0,access=mmap .ACCESS_READ))作为男:
#也可以通过查找(字符串,位置)来处理
虽然正确:
line=m.readline().条状()
如果line.find(word)=0:
打印结果:
打印行
elif m.tell()==m.size():
破裂
否则:
及格效果:
~$ python untitled.py
查找:周教育行业标准
结果:
-周周转储10.13发行版5.6.19,适用于osx10.7 (x86_64)
结果:
/*!40101周jy SET @ OLD _ CHARACTER _ SET _ CLIENT=@ @ CHARACTER _ SET _ CLIENT */周jy;
结果:
/*!40103 SET TIME _ ZONE= 00:00 */ZHOUJY;查看代码
:从整个文件里查找,找到就退出(确认到底是否存在)
#!/usr/bin/python
# -*-编码:utf-8 -*-
导入内存映射
导入上下文库
word=ZHOUJY
打印查找:,单词
f=打开( test.txt , r )
使用上下文库。关闭(mmap。mmap(f . fileno(),0,access=mmap .ACCESS_READ))作为男:
#不需要循环,只要找到一个就可以了
loc=m.find(word)
如果loc=0:
打印位置
print m[loc:loc len(word)]效果:
~$ python untitled.py
查找:周教育行业标准
194
周JYView代码
:通过正则查找,(找出40开头的数字)
#!/usr/bin/python
# -*-编码:utf-8 -*-
导入内存映射
进口是
导入上下文库
pattern=re.compile(r(40\d*))
用打开( test.txt , r )作为女:
使用上下文库。关闭(mmap。mmap(f . fileno(),0,access=mmap .ACCESS_READ))作为男:
打印模式。芬达尔(m)效果:
~$ python untitled.py
[40101 , 40101 , 40101 , 40101 , 40103 , 40103 , 40014 , 40014 , 40101 , 40111 ]查看代码
3):处理文本,只能等长处理(通过上面的查找方法,来替换查找出的内容),模式:访问写入、访问复制
通过对mmap方法的介绍和说明,大致了解了mmap的特点。这里,通过比较sed方法,我们可以看到哪种方法在处理大文件时更有效。
:替换文本中出现过一次的内容。例如,如果您想将库A的备份文件(9G)恢复到库B,您需要将其中的使用‘A’改为使用‘B’。
1 sed处理:耗时近105s;木卫一快满了;几乎不消耗内存,CPU消耗在10 ~ 20%之间。
1.替换文本中的第一个匹配项。
~$ date sed -i 0,/USE edcba ;/s//使用“ABCDE ”;/ test.sql日期
美国中部时间2016年11月16日星期三12:04:17
美国中部时间2016年11月16日星期三12:06:02
2:替换文本中指定行的内容
~ $ date sed-I 24s/使用 ABCDE ;/使用“edcba ”;/ test.sql日期
美国中部时间2016年11月16日星期三中午12:09:05
2016年11月16日星期三12:10:50 CSTIO消费:
设备:rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-SZ avgqu-SZ await r _ await w _ await SVC TM % util
105.00 87.22 92.06 418.65 27.90 31.35 2.21 245.56 1.14 100.00
设备:rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-SZ avgqu-SZ await r _ await w _ await SVC TM % util
sda 1.00 4.00 778.00 102.00 87.59 90.03 413.36 25.08 30.30 2.59 241.65 1.13 99.60
设备:rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-SZ avgqu-SZ await r _ await w _ await SVC TM % util
101.00 87.48 88.04 412.22 29.80 30.24 2.34 243.21 1.14 99.60
设备:rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-SZ avgqu-SZ await r _ await w _ await SVC TM % util
18.00 431.00 137.00 49.08 122.04 616.99 66.20 70.25 3.02 281.75 1.75 99.60
设备:rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-SZ avgqu-SZ await r _ await w _ await SVC TM % util
sda 0.00 1.00 1.00 248.00 0.00 177.04 1456.16 105.24 416.53 24.00 418.11 4.02 100.00查看代码
Python处理:耗时毫秒级,几乎是秒级。这种情况比较特殊:搜索到的关键词在大文本的前面位置,所以t上处理大文件很快,如果搜索到的关键词在后面会怎么样?后面会解释。
#!/usr/bin/python
# -*-编码:utf-8 -*-
导入mmap
导入上下文库
进口re
word=使用 EDCBA
replace=使用` ABCDE
打印“查找:”一词
打印“替换:”,替换
f=open(test.sql , r )
with context lib . closing(mmap . mmap(f . fileno(),0,access=mmap。ACCESS_WRITE))作为m:
loc=m.find(word)
如果loc=0:
打印位置
m[loc:loc len(word)]=replace Execute:
~$ date python mmap_python.py date
美国中部时间2016年11月16日星期三12:14:19
查:用` EDCBA
替换为:使用` abcde ;
929
2016年11月16日星期三12:14:19 CST:替换文本中所有匹配的关键词。例如,我想将备份文件中的ENGINE=MYISAM更改为ENGINE=InnoDB,以查看它的执行情况。
1 sed处理:耗时110s;磁盘快满了(读写IO高);几乎不消耗内存,CPU消耗在10 ~ 30%之间。
~ $ date sed-I s/ENGINE=InnoDB/ENGINE=MyISAM/g test . SQL date
美国中部时间2016年11月16日星期三中午12:19:30
2016年11月16日周三,CST 12:21:20和,sed的执行效果差不多。事实上,sed在处理一个或多个记录时会做同样多的工作。至于原因,可以看sed工作原理的解释。我个人的理解大致是:sed一次读取一行(所以内存消耗很小),放入自己的缓冲区,替换后再写入(所以IO很高)。
2 python处理:20多秒,比sed少。因为不用什么都重写,只需要替换指定的内容,而且是在内存中处理,所以写IO几乎没有压力。关键字比较低的时候,读入的数据比较大,需要把文件从磁盘读入内存。此时磁盘的读IO也很高,但是写IO还是不可用。因为是虚拟内存映射文件,所以不会占用太多物理内存。虽然通过TOP看到的内存利用率%mem很高,但是这里可以忽略,因为大部分都消耗在SHR列,真正使用的内存可以通过RES-SHR计算出来。对于top中SHR的含义,可以阅读相关文章。
#!/usr/bin/python
# -*-编码:utf-8 -*-
导入内存映射
导入上下文库
word=ENGINE=MyISAM
replace=ENGINE=InnoDB
打印查找:,单词
打印替换:,替换
loc=0
f=open(test.sql , r )
使用上下文库。关闭(mmap。mmap(f . fileno(),0,access=mmap .访问_写入))作为男:
虽然正确:
loc=m.find(word,loc)
如果loc=0:
打印位置
m[loc:loc len(word)]=replace
#要是access=mmap .访问_复制需要执行脸红
#m.flush()
elif loc==-1:
破裂
否则:
及格效果:
~$ date python mmap_python.py date
2016年11月16日星期三中部时间13时19分30秒
查找:ENGINE=MyISAM
替换:ENGINE=InnoDB
1663
5884938
11941259
12630481
12904261
64852169
64859312
65018692
65179617
65181544
65709930
149571849
3592900115
5874952354
7998151839
2016年11月16日星期三13时19分55秒中央标准时间:正则匹配修改,这个可以通过上面介绍的查找方法,做下修改即可,就不再做说明。
小结:
对比一项Linux操作系统指令和大蟒处理文件的方法,这里来小结下:对于一项Linux操作系统指令不管修改的关键字在文本中的任意位置、次数,修改的工作量都一样(全文的读写IO),差距不大;对于python mmap的修改,要是关键字出现在比较靠前的地方,修改起来速度非常快,否则修改也会有大量的读木卫一,写超正析象管(图片Orthicon)没有。通过上面的对比分析来看,mmap的修改要比一项Linux操作系统指令修改性能高。
计算机编程语言还有另一个读取操作的方法:打开中的读取、读取行、读取行,这个方法是把文件全部载入内存,再进行操作。若内存不足直接用交换或则报错退出,内存消耗和文本大小成正比,而通过内存映射模块的方法可以很好的避免了这个问题。
总结:通过上面的介绍,大致知道如何使用内存映射模块了,其大致特点如下:
普通文件被映射到虚拟地址空间后,程序可以向访问普通内存一样对文件进行访问,在有些情况下可以提高超正析象管(图片Orthicon)效率。它占用物理内存空间少,可以解决内存空间不足的问题,适合处理超大文件。不同于通常的字符串对象,它是可变的,可以通过切片的方式更改,也可以定位当前文件位置泰尔先生或m.seek()定位到文件的指定位置,再进行m .写固定长度的修改操作。最后,可以把内存映射封装起来进行使用了,脚本信息:
#!/usr/bin/python
# -*-编码:utf-8 -*-
导入内存映射
导入上下文库
导入时间
从optparse导入选项解析器
定义计算时间(函数):
def _deco(*args,**kwargs):
begin_time=time.time()
func(*args,**kwargs)
成本时间=时间时间()-开始时间
"打印"成本时间:%s %(成本时间)
返回_装饰
@calc_time
def replace _ key _ all(文件名,旧单词,新单词):
if len(old_word)==len(new_word):
loc=0
打印" %s "替换成% s"%(新单词,旧单词)
用打开(文件名, r )作为女:
使用上下文库。关闭(mmap。mmap(f . fileno(),0,access=mmap .访问_写入))作为男:
虽然正确:
loc=m.find(old_word,loc)
如果loc=0:
m[loc:loc len(old _ word)]=new _ word
elif loc==-1:
破裂
否则:
及格
f.close()
否则:
打印替换的词要和被替换的词长度一致!
退出()
@calc_time
定义replace_keyword_once(文件名,旧单词,新单词):
if len(old_word)==len(new_word):
打印" %s "替换成% s"%(新单词,旧单词)
用打开(文件名, r )作为女:
使用上下文库。关闭(mmap。mmap(f . fileno(),0,access=mmap .访问_写入))作为男:
loc=m.find(old_word)
如果loc=0:
m[loc:loc len(old _ word)]=new _ word
f.close()
否则:
打印替换的词要和被替换的词长度一致!
退出()
if __name__==__main__ :
parser=OptionParser()
parser.add_option(-f ,- filename ,help=用于搜索的文件名,dest=文件名)
parser.add_option(-o ,- oldword ,help=要使用的 ip ,dest=old_word )
parser.add_option(-n ,- newword ,help=要使用的 ip ,dest=new_word )
(options,args)=parser.parse_args()
如果不是选项.文件名:
打印"需要应用的参数文件名"
退出()
如果不是options.old_word:
打印"需要应用旧参数"
退出()
如果不是options.new_word:
打印“需要应用的参数新词”
退出()
#替换文本中第一次出现的内容(找到一个就处理退出,越早越快)
# replace _ keyword _ once(options . filename,options.old_word,options.new_word)
#替换文本中出现的内容(查找并处理整个文本)
replace _ keyword _ all(options . filename,options.old_word,options.new_word)查看代码
方法:
~$ python mmap_search.py -h
用法:mmap _ search . py[选项]
选项:
-h,- help显示此帮助消息并退出
-f文件名,-文件名=文件名
用于搜索的文件名
-o旧字,-旧字=旧字
要使用的ip
-n新单词,-新单词=新单词
要使用的ip视图代码
脚本处理效果:(40G文本)
1)sed:替换文本中第一个出现的内容。
~$ date sed -i 0,/USE edcba ;/s//使用“ABCDE ”;/ test.sql日期
美国中部时间2016年11月17日星期四11:15:33
美国中部时间2016年11月17日星期四11:21:47
2)mmap:替换文本中第一次出现的内容(使用replace_keyword_once方法,找到一个就处理退出,越早越快)
~ $ python mmap _ search . py-filename= test . SQL -old word= USE \ ` edcba \ `;-new word= USE \ ` abcde \ `;
使用ABCDE替换为使用“EDCBA ”;
花费时间:0.00000016365
3)sed:替换文本中出现的内容(查找并处理整个文本)
~ $ date sed-I s/ENGINE=InnoDB/ENGINE=MyISAM/g test . SQL date
美国中部时间2016年11月17日星期四10:04:49
美国中部时间2016年11月17日星期四10:11:34
4)mmap:替换文本中出现的内容(使用replace_keyword_all方法查找并处理整个文本)
~ $ python mmap _ search . py-filename= test . SQL -old word= ENGINE=MyISAM -new word= ENGINE=InnoDB
ENGINE=InnoDB替换为ENGINE=MyISAM。
花费时间:198.471223116结论:要修改一个大的文本文件,通过sed处理,无论修改的单词在哪里,都需要重写整个文件;mmap修改文本时,修改后的单词表现更好。不需要重写整篇文章,只需要替换被修改单词的长度即可。
参考:内存映射文件支持
Mmap模块和mmap对象
~~~~~~~~~~~~~~~
在所有的事物中,希望是最美丽的
~~~~~~~~~~~~~~~
转载请联系作者获得授权,否则将追究法律责任。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。