首页 文章 精选 留言 我的

精选列表

搜索[计算机基础],共10000篇文章
优秀的个人博客,低调大师

Activity多功能按钮——基础编

packagecom.smart; importandroid.app.Activity; importandroid.app.AlertDialog; importandroid.app.Dialog; importandroid.content.DialogInterface; importandroid.os.Bundle; importandroid.util.Log; importandroid.view.View; importandroid.view.View.OnClickListener; importandroid.widget.Button; importandroid.widget.ListView; //继承OnClickListener publicclassMainextendsActivityimplementsOnClickListener{ //固定的静态变量, privatefinalintDELETE_FILE=1; privatefinalintSIMPLE_LIST=2; privatefinalintSINGLE_CHOICE_LIST=3; privatefinalintMULTI_LIST=4; privateListViewlv=null; //定义一个字符串数组 privateString[]provinces=newString[]{"中国","泰国","美国","法国", "新加坡","英国"}; //按钮 privateButtonOnClickbuttonOnClick=newButtonOnClick(1); @Override//事件点击 publicvoidonClick(Viewv){ //开关选择 switch(v.getId()){ caseR.id.btnDeleteFile: showDialog(DELETE_FILE); break; caseR.id.btnSimpleList: showDialog(SIMPLE_LIST); break; caseR.id.btnChoiceList: showDialog(SINGLE_CHOICE_LIST); break; caseR.id.btnMultiChoiceList: showDialog(MULTI_LIST); break; caseR.id.btnRemoveDialog: removeDialog(DELETE_FILE); removeDialog(SIMPLE_LIST); removeDialog(SINGLE_CHOICE_LIST); removeDialog(MULTI_LIST); break; } } @Override protectedDialogonCreateDialog(intid){ Log.d("dialog",String.valueOf(id)); //用来判断选择的目标。如果没有选择,并提示出来,选择中了,也显示结果。详看代码 switch(id){ caseDELETE_FILE: returnnewAlertDialog.Builder(this).setIcon(R.drawable.question).setTitle("是否删除文件").setPositiveButton("确定",newDialogInterface.OnClickListener(){ @Override publicvoidonClick(DialogInterfacedialog,intwhich){ newAlertDialog.Builder(Main.this).setMessage("文件已经被删除").create().show(); } }).setNegativeButton("取消",newDialogInterface.OnClickListener(){ @Override publicvoidonClick(DialogInterfacedialog,intwhich){ newAlertDialog.Builder(Main.this).setMessage("您已经选择了取消,文件未删除").create().show(); } }).create(); caseSIMPLE_LIST: returnnewAlertDialog.Builder(this).setTitle("选择国家").setItems(provinces,newDialogInterface.OnClickListener(){ @Override publicvoidonClick(DialogInterfacedialog,intwhich){ finalAlertDialogad=newAlertDialog.Builder(Main.this).setMessage("您已经选择了"+which+":"+provinces[which]).show(); android.os.Handlerhander=newandroid.os.Handler(); hander.postDelayed(newRunnable(){ //线程管理 @Override publicvoidrun(){ ad.dismiss(); } },5*1000); } }).create(); caseSINGLE_CHOICE_LIST: returnnewAlertDialog.Builder(this).setTitle("选择国家").setSingleChoiceItems(provinces,1,buttonOnClick).setPositiveButton("确定",buttonOnClick).setNegativeButton("取消",buttonOnClick).create(); caseMULTI_LIST: AlertDialogad=newAlertDialog.Builder(this).setIcon(R.drawable.image).setTitle("选择国家").setMultiChoiceItems(provinces,newboolean[]{false,true,false,true,false,false},newDialogInterface.OnMultiChoiceClickListener(){ @Override publicvoidonClick(DialogInterfacedialog,intwhich,booleanisChecked){ } }).setPositiveButton("确定",newDialogInterface.OnClickListener(){ @Override publicvoidonClick(DialogInterfacedialog,intwhich){ intcount=lv.getCount(); Strings="您选择了:"; for(inti=0;i<provinces.length;i++){ if(lv.getCheckedItemPositions().get(i)){ s+=i+":"+lv.getAdapter().getItem(i)+""; } } if(lv.getCheckedItemPositions().size()>0){ newAlertDialog.Builder(Main.this).setMessage(s).show(); }else{ newAlertDialog.Builder(Main.this).setMessage("您未选择任何国家").show(); } } }).setNegativeButton("取消",null).create(); lv=ad.getListView(); returnad; } returnnull; } @Override publicvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.main); //得到选中的哪一个按钮 ButtonbtnDeletefile=(Button)findViewById(R.id.btnDeleteFile); ButtonbtnSimpleList=(Button)findViewById(R.id.btnChoiceList); ButtonbtnSimngleChoiceList=(Button)findViewById(R.id.btnSimpleList); ButtonbtnMultiChoiceList=(Button)findViewById(R.id.btnMultiChoiceList); ButtonbtnRemoveDialog=(Button)findViewById(R.id.btnRemoveDialog); //绑定监听器 btnDeletefile.setOnClickListener(this); btnSimpleList.setOnClickListener(this); btnSimngleChoiceList.setOnClickListener(this); btnMultiChoiceList.setOnClickListener(this); btnRemoveDialog.setOnClickListener(this); } //定义一个类,用来判断选择中的。 privateclassButtonOnClickimplementsDialogInterface.OnClickListener{ privateintindex; publicButtonOnClick(intindex){ this.index=index; } @Override publicvoidonClick(DialogInterfacedialog,intwhichButton){ if(whichButton>=0){ index=whichButton; }else{ if(whichButton==DialogInterface.BUTTON_POSITIVE){ newAlertDialog.Builder(Main.this).setMessage("您已经选择了:"+index+":"+provinces[index]).show(); }elseif(whichButton==DialogInterface.BUTTON_NEGATIVE){ newAlertDialog.Builder(Main.this).setMessage("你未选择,请选择").show(); } } } } protectedvoidonPrepareDialog(intid,Dialogdialog){ super.onPrepareDialog(id,dialog); } } 另外很多朋友对Android系统构架图还不是很了解,我附上一张中文的图给大家观看 本文转自 llb988 51CTO博客,原文链接:http://blog.51cto.com/llb988/489522,如需转载请自行联系原作者

优秀的个人博客,低调大师

python文件基础之(文件操作)

在之前学习了python的列表、元组、集合等知识,接下来将python的文件相关的知识做一总结和分析。 一 open函数 在我们用word、excel、vim对文件操作时,肯定要先打开文件,同样在编程里面也是需要将文件打开,然后再对文件操作,操作完对文件进行关闭。文件打开使用open()函数,同时创建一个相关的对象。 、基本语法: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 open ( file ,mode = 'r' ,buffering = None ,encoding = None ,errors = None ,newline = None ,closefd = True ) 参数介绍: file :表示文件名,可以使用绝对路径和相对路径,还有可以根据mode方式决定文件的追加或者覆盖 mode:表示打开文件的模式 buffering:设置缓存模式。 0 表示不缓存, 1 表示缓存;如果大于 1 则表示缓冲区的大小,以字节为单位。 encoding:表示打开文件的编码格式 errors:参数errors是用来指明编码和解码错误时怎么样处理。不能在二进制的模式下使用。 1 )当指明为’strict’时,编码出错则抛出异常ValueError。 2 )当指明为’ignore’时,忽略错误。 3 )当指明为’replace’时,使用某字符进行替代模式,比如使用’?’来替换出错的。 4 )其它相应还有surrogateescape / xmlcharrefreplacs / backslashreplace。 newline: 参数newline是用来控制文本模式之下,一行的结束字符。可以是 None ,’’,\n,\r,\r\n等。 当在读取模式下,如果新行符为 None ,那么就作为通用换行符模式工作,意思就是说当遇到\n, \r或\r\n都可以作为换行标识,并且统一转换为\n作为文本输入的换行符。当设置为空’’时, 也是通用换行符模式工作,但不作转换为\n,输入什么样的,就保持原样全输入。当设置为其它相应 字符时,就会判断到相应的字符作为换行符,并保持原样输入到文本。 当在输出模式时,如果新行符为 None ,那么所有输出文本都是采用\n作为换行符。如果设置为’’ 或者\n时,不作任何的替换动作。如果是其它字符,会在字符后面添加\n作为换行符。 closefd:是用来当给一个文件句柄传进来时,而当退出文件使用时,而不对文件句柄进行关闭。如果传 递一个文件名进来,这个参数无效,必定为 True 方式。 关于上面提到的mode模式种类比较多,我们做以下相关介绍和总结, 模式 描述 r 打开一个文件为只读。文件指针置于该文件的开头。这是默认模式。 rb 打开一个文件只能以二进制格式读取。文件指针置于该文件的开头。这是默认模式。 r+ 打开用于读取和写入文件。文件指针将会在文件的开头。 rb+ 打开用于读取和写入二进制格式的文件。文件指针将会在文件的开头。 w 打开一个文件只写。覆盖该文件,如果该文件存在。如果该文件不存在,则创建用于写入一个新的文件。 wb 打开一个文件只能以二进制格式写入。覆盖该文件,如果该文件存在。如果该文件不存在,则创建用于写入一个新的文件。 w+ 打开用于写入和读取的文件。覆盖现有的文件,如果文件存在。如果该文件不存在,则创建读取和写入新的文件。 wb+ 打开用于写入和读取的二进制格式的文件。覆盖现有的文件,如果文件存在。如果该文件不存在,则创建读取和写入新的文件。 a 将打开追加文件。文件指针是在文件的结尾。也就是说,该文件是在附加模式。如果该文件不存在,它创造了写入一个新的文件。 ab 将打开追加的二进制格式的文件。文件指针在该文件的结束。也就是说,该文件为追加模式。如果该文件不存在,它创建并写入一个新的文件。 a+ 打开为追加和读取文件。文件指针在该文件的结束。该文件将为追加模式。如果该文件不存在,它创建并读取和写入的新文件。 ab+ 打开两个追加和读取的二进制格式的文件。文件指针在该文件的结束。该文件将在追加模式。如果该文件不存在,它创建并读取和写入的新文件。 二进制在我们处理图像等信息时使用比较多,而其他部分在我们操作字符串等内容比较多。 简单的示例: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 示例文件内容: 我曾经问个不休你何时跟我走 可你却总是笑我一无所有 我要给你我的追求还有我的自由 可你却总是笑我一无所有 噢你何时跟我走 噢你何时跟我走 脚下的地在走身边的水在流 可你却总是笑我一无所有 为何你总笑个没够为何我总要追求 难道在你面前我永远是一无所有 Processfinishedwithexitcode 0 #!/usr/bin/envpython #_*_coding:utf-8_*_ a_File = open ( "D:\\pythonfile.txt" , "r" ,encoding = 'utf-8' ) readline = a_File.read() print (readline) 结果: 我曾经问个不休你何时跟我走 可你却总是笑我一无所有 我要给你我的追求还有我的自由 可你却总是笑我一无所有 噢你何时跟我走 噢你何时跟我走 脚下的地在走身边的水在流 可你却总是笑我一无所有 为何你总笑个没够为何我总要追求 难道在你面前我永远是一无所有 上面使用的r模式打开,我们采取尝试写入文件,写入内容为字符串openstack\nMYSQLDBA #!/usr/bin/envpython #_*_coding:utf-8_*_ a_File = open ( "D:\\pythonfile.txt" , "r" ,encoding = 'utf-8' ) readline = a_File.read() print (readline) a_File.write( "openstack\nMYSQLDBA" ) a_File.close() 结果:文件不可写 Traceback(mostrecentcalllast): File "D:/project/myapp/hello.py" ,line 6 , in <module> a_File.write( "openstack\nMYSQLDBA" ) io.UnsupportedOperation: not writable 我们再尝试用二进制方式打开文件查看内容: #!/usr/bin/envpython #_*_coding:utf-8_*_ a_File = open ( "D:\\pythonfile.txt" , "rb" ) #去掉了编码格式 readline = a_File.read() print (readline) #a_File.write("openstack\nMYSQLDBA") a_File.close() 结果: b'\xe6\x88\x91\xe6\x9b\xbe\xe7\xbb\x8f\xe9\x97\xae\xe4\xb8\xaa\xe4\xb8\x8d\xe4\xbc\x91\xe4\xbd\xa0\xe4\xbd\x95\xe 其他内容繁多,因此不再演示其他的mode模式 在研究完我们如何将文件打开后,我们就要考虑如何处理打开的文件,主要涉及到文件对象的一些方法。 序号 方法以及描述与应用 1 open()可以创建一个对象打开某个文件,这一部分涉及内容比较多,下一部分介绍,打开的方式以及编码格式等 2 file.close()关闭文件 关闭文件后不能再进行读写操作 3 file.read([size])从文件读取指定的字节数,要是未指定或为负则读取所有 4 file.readline([size])读取整行包括”\n”换行 5 file.readlines()读取文件里的所有行并返回列表,若sizeint>0返回总行约为sizeint字节的行,实际读取的值可能比sizeint较大,因为需要缓冲区 6 file.next()返回文件下一行 7 file.isatty()如果文件连接一个终端设备返回Ture 否则返回False 8 file.flush()刷新文件内部缓冲,直接把内部缓存区的数据写入文件,而不是被动的等待输出缓存区写入 9 file.fileno()返回一个整型的文件描述符(file descriptor FD)可以用在os模块的read方法等的底层操作 10 file.seek(offset[whencr])设置文件的当前位置 11 file.tell()返回文件的当前位置 12 file.truncate([size])截取文件,截取的字节通过size指定,默认当前位置开始 13 file.write(str)将字符串写入文件没有返回值 14 file.writelines(sequence)向文件写入一个序列字符串列表,如果需要换行则需要自己加入换行符 下面根据不同的方法做简单介绍以及相关示例 读操作:读的有file.read() filereadline() filereadlies()等三种方法 1、file.read()方法 里面的参数是size,表示从文件中读取size大小字节,当默认为空或者为负值时表示读取所有的字节, 示例: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 #!/usr/bin/envpython #_*_coding:utf-8_*_ a_File = open ( "D:\\pythonfile.txt" , "r" ,encoding = 'utf-8' ) #readline=a_File.read(1) print ( "测试结果1" .center( 100 , '#' ))#为了更好的展现测试结果分割 print (a_File.read( - 1 )) 结果: ###############################################测试结果1################################################ 我曾经问个不休你何时跟我走 可你却总是笑我一无所有 我要给你我的追求还有我的自由 可你却总是笑我一无所有 噢你何时跟我走 噢你何时跟我走 脚下的地在走身边的水在流 #!/usr/bin/envpython #_*_coding:utf-8_*_ a_File = open ( "D:\\pythonfile.txt" , "r" ,encoding = 'utf-8' ) #readline=a_File.read(1) print ( "测试结果2" .center( 100 , '#' ))#为了更好的展现测试结果分割 print (a_File.read()) 结果: ###############################################测试结果2################################################ 我曾经问个不休你何时跟我走 可你却总是笑我一无所有 我要给你我的追求还有我的自由 可你却总是笑我一无所有 噢你何时跟我走 噢你何时跟我走 脚下的地在走身边的水在流 #!/usr/bin/envpython #_*_coding:utf-8_*_ a_File = open ( "D:\\pythonfile.txt" , "r" ,encoding = 'utf-8' ) #readline=a_File.read(1) print ( "测试结果3" .center( 100 , '#' ))#为了更好的展现测试结果分割 print (a_File.read( 3 )) 结果: ###############################################测试结果3################################################ 我曾经 #!/usr/bin/envpython #_*_coding:utf-8_*_ a_File = open ( "D:\\pythonfile.txt" , "r" ,encoding = 'utf-8' ) #readline=a_File.read(1) print ( "测试结果4" .center( 100 , '#' ))#为了更好的展现测试结果分割 print (a_File.read( 15 )) 结果: ###############################################测试结果4################################################ 我曾经问个不休你何时跟我走 可以发现read方法是受字节数量控制的,字节数量的控制影响其输出 2、readline()方法 读取整行包括”\n”换行,参数也是[size]控制,其和read()的区别就是当readline()某行中的字符不够时,只读取改行,而read()会读取其他行的内容。 示例(两者的区别) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 #!/usr/bin/envpython #_*_coding:utf-8_*_ a_File = open ( "D:\\pythonfile.txt" , "r" ,encoding = 'utf-8' ) #readline=a_File.read(1) print ( "测试结果1" .center( 100 , '#' ))#为了更好的展现测试结果分割 print (a_File.read( 50 )) print ( "测试结果2" .center( 100 , '#' ))#为了更好的展现测试结果分割 print (a_File.readline( 100 )) 结果: ###############################################测试结果1################################################ 我曾经问个不休你何时跟我走 可你却总是笑我一无所有 我要给你我的追求还有我的自由 可你却总是笑 ###############################################测试结果2################################################ 我一无所有 readline()方法默认值和负值的相关示例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 #!/usr/bin/envpython #_*_coding:utf-8_*_ a_File = open ( "D:\\pythonfile.txt" , "r" ,encoding = 'utf-8' ) #readline=a_File.read(1) print ( "测试结果1" .center( 100 , '#' ))#为了更好的展现测试结果分割 print (a_File.readline()) print ( "测试结果2" .center( 100 , '#' ))#为了更好的展现测试结果分割 print (a_File.readline( - 1 )) print ( "测试结果3" .center( 100 , '#' ))#为了更好的展现测试结果分割 print (a_File.readline( 4 )) print ( "测试结果4" .center( 100 , '#' ))#为了更好的展现测试结果分割 print (a_File.readline( 10 )) 结果: ###############################################测试结果1################################################ 我曾经问个不休你何时跟我走 ###############################################测试结果2################################################ 可你却总是笑我一无所有 ###############################################测试结果3################################################ 我要给你 ###############################################测试结果4################################################ 我的追求还有我的自 3、readlines()取文件里的所有行并返回列表,若sizeint>0返回总行约为sizeint字节的行,实际读取的值可能比sizeint较大,因为需要缓冲区。则读取指定长度的字节, 并且将这些字节按行分割。 例如: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #!/usr/bin/envpython #_*_coding:utf-8_*_ a_File = open ( "D:\\pythonfile.txt" , "r" ,encoding = 'utf-8' ) #readline=a_File.read(1) print ( "测试结果1" .center( 100 , '#' ))#为了更好的展现测试结果分割 print (a_File.readlines( 14 )) ###############################################测试结果1################################################ [ '我曾经问个不休你何时跟我走\n' ] #!/usr/bin/envpython #_*_coding:utf-8_*_ a_File = open ( "D:\\pythonfile.txt" , "r" ,encoding = 'utf-8' ) #readline=a_File.read(1) print ( "测试结果1" .center( 100 , '#' ))#为了更好的展现测试结果分割 print (a_File.readlines( 14 )) [ '我曾经问个不休你何时跟我走\n' , '可你却总是笑我一无所有\n' ] 当我们设置sizeint值大于行中的字符时才能显示其他行的内容 4、file.close() 关闭文件 关闭文件后不能再进行读写操作文件对象的close()方法刷新未写入的信息,并关闭该文件的对象,在这之后没有数据内容可以执行写入。 Python自动关闭,当文件的引用对象被重新分配给另外一个文件。它是使用close()方法来关闭文件是一个很好的做法。 1 2 3 4 5 6 7 8 9 #!/usr/bin/envpython #_*_coding:utf-8_*_ a_File = open ( "D:\\pythonfile2.txt" , "w+" ) #readline=a_File.read(1) a_File.write( "winnerlookopenatck" ) a_File.close() 将文件写入 写入内容: winnerlookopenatck 5、flie.write() write()方法写入字符串到任何一个打开的文件。要注意的是Python字符串可以具有二进制数据,而不仅仅是文字。 write()方法不要将换行字符(' ')添加到字符串的结尾。在文件关闭前或缓冲区刷新前,字符串内容存储在缓冲区中,这时你在文件中是看不到写入的内容。 例如: 1 2 3 4 5 6 #!/usr/bin/envpython #_*_coding:utf-8_*_ a_File = open ( "D:\\pythonfile2.txt" , "w+" ) #readline=a_File.read(1) a_File.write( "winnerlookopenatck" ) a_File.close() 6、file.writelines() file.writelines()方法用于向文件中写入一序列的字符串。这一序列字符串可以是由迭代对象产生的,如一个字符串列表。换行需要制定换行符 \n。 1 2 3 4 5 6 7 8 9 10 11 12 13 #!/usr/bin/envpython #_*_coding:utf-8_*_ sed = [ "openstack:1\n" , "docker2\n" , "mysqlDBA3\n" , "KVM4\n" ] #定义列表 a_File = open ( "D:\\pythonfile2.txt" , "w+" ) #readline=a_File.read(1) a_File.writelines(sed) a_File.close() 结果: openstack: 1 docker 2 mysqlDBA 3 KVM 4 7、file.flush() flush() 方法是用来刷新缓冲区的,即将缓冲区中的数据立刻写入文件,同时清空缓冲区,不需要是被动的等待输出缓冲区写入。 一般情况下,文件关闭后会自动刷新缓冲区,但有时你需要在关闭前刷新它,这时就可以使用 flush() 方法。没有返回值 例如 1 2 3 4 5 6 7 8 9 #!/usr/bin/envpython #_*_coding:utf-8_*_ sed = [ "openstack:1\n" , "docker2\n" , "mysqlDBA3\n" , "KVM4\n" ] a_File = open ( "D:\\pythonfile2.txt" , "w+" ) #readline=a_File.read(1) a_File.writelines(sed) a_File.flush() a_File.close() 8、file.next() next() 方法在文件使用迭代器时会使用到,在循环中,next()方法会在每次循环中调用,该方法返回文件的下一行,如果到达结尾(EOF),则触发StopIteration 示例: 1 2 3 4 5 6 7 8 #!/usr/bin/envpython #_*_coding:utf-8_*_ sed = [ "openstack:1\n" , "docker2\n" , "mysqlDBA3\n" , "KVM4\n" ] aFile = open ( "D:\\pythonfile2.txt" , "w+" ) for index in range ( 3 ): line = next (aFile) print ( "第%d行-%s" % (index,line)) 9、file.tell() file.tell()方法返回文件的当前位置,即文件指针当前位置。 语法: 1 fileObject.tell(offset[,whence]) 返回值当前文件指针 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 #!/usr/bin/envpython #_*_coding:utf-8_*_ sed = [ "openstack:1\n" , "docker2\n" , "mysqlDBA3\n" , "KVM4\n" ] aFile = open ( "D:\\pythonfile.txt" , "r" ,encoding = "utf-8" ) print (aFile.readline( 30 )) print (aFile.tell()) 我曾经问个不休你何时跟我走我曾经问个不休你何时跟我走我曾 86 #!/usr/bin/envpython #_*_coding:utf-8_*_ sed = [ "openstack:1\n" , "docker2\n" , "mysqlDBA3\n" , "KVM4\n" ] aFile = open ( "D:\\pythonfile.txt" , "r" ,encoding = "utf-8" ) print (aFile.readline()) print (aFile.tell()) 我曾经问个不休你何时跟我走我曾经问个不休你何时跟我走我曾经问个不休你何时跟我走我曾经问个不休你何时跟我走 162 10、file.isatty() file.isatty()方法检测文件是否连接到一个终端设备,如果是返回 True,否则返回 False 用法: fileObject.isatty() #!/usr/bin/envpython #_*_coding:utf-8_*_ sed=["openstack:1\n","docker2\n","mysqlDBA3\n","KVM4\n"] aFile=open("D:\\pythonfile.txt","r",encoding="utf-8") print(aFile.isatty()) False 11、file.seek() seek() 方法用于移动文件读取指针到指定位置,没有返回值 seek() 方法语法如下: fileObject.seek(offset[,whence]) offset -- 开始的偏移量,也就是代表需要移动偏移的字节数 whence:可选,默认值为 0。给offset参数一个定义,表示要从哪个位置开始偏移;0代表从文件开头开始算起,1代表从当前位置开始算起,2代表从文件末尾算起。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #!/usr/bin/envpython #_*_coding:utf-8_*_ sed = [ "openstack:1\n" , "docker2\n" , "mysqlDBA3\n" , "KVM4\n" ] aFile = open ( "D:\\pythonfile.txt" , "r" ,encoding = "utf-8" ) print (aFile.readline( 10 )) print (aFile.readline( 10 )) aFile.seek( 0 , 0 ) #设置起始位置为0 print (aFile.readline( 10 )) 结果: 我曾经问个不休你何 时跟我走我曾经问个不 我曾经问个不休你何 总结打印完第一行后,下次打印从上次的位置接上,而重新设置其位置后在开始位置打印 12、file.fileno() 方法返回一个整型的文件描述符(file descriptor FD 整型),可用于底层操作系统的 I/O 操作。返回值为一个文件描述符: 1 2 3 4 5 6 7 8 9 #!/usr/bin/envpython #_*_coding:utf-8_*_ sed = [ "openstack:1\n" , "docker2\n" , "mysqlDBA3\n" , "KVM4\n" ] aFile = open ( "D:\\pythonfile.txt" , "r" ,encoding = "utf-8" ) print (aFile.fileno()) 结果: 3 13、file.truncate() truncate() 方法用于截断文件,如果指定了可选参数 size,则表示截断文件为 size 个字符。 如果没有指定 size,则从当前位置起截断;截断之后 size 后面的所有字符被删除 truncate() 方法语法如下: fileObject.truncate([size]) 参数 本文转自 tianya1993 51CTO博客,原文链接:http://blog.51cto.com/dreamlinux/1910955,如需转载请自行联系原作者

优秀的个人博客,低调大师

Android多点触控手势基础

处理多点触控手势 多点触控就是同时把一根以上的手指放在屏幕上。 再继续往下以前需要补充一些名词: 触控手势:就是把一根或者几根手指放在屏幕上做各种动作,其中包括保留一根手指的前提下,拿起或者放下其余的手指。 触控事件:在触控手势中,有手指移动或者离开屏幕的时候就会引发一个触控事件。这个事件就存放在MotionEvent中。 在这个事件中,包含说与的触控数据。 触控:手指碰到屏幕的时候就产生了一个触控(pointer)。 追踪多个触控点 多个手指同时放在屏幕上的时候会触发以下的系统事件: ACTION_DOWN --第一个对屏幕的触碰。这是多点触控的开始。这个触碰的而数据 保存在index为0的MotionEvent中。 ACTION_POINTER_DOWN--其他对屏幕的触碰。触碰事件的index可以用方法getActionIndex()获取到。 触碰的数据保存在这个index指定的MotionEvent中。 ACTION_MOVE--放在屏幕上的任何一根手指移动的时候触发。 ACTION_POINTER_UP--第一个触摸屏幕的手指以外的其他手指离开屏幕的时候触发。 ACTION_UP--当最后一根手指离开屏幕的时候触发。 你可以通过触碰事件的index或者ID来获得事件MotionEvent。 Index: 一个MotionEvent存储了几根手指触摸屏幕的每一个手指的触碰数据。一般处理触摸 的是后都用index作为获取MotionEvent的依据,而不是触碰ID。 ID:整个多点触摸事件过程中,每一个触摸都有一个ID和整个触摸匹配。 一个触碰的index在MotionEvent中可能发生改变的。而整个触碰的ID是保持不变的,只要整个 触碰保持激活状态。用getPointerId()可以获取整个手势执行期间的每一个event里的触碰数据。 也可以通过findPointerIndex()来根据一个触控的ID来获取这触控在触控事件中的index。比如: var mActivePointerId: Int? = null override fun onTouchEvent(event: MotionEvent?): Boolean { mActivePointerId = event?.getPointerId(0) // 其他的事件先不管... // 用触控ID获得index,然后获取位置数据 var pointerIndex = event?.findPointerIndex(mActivePointerId!!) // 获取触控的当前位置 var x = event?.getX(pointerIndex!!) var y = event?.getY(pointerIndex!!) return true } 获取一个MotionEvent的Action 你应该使用getActionMasked()(或者从兼容方面考虑的话用MotionEventCompat.getAtionMasked()来获取MotionEvent的action。与getAction()不同,getActionMasked()就是被用来处理多点触控的。 这个方法的返回值不在包含触控index的位数。你可以用getActonIndex()来获取触控action的index。这些在后面详细叙述。 注意:后面的例子用的是MotionEventCompat类。这个类在Support Library中。 你可以使用MotionEventCompat来获得更多的平台支持。MotionEventCompat不是用来代替MotionEvent的。 其实,这个类只是提供了一些静态方法以方便使用。 override fun onTouchEvent(event: MotionEvent?): Boolean { var action = MotionEventCompat.getActionMasked(event!!) var index: Int = MotionEventCompat.getActionIndex(event!!) var xPos = -1.0f var yPos = -1.0f Log.d(TAG, "The action is " + actionToSring(action)) if (event!!.pointerCount > 1) { Log.d(TAG, "Mutipletouch event") // 坐标系是相对于处理这个事件的View或者Activity的 xPos = MotionEventCompat.getX(event!!, index) yPos = MotionEventCompat.getY(event!!, index) } else { //单点触控 Log.d(TAG, "Single touch event") xPos = MotionEventCompat.getX(event!!, index) yPos = MotionEventCompat.getY(event!!, index) } return true } fun actionToSring(action: Int): String { when (action) { MotionEvent.ACTION_DOWN -> return "Down" MotionEvent.ACTION_MOVE -> return "Move" MotionEvent.ACTION_POINTER_DOWN -> return "Pointer down" MotionEvent.ACTION_UP -> return "UP" MotionEvent.ACTION_POINTER_UP -> return "Pointer up" MotionEvent.ACTION_OUTSIDE -> return "Outside" MotionEvent.ACTION_CANCEL -> return "Cancel" } return "" } 原文是Google的文档。但是文档杜宇前提和一些概念的描述不足,会导致初学者理解出现偏差。我都加上了,我就是初学者。 代码都是用Kotlin写的,自从用了这个语言就再也不想用Java了。对于Java开发者理解Kotlin的代码没有什么太大的问题,基本上都一样。 欢迎加群互相学习,共同进步。QQ群:iOS: 58099570 | Android: 572064792 | Nodejs:329118122 做人要厚道,转载请注明出处! 本文转自张昺华-sky博客园博客,原文链接:http://www.cnblogs.com/sunshine-anycall/p/5245293.html ,如需转载请自行联系原作者

优秀的个人博客,低调大师

Elastic 技术栈之 Logstash 基础

本文是 Elastic 技术栈(ELK)的 Logstash 应用。 如果不了解 Elastic 的安装、配置、部署,可以参考:Elastic 技术栈之快速入门 简介 Logstash 可以传输和处理你的日志、事务或其他数据。 功能 Logstash 是 Elasticsearch 的最佳数据管道。 Logstash 是插件式管理模式,在输入、过滤、输出以及编码过程中都可以使用插件进行定制。Logstash 社区有超过 200 种可用插件。 工作原理 Logstash 有两个必要元素:input和output,一个可选元素:filter。 这三个元素,分别代表 Logstash 事件处理的三个阶段:输入 > 过滤器 > 输出。 input 负责从数据源采集数据。 filter 将数据修改为你指定的格式或内容。 output 将数据传输到目的地。 在实际应用场景中,通常输入、输出、过滤器不止一个。Logstash 的这三个元素都使用插件式管理方式,用户可以根据应用需要,灵活的选用各阶段需要的插件,并组合使用。 后面将对插件展开讲解,暂且不表。 设置 设置文件 logstash.yml:logstash 的默认启动配置文件 jvm.options:logstash 的 JVM 配置文件。 startup.options(Linux):包含系统安装脚本在/usr/share/logstash/bin中使用的选项为您的系统构建适当的启动脚本。安装 Logstash 软件包时,系统安装脚本将在安装过程结束时执行,并使用startup.options中指定的设置来设置用户,组,服务名称和服务描述等选项。 logstash.yml 设置项 节选部分设置项,更多项请参考:https://www.elastic.co/guide/en/logstash/current/logstash-settings-file.html 参数 描述 默认值 node.name 节点名 机器的主机名 path.data Logstash及其插件用于任何持久性需求的目录。 LOGSTASH_HOME/data pipeline.workers 同时执行管道的过滤器和输出阶段的工作任务数量。如果发现事件正在备份,或CPU未饱和,请考虑增加此数字以更好地利用机器处理能力。 Number of the host’s CPU cores pipeline.batch.size 尝试执行过滤器和输出之前,单个工作线程从输入收集的最大事件数量。较大的批量处理大小一般来说效率更高,但是以增加的内存开销为代价。您可能必须通过设置LS_HEAP_SIZE变量来有效使用该选项来增加JVM堆大小。 125 pipeline.batch.delay 创建管道事件批处理时,在将一个尺寸过小的批次发送给管道工作任务之前,等待每个事件需要多长时间(毫秒)。 5 pipeline.unsafe_shutdown 如果设置为true,则即使在内存中仍存在inflight事件时,也会强制Logstash在关闭期间退出。默认情况下,Logstash将拒绝退出,直到所有接收到的事件都被推送到输出。启用此选项可能会导致关机期间数据丢失。 false path.config 主管道的Logstash配置路径。如果您指定一个目录或通配符,配置文件将按字母顺序从目录中读取。 Platform-specific. See [dir-layout]. config.string 包含用于主管道的管道配置的字符串。使用与配置文件相同的语法。 None config.test_and_exit 设置为true时,检查配置是否有效,然后退出。请注意,使用此设置不会检查grok模式的正确性。 Logstash可以从目录中读取多个配置文件。如果将此设置与log.level:debug结合使用,则Logstash将记录组合的配置文件,并注掉其源文件的配置块。 false config.reload.automatic 设置为true时,定期检查配置是否已更改,并在配置更改时重新加载配置。这也可以通过SIGHUP信号手动触发。 false config.reload.interval Logstash 检查配置文件更改的时间间隔。 3s config.debug 设置为true时,将完全编译的配置显示为调试日志消息。您还必须设置log.level:debug。警告:日志消息将包括任何传递给插件配置作为明文的“密码”选项,并可能导致明文密码出现在您的日志! false config.support_escapes 当设置为true时,带引号的字符串将处理转义字符。 false modules 配置时,模块必须处于上表所述的嵌套YAML结构中。 None http.host 绑定地址 "127.0.0.1" http.port 绑定端口 9600 log.level 日志级别。有效选项:fatal > error > warn > info > debug > trace info log.format 日志格式。json (JSON 格式)或 plain (原对象) plain path.logs Logstash 自身日志的存储路径 LOGSTASH_HOME/logs path.plugins 在哪里可以找到自定义的插件。您可以多次指定此设置以包含多个路径。 启动 命令行 通过命令行启动 logstash 的方式如下: bin/logstash [options] 其中 [options] 是您可以指定用于控制 Logstash 执行的命令行标志。 在命令行上设置的任何标志都会覆盖 Logstash 设置文件(logstash.yml)中的相应设置,但设置文件本身不会更改。 注 虽然可以通过指定命令行参数的方式,来控制 logstash 的运行方式,但显然这么做很麻烦。 建议通过指定配置文件的方式,来控制 logstash 运行,启动命令如下: bin/logstash -f logstash.conf 若想了解更多的命令行参数细节,请参考:https://www.elastic.co/guide/en/logstash/current/running-logstash-command-line.html 配置文件 上节,我们了解到,logstash 可以执行bin/logstash -f logstash.conf,按照配置文件中的参数去覆盖默认设置文件(logstash.yml)中的设置。 这节,我们就来学习一下这个配置文件如何配置参数。 配置文件结构 在工作原理一节中,我们已经知道了 Logstash 主要有三个工作阶段 input 、filter、output。而 logstash 配置文件文件结构也与之相对应: input {} filter {} output {} 每个部分都包含一个或多个插件的配置选项。如果指定了多个过滤器,则会按照它们在配置文件中的显示顺序应用它们。 插件配置 插件的配置由插件名称和插件的一个设置块组成。 下面的例子中配置了两个输入文件配置: input { file { path => "/var/log/messages" type => "syslog" } file { path => "/var/log/apache/access.log" type => "apache" } } 您可以配置的设置因插件类型而异。你可以参考:Input Plugins,Output Plugins,Filter Plugins, 和Codec Plugins。 值类型 一个插件可以要求设置的值是一个特定的类型,比如布尔值,列表或哈希值。以下值类型受支持。 Array users => [ {id => 1, name => bob}, {id => 2, name => jane} ] Lists path => [ "/var/log/messages", "/var/log/*.log" ] uris => [ "http://elastic.co", "http://example.net" ] Boolean ssl_enable => true Bytes my_bytes => "1113" # 1113 bytes my_bytes => "10MiB" # 10485760 bytes my_bytes => "100kib" # 102400 bytes my_bytes => "180 mb" # 180000000 bytes Codec codec => "json" Hash match => { "field1" => "value1" "field2" => "value2" ... } Number port => 33 Password my_password => "password" URI my_uri => "http://foo:bar@example.net" Path my_path => "/tmp/logstash" String 转义字符 插件 input Logstash 支持各种输入选择 ,可以在同一时间从众多常用来源捕捉事件。能够以连续的流式传输方式,轻松地从您的日志、指标、Web 应用、数据存储以及各种 AWS 服务采集数据。 常用 input 插件 file:从文件系统上的文件读取,就像UNIX命令tail -0F一样 syslog:在众所周知的端口514上侦听系统日志消息,并根据RFC3164格式进行解析 redis:从redis服务器读取,使用redis通道和redis列表。 Redis经常用作集中式Logstash安装中的“代理”,它将来自远程Logstash“托运人”的Logstash事件排队。 beats:处理由Filebeat发送的事件。 更多详情请见:Input Plugins filter 过滤器是Logstash管道中的中间处理设备。如果符合特定条件,您可以将条件过滤器组合在一起,对事件执行操作。 常用 filter 插件 grok:解析和结构任意文本。 Grok目前是Logstash中将非结构化日志数据解析为结构化和可查询的最佳方法。 mutate:对事件字段执行一般转换。您可以重命名,删除,替换和修改事件中的字段。 drop:完全放弃一个事件,例如调试事件。 clone:制作一个事件的副本,可能会添加或删除字段。 geoip:添加有关IP地址的地理位置的信息(也可以在Kibana中显示惊人的图表!) 更多详情请见:Filter Plugins output 输出是Logstash管道的最后阶段。一个事件可以通过多个输出,但是一旦所有输出处理完成,事件就完成了执行。 常用 output 插件 elasticsearch:将事件数据发送给 Elasticsearch(推荐模式)。 file:将事件数据写入文件或磁盘。 graphite:将事件数据发送给 graphite(一个流行的开源工具,存储和绘制指标。http://graphite.readthedocs.io/en/latest/)。 statsd:将事件数据发送到 statsd (这是一种侦听统计数据的服务,如计数器和定时器,通过UDP发送并将聚合发送到一个或多个可插入的后端服务)。 更多详情请见:Output Plugins codec 用于格式化对应的内容。 常用 codec 插件 json:以JSON格式对数据进行编码或解码。 multiline:将多行文本事件(如java异常和堆栈跟踪消息)合并为单个事件。 更多插件请见:Codec Plugins 实战 前面的内容都是对 Logstash 的介绍和原理说明。接下来,我们来实战一些常见的应用场景。 传输控制台数据 stdin input 插件从标准输入读取事件。这是最简单的 input 插件,一般用于测试场景。 应用 (1)创建logstash-input-stdin.conf: input { stdin { } } output { elasticsearch { hosts => ["localhost:9200"] } stdout { codec => rubydebug } } 更多配置项可以参考:https://www.elastic.co/guide/en/logstash/current/plugins-inputs-stdin.html (2)执行 logstash,使用-f来指定你的配置文件: bin/logstash -f logstash-input-stdin.conf 传输 logback 日志 想使用 logback + logstash ,可以使用logstash-logback-encoder。logstash-logback-encoder提供了 UDP / TCP / 异步方式来传输日志数据到 logstash。 TCP 应用 logstash 配置 (1)创建logstash-input-tcp.conf: input { tcp { port => 9251 codec => json_lines mode => server } } output { elasticsearch { hosts => ["localhost:9200"] } stdout { codec => rubydebug } } 更多配置项可以参考:https://www.elastic.co/guide/en/logstash/current/plugins-inputs-tcp.html (2)执行 logstash,使用-f来指定你的配置文件:bin/logstash -f logstash-input-udp.conf java 应用配置 (1)在 Java 应用的 pom.xml 中引入 jar 包: <dependency> <groupId>net.logstash.logback</groupId> <artifactId>logstash-logback-encoder</artifactId> <version>4.11</version> </dependency> <!-- logback 依赖包 --> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-core</artifactId> <version>1.2.3</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.3</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-access</artifactId> <version>1.2.3</version> </dependency> (2)接着,在 logback.xml 中添加 appender <appender name="ELK-TCP" class="net.logstash.logback.appender.LogstashTcpSocketAppender"> <!-- destination 是 logstash 服务的 host:port, 相当于和 logstash 建立了管道,将日志数据定向传输到 logstash --> <destination>192.168.28.32:9251</destination> <encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder"/> </appender> <logger name="io.github.dunwu.spring" level="TRACE" additivity="false"> <appender-ref ref="ELK-TCP" /> </logger> (3)接下来,就是 logback 的具体使用 ,如果对此不了解,不妨参考一下我的这篇博文:细说 Java 主流日志工具库。 实例:我的logback.xml UDP 应用 UDP 和 TCP 的使用方式大同小异。 logstash 配置 (1)创建logstash-input-udp.conf: input { udp { port => 9250 codec => json } } output { elasticsearch { hosts => ["localhost:9200"] } stdout { codec => rubydebug } } 更多配置项可以参考:https://www.elastic.co/guide/en/logstash/current/plugins-inputs-udp.html (2)执行 logstash,使用-f来指定你的配置文件:bin/logstash -f logstash-input-udp.conf java 应用配置 (1)在 Java 应用的 pom.xml 中引入 jar 包: 与TCP 应用一节中的引入依赖包完全相同。 (2)接着,在 logback.xml 中添加 appender <appender name="ELK-UDP" class="net.logstash.logback.appender.LogstashSocketAppender"> <host>192.168.28.32</host> <port>9250</port> </appender> <logger name="io.github.dunwu.spring" level="TRACE" additivity="false"> <appender-ref ref="ELK-UDP" /> </logger> (3)接下来,就是 logback 的具体使用 ,如果对此不了解,不妨参考一下我的这篇博文:细说 Java 主流日志工具库。 实例:我的logback.xml 传输文件 在 Java Web 领域,需要用到一些重要的工具,例如 Tomcat 、Nginx 、Mysql 等。这些不属于业务应用,但是它们的日志数据对于定位问题、分析统计同样很重要。这时无法使用 logback 方式将它们的日志传输到 logstash。 如何采集这些日志文件呢?别急,你可以使用 logstash 的 file input 插件。 需要注意的是,传输文件这种方式,必须在日志所在的机器上部署 logstash 。 应用 logstash 配置 (1)创建logstash-input-file.conf: input { file { path => ["/var/log/nginx/access.log"] type => "nginx-access-log" start_position => "beginning" } } output { if [type] == "nginx-access-log" { elasticsearch { hosts => ["localhost:9200"] index => "nginx-access-log" } } } (2)执行 logstash,使用-f来指定你的配置文件:bin/logstash -f logstash-input-file.conf 更多配置项可以参考:https://www.elastic.co/guide/en/logstash/current/plugins-inputs-file.html 小技巧 启动、终止应用 如果你的 logstash 每次都是通过指定配置文件方式启动。不妨建立一个启动脚本。 # cd xxx 进入 logstash 安装目录下的 bin 目录 logstash -f logstash.conf 如果你的 logstash 运行在 linux 系统下,不妨使用 nohup 来启动一个守护进程。这样做的好处在于,即使关闭终端,应用仍会运行。 创建 startup.sh nohup ./logstash -f logstash.conf >> nohup.out 2>&1 & 终止应用没有什么好方法,你只能使用 ps -ef | grep logstash ,查出进程,将其kill 。不过,我们可以写一个脚本来干这件事: 创建 shutdown.sh 脚本不多解释,请自行领会作用。 PID=`ps -ef | grep logstash | awk '{ print $2}' | head -n 1` kill -9 ${PID} 本文转自静默虚空博客园博客,原文链接:http://www.cnblogs.com/jingmoxukong/p/8118791.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

【Android 基础】EditText的属性介绍

EditText继承TextView,所以EditText具有TextView的属性特点,下面主要介绍一些EditText的特有的输入法的属性特点 android:layout_gravity="center_vertical":设置控件显示的位置:默认top,这里居中显示,还有bottom android:hin :Text为空时显示的文字提示信息,可通过textColorHint设置提示信息的颜色。 android:singleLine :设置单行输入,一旦设置为 true ,则文字不会自动换行。 android:gray="top" :多行中指针在第一行第一位置 et.setSelection(et.length()); :调整光标到最后一行 android:autoText :自动拼写帮助。这里单独设置是没有效果的,可能需要其他输入法辅助才行 android:capitalize :设置英文字母大写类型。设置如下值:sentences仅第一个字母大写;words每一个单词首字母大小,用空格区分单词;characters每一个英文字母都大写。 android:digits :设置允许输入哪些字符。如“1234567890.+-*/%\n()” android:singleLine :是否单行或者多行,回车是离开文本框还是文本框增加新行 android:numeric :如果被设置,该TextView接收数字输入。有如下值设置:integer正整数、signed带符号整数、decimal带小数点浮点数。 android:inputType:设置文本的类型 android:password :密码,以小点”.”显示文本 android:phoneNumber :设置为电话号码的输入方式。 android:editable :设置是否可编辑。仍然可以获取光标,但是无法输入。 android:autoLink=”all” :设置文本超链接样式当点击网址时,跳向该网址 android:textColor = "#ff8c00" :字体颜色 android:textStyle="bold" :字体, bold, italic, bolditalic android:textAlign="center" : EditText 没有这个属性,但 TextView 有 android:textColorHighlight="#cccccc" :被选中文字的底色,默认为蓝色 android:textColorHint="#ffff00" :设置提示信息文字的颜色,默认为灰色 android:textScaleX="1.5" :控制字与字之间的间距 android:typeface="monospace" :字型, normal, sans, serif, monospace android:background="@null" :空间背景,这里没有,指透明 android:layout_weight="1" :权重在控制控件显示的大小时蛮有用的。 android:textAppearance="?android:attr/textAppearanceLargeInverse" :文字外观,这里引用的是系统自带的一个外观,?表示系统是否有这种外观,否则使用默认的外观。 本文转自叶超Luka博客园博客,原文链接:http://www.cnblogs.com/yc-755909659/archive/2012/08/18/2645426.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

Android基础:shape的基本用法

<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" > <!-- 边角的圆弧半径 --> <corners android:radius="9dp" /> <!-- 实心填充 --> <solid android:color="#00000000" /> <!-- 描边:一般大小都是1dp --> <stroke android:width="1dp" android:color="#ff000000" /> <!-- 四周留出来的空白,和xml文件中的pad效果一样,对内起作用 --> <padding android:bottom="30dp" android:left="20dp" android:right="30dp" android:top="20dp" /> <!-- 背景颜色渐变 --> <gradient android:angle="90" android:endColor="#ff00ff00" android:startColor="#ff0000ff" /> </shape> shape总体说来可以看做是使一张图片,放在drawable目录下,可以单独使用,也可以和selector一起使用,主要用户处理图片的圆角,点击变色的变化。可以单独写comm_shape.xml,press_shape.xml(文件名是随便取的), 然后结合selector使用,如果熟练的话可以直接在selector中直接写,那样看起来文件不是那么多。注意上面的代码中,实心solid和渐变gradient一般不会一起使用。 本文转自demoblog博客园博客,原文链接http://www.cnblogs.com/0616--ataozhijia/archive/2012/10/31/2747284.html如需转载请自行联系原作者 demoblog

优秀的个人博客,低调大师

LNMP基础架构介绍与安装

1、LNMP架构介绍 LNMP==Linux+Nginx+Mysql+PHP nginx:省资源,省cpu,所以在高并发时能够处理更多的请求,高端能达到3万到5万的并发量。 nginx和LAMP不同的是,提供web服务的是Nginx 并且php是作为一个独立服务存在的,这个服务叫做php-fpm Nginx直接处理静态请求,动态请求会转发给php-fpm 在当前互联网环境下,一般高端的服务前端都采用nginx作为web前端,而更多的都是采用lnmp架构,真正的后端服务器才会采用apache. 为什么这么做,要取决于nginx和apache两者之间的优缺性.: nginx与apache相比有以下优势:在性能上,nginx占用很少的系统资源,能支持更多的并发链接,达到更高的访问率;在功能上,Nginx是优秀的代理服务器和负载均衡器;在安装配置上,简单灵活。 nginx模块基本都是静态编译,同时对Fast-CGI支持比较好.在处理链接上,nginx支持epoll,而且体积小一般只有几百K。 Nginx的优点有以下几点: 1.作为Web服务器,nginx处理静态文件、索引文件以及自动索引效率非常高。 2.作为代理服务器,Nginx可以实现无缓存的反向代理加速,提高网站运行速度。 3.作为负载均衡服务器,Nginx既可以在内部直接支持Rails和PHP,也可以支持HTTP代理服务器,对外进行服务。同时支持简单的容错和利用算法进行负载均衡。 4.在性能方面,Nginx是专门为性能优化而开发的,在实现上非常注重效率。它采用内核Poll模型,可以支持更多的并发连接,最大可以支持对50 000个并发连接数的响应,而且占用很低的内存资源。 5.在稳定性方面,Nginx采取了分阶段资源分配技术,使得对CPU与内存的占用率非常低。Nginx官方表示Nginx保持10 000个没有活动的连接,这些连接只占2.5M内存,因此,类似DOS这样的攻击对Nginx来说基本上是没有任何作用的。 6.在高可用性方面,Nginx支持热部署,启动速度特别迅速,因此可以在不间断服务的情况下,对软件版本或者配置进行升级,即使运行数月也无需重新启动,几乎可以做到7×24小时的不间断运行。 2、mysql安装 安装mysql的配置,其实在做LAMP的时候已经做过了,一模一样的编译配置。http://blog.51cto.com/chy940405/2047288(有需要的可以看看这篇) 3、php安装总结 和LAMP安装PHP方法有差别,需要开启php-fpm服务 [root@chy php-5.6.30]# wget http://cn2.php.net/distributions/php-5.6.30.tar.gz [root@chy php-5.6.30]# tar -zxvf php-5.6.30.tar.gz [root@chy01 php-5.6.30]# useradd -s /sbin/nologin php-fpm (增加php-fpm用户) [root@chy01 php-5.6.30]# ./configure --prefix=/usr/local/php-fpm --with-config-file-path=/usr/local/php-fpm/etc --enable-fpm --with-fpm-user=php-fpm --with-fpm-group=php-fpm --with-mysql=/usr/local/mysql --with-mysqli=/usr/local/mysql/bin/mysql_config --with-pdo-mysql=/usr/local/mysql --with-mysql-sock=/tmp/mysql.sock --with-libxml-dir --with-gd --with-jpeg-dir --with-png-dir --with-freetype-dir --with-iconv-dir --with-zlib-dir --with-mcrypt --enable-soap --enable-gd-native-ttf --enable-ftp --enable-mbstring --enable-exif --with-pear --with-curl --with-openssl (编译参数如上,如下是详解参数 ./configure --prefix=/usr/local/php-fpm(php路径) --with-config-file-path=/usr/local/php-fpm/etc(php配置文件路径) --enable-fpm(启动服务必须的参数) --with-fpm-user=php-fpm(指定php的用户) --with-fpm-group=php-fpm(指定phpd 的组) --with-mysql=/usr/local/mysql --with-mysqli=/usr/local/mysql/bin/mysql_config --with-pdo-mysql=/usr/local/mysql --with-mysql-sock=/tmp/mysql.sock --with-libxml-dir --with-gd --with-jpeg-dir --with-png-dir --with-freetype-dir --with-iconv-dir --with-zlib-dir --with-mcrypt --enable-soap --enable-gd-native-ttf --enable-ftp --enable-mbstring --enable-exif --with-pear --with-curl --with-openssl 报错信息1:configure: error: Please reinstall the libcurl distribution - easy.h should be in <curl-dir>/include/curl/ 解决方法:[root@chy01 php-5.6.30]# yum install -y libcurl-devel 然后再次编译时:编译成功 [root@chy01 php-5.6.30]# echo $? 0 [root@chy01 php-5.6.30]# make && make install (然后make 与make install) [root@chy01 php-5.6.30]# echo $? 0 (make 成功) php-fpm简单介绍 [root@chy01 php-5.6.30]# ls /usr/local/php-fpm/sbin/ php-fpm 其中(php-fpm是php-fpm的启动文件) [root@chy01 php-5.6.30]# ls /usr/local/php-fpm/var/log/ (查看日志的启动文件) [root@chy01 php-5.6.30]# /usr/local/php-fpm/sbin/php-fpm -i [root@chy01 php-5.6.30]# /usr/local/php-fpm/sbin/php-fpm -m (查看php的模块) [root@chy01 php-5.6.30]# /usr/local/php-fpm/sbin/php-fpm -t [10-Aug-2017 01:41:12] ERROR: failed to open configuration file '/usr/local/php-fpm/etc/php-fpm.conf': No such file or directory (2) [10-Aug-2017 01:41:12] ERROR: failed to load configuration file '/usr/local/php-fpm/etc/php-fpm.conf' [10-Aug-2017 01:41:12] ERROR: FPM initialization failed (-t测试php-fpm的配置的语法是否正确) [root@chy01 php-5.6.30]# cp php.ini-production /usr/local/php-fpm/etc/php.ini (cp php的线上的配置文件到/usr/local/php-fpm/etc/php.ini下去) [root@chy01 php-5.6.30]# cd /usr/local/php-fpm/etc/ [root@chy01 etc]# ls pear.conf php-fpm.conf.default php.ini [root@chy01 etc]# vim php-fpm.conf (创建php-fpm.conf,增加如下配置) [global] pid = /usr/local/php-fpm/var/run/php-fpm.pid error_log = /usr/local/php-fpm/var/log/php-fpm.log [www] listen = /tmp/php-fcgi.sock listen.mode = 666 user = php-fpm group = php-fpm pm = dynamic pm.max_children = 50 pm.start_servers = 20 pm.min_spare_servers = 5 pm.max_spare_servers = 35 pm.max_requests = 500 rlimit_files = 1024 (配置文件含义如下:[global](定义全局参数) pid = /usr/local/php-fpm/var/run/php-fpm.pid (定义pid) error_log = /usr/local/php-fpm/var/log/php-fpm.log [www] (服务的名称) listen = /tmp/php-fcgi.sock(监听的sock) #listen =127.0.0.1:9000 (这个是监听的ip地址) listen.mode = 666(这个是如果监听的是sock此项才会生效,则不会生效) user = php-fpm(用来定义用户) group = php-fpm pm = dynamic (如下是关于进程的信息) pm.max_children = 50 pm.start_servers = 20 pm.min_spare_servers = 5 pm.max_spare_servers = 35 pm.max_requests = 500 rlimit_files = 1024 [root@chy01 etc]# cd /usr/local/src/php-5.6.30 (进入到php的源码包里) [root@chy01 php-5.6.30]# cp sapi/fpm/init.d.php-fpm /etc/init.d/php-fpm (cp配置文件到/etc/init.d/php-fpm 下) [root@chy01 php-5.6.30]# chmod 755 /etc/init.d/php-fpm (更改配置权限为755) [root@chy01 php-5.6.30]# chkconfig --add php-fpm [root@chy01 php-5.6.30]# chkconfig --list 注意:该输出结果只显示 SysV 服务,并不包含原生 systemd 服务。SysV 配置数据可能被原生 systemd 配置覆盖。 如果您想列出 systemd 服务,请执行 'systemctl list-unit-files'。 欲查看对特定 target 启用的服务请执行 'systemctl list-dependencies [target]'。 apache2 0:关 1:关 2:关 3:开 4:关 5:开 6:关 mysqld 0:关 1:关 2:开 3:开 4:开 5:开 6:关 netconsole 0:关 1:关 2:关 3:关 4:关 5:关 6:关 network 0:关 1:关 2:开 3:开 4:开 5:开 6:关 php-fpm 0:关 1:关 2:开 3:开 4:开 5:开 6:关 (增加到开机启动) [root@chy01 php-5.6.30]# /etc/init.d/php-fpm start Starting php-fpm done (启动服务) [root@chy01 php-5.6.30]# ps aux |grep php-fpm root 125159 0.0 0.3 226640 4948 ? Ss 02:13 0:00 php-fpm: master process (/usr/local/php-fpm/etc/php-fpm.conf) php-fpm 125160 0.0 0.3 226640 4712 ? S 02:13 0:00 php-fpm: pool www php-fpm 125161 0.0 0.3 226640 4712 ? S 02:13 0:00 php-fpm: pool www php-fpm 125162 0.0 0.3 226640 4712 ? S 02:13 0:00 php-fpm: pool www php-fpm 125163 0.0 0.3 226640 4712 ? S 02:13 0:00 php-fpm: pool www php-fpm 125164 0.0 0.3 226640 4716 ? S 02:13 0:00 php-fpm: pool www php-fpm 125165 0.0 0.3 226640 4720 ? S 02:13 0:00 php-fpm: pool www php-fpm 125166 0.0 0.3 226640 4720 ? S 02:13 0:00 php-fpm: pool www php-fpm 125167 0.0 0.3 226640 4720 ? S 02:13 0:00 php-fpm: pool www php-fpm 125168 0.0 0.3 226640 4720 ? S 02:13 0:00 php-fpm: pool www php-fpm 125169 0.0 0.3 226640 4720 ? S 02:13 0:00 php-fpm: pool www php-fpm 125170 0.0 0.3 226640 4720 ? S 02:13 0:00 php-fpm: pool www php-fpm 125171 0.0 0.3 226640 4720 ? S 02:13 0:00 php-fpm: pool www php-fpm 125172 0.0 0.3 226640 4720 ? S 02:13 0:00 php-fpm: pool www php-fpm 125173 0.0 0.3 226640 4720 ? S 02:13 0:00 php-fpm: pool www php-fpm 125174 0.0 0.3 226640 4720 ? S 02:13 0:00 php-fpm: pool www php-fpm 125175 0.0 0.3 226640 4720 ? S 02:13 0:00 php-fpm: pool www php-fpm 125176 0.0 0.3 226640 4720 ? S 02:13 0:00 php-fpm: pool www php-fpm 125177 0.0 0.3 226640 4720 ? S 02:13 0:00 php-fpm: pool www php-fpm 125178 0.0 0.3 226640 4720 ? S 02:13 0:00 php-fpm: pool www php-fpm 125179 0.0 0.3 226640 4720 ? S 02:13 0:00 php-fpm: pool www root 125220 0.0 0.0 112664 976 pts/0 R+ 02:15 0:00 grep --color=auto php-fpm [root@chy01 php-5.6.30]# ls -l /tmp/php-fcgi.sock srw-rw-rw- 1 root root 0 8月 10 02:13 /tmp/php-fcgi.sock 4nginx介绍与安装 nginx官网http://nginx.org Nginx应用场景:web服务、反向代理、负载均衡 Nginx著名分支,淘宝基于Nginx开发的Tengine,使用上和Nginx一致,服务名,配置文件名都一样,和Nginx的最大区别在于Tenging增加了一些定制化模块,在安全限速方面表现突出,另外它支持对js,css合并 [root@chy01 src]# wget http://nginx.org/download/nginx-1.12.1.tar.gz (下载nginx安装包) [root@chy01 src]# tar zxvf nginx-1.12.1.tar.gz (解压) [root@chy01 src]./configure --prefix=/usr/local/nginx [root@chy01 src]# cd nginx-1.12.1 (进入到此目录下开始编译) [root@chy01 nginx-1.12.1]# echo $? 0 [root@chy01 nginx-1.12.1]# make && make install [root@chy01 nginx-1.12.1]# echo $? 0 (编译成功) [root@chy01 nginx-1.12.1]# /usr/local/nginx/sbin/nginx -t nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful (-t检查配置文件语法是否错误) [root@chy01 nginx-1.12.1]# vim /etc/init.d/nginx (在启动配置文件中增加如下内容) #!/bin/bash # chkconfig: - 30 21 # description: http service. # Source Function Library . /etc/init.d/functions # Nginx Settings NGINX_SBIN="/usr/local/nginx/sbin/nginx" NGINX_CONF="/usr/local/nginx/conf/nginx.conf" NGINX_PID="/usr/local/nginx/logs/nginx.pid" RETVAL=0 prog="Nginx" start() { echo -n $"Starting $prog: " mkdir -p /dev/shm/nginx_temp daemon $NGINX_SBIN -c $NGINX_CONF RETVAL=$? echo return $RETVAL } stop() { echo -n $"Stopping $prog: " killproc -p $NGINX_PID $NGINX_SBIN -TERM rm -rf /dev/shm/nginx_temp RETVAL=$? echo return $RETVAL } reload() { echo -n $"Reloading $prog: " killproc -p $NGINX_PID $NGINX_SBIN -HUP RETVAL=$? echo return $RETVAL } restart() { stop start } configtest() { $NGINX_SBIN -c $NGINX_CONF -t return 0 } case "$1" in start) start ;; stop) stop ;; reload) reload ;; restart) restart ;; configtest) configtest ;; *) echo $"Usage: $0 {start|stop|reload|restart|configtest}" RETVAL=1 esac exit $RETVAL [root@chy01 nginx-1.12.1]# chmod 755 /etc/init.d/nginx (增加nginx权限) [root@chy01 nginx-1.12.1]# chkconfig --add nginx (将nginx设置为开机自启) [root@chy01 nginx-1.12.1]# cd /usr/local/nginx/conf/ (配置nginx的配置文件,需要先下一个模板) [root@chy01 conf]# mv nginx.conf nginx.conf.1 (因nginx已经有一个配置文件,需要将此配置文件cp并且重新更改一个自己的配置文件) [root@chy01 conf]# vim nginx.conf (配置nginx的配置文件) user nobody nobody; worker_processes 2; error_log /usr/local/nginx/logs/nginx_error.log crit; pid /usr/local/nginx/logs/nginx.pid; worker_rlimit_nofile 51200; events { use epoll; worker_connections 6000; } http { include mime.types; default_type application/octet-stream; server_names_hash_bucket_size 3526; server_names_hash_max_size 4096; log_format combined_realip '$remote_addr $http_x_forwarded_for [$time_local]' ' $host "$request_uri" $status' ' "$http_referer" "$http_user_agent"'; sendfile on; tcp_nopush on; keepalive_timeout 30; client_header_timeout 3m; client_body_timeout 3m; send_timeout 3m; connection_pool_size 256; client_header_buffer_size 1k; large_client_header_buffers 8 4k; request_pool_size 4k; output_buffers 4 32k; postpone_output 1460; client_max_body_size 10m; client_body_buffer_size 256k; client_body_temp_path /usr/local/nginx/client_body_temp; proxy_temp_path /usr/local/nginx/proxy_temp; fastcgi_temp_path /usr/local/nginx/fastcgi_temp; fastcgi_intercept_errors on; tcp_nodelay on; gzip on; gzip_min_length 1k; gzip_buffers 4 8k; gzip_comp_level 5; gzip_http_version 1.1; gzip_types text/plain application/x-javascript text/css text/htm application/xml; server { listen 80; server_name localhost; index index.html index.htm index.php; root /usr/local/nginx/html; location ~ \.php$ { include fastcgi_params; fastcgi_pass unix:/tmp/php-fcgi.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /usr/local/nginx/html$fastcgi_script_name; } } } 如下是配置文件的简单介绍: user nobody nobody; (定义的nginx的用户) worker_processes 2;(定义子进程有几个) error_log /usr/local/nginx/logs/nginx_error.log crit; (定义错误日志) pid /usr/local/nginx/logs/nginx.pid; worker_rlimit_nofile 51200;(定义nginx最多能打开多少个文件) events { use epoll; worker_connections 6000;(进程有多少个连接) } http { include mime.types; default_type application/octet-stream; server_names_hash_bucket_size 3526; server_names_hash_max_size 4096; log_format combined_realip '$remote_addr $http_x_forwarded_for [$time_local]' ' $host "$request_uri" $status' ' "$http_referer" "$http_user_agent"'; sendfile on; tcp_nopush on; keepalive_timeout 30; client_header_timeout 3m; client_body_timeout 3m; send_timeout 3m; connection_pool_size 256; client_header_buffer_size 1k; large_client_header_buffers 8 4k; request_pool_size 4k; output_buffers 4 32k; postpone_output 1460; client_max_body_size 10m; client_body_buffer_size 256k; client_body_temp_path /usr/local/nginx/client_body_temp; proxy_temp_path /usr/local/nginx/proxy_temp; fastcgi_temp_path /usr/local/nginx/fastcgi_temp; fastcgi_intercept_errors on; tcp_nodelay on; gzip on; gzip_min_length 1k; gzip_buffers 4 8k; gzip_comp_level 5; gzip_http_version 1.1; gzip_types text/plain application/x-javascript text/css text/htm application/xml; server { listen 80; server_name localhost; index index.html index.htm index.php; root /usr/local/nginx/html; location ~ \.php$ (配置解析Php) { include fastcgi_params; fastcgi_pass unix:/tmp/php-fcgi.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /usr/local/nginx/html$fastcgi_script_name; } } } [root@chy01 conf]# /usr/local/nginx/sbin/nginx -t nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful (查看nginx配置文件是否有错) [root@chy01 conf]# /etc/init.d/nginx start(这里报了一个错误) Starting nginx (via systemctl): Job for nginx.service failed because the control process exited with error code. See "systemctl status nginx.service" and "journalctl -xe" for details. [失败] (根据提示查错误,[root@chy01 conf]# systemctl status nginx.service ● nginx.service - SYSV: http service. Loaded: loaded (/etc/rc.d/init.d/nginx; bad; vendor preset: disabled) Active: failed (Result: exit-code) since 五 2017-08-11 00:23:23 CST; 36s ago Docs: man:systemd-sysv-generator(8) Process: 5613 ExecStart=/etc/rc.d/init.d/nginx start (code=exited, status=1/FAILURE) 8月 11 00:23:21 chy01 nginx[5613]: nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use) 8月 11 00:23:21 chy01 nginx[5613]: nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use) 8月 11 00:23:22 chy01 nginx[5613]: nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use) 8月 11 00:23:22 chy01 nginx[5613]: nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use) 8月 11 00:23:23 chy01 nginx[5613]: nginx: [emerg] still could not bind() 8月 11 00:23:23 chy01 nginx[5613]: [失败] 8月 11 00:23:23 chy01 systemd[1]: nginx.service: control process exited, code=exited status=1 8月 11 00:23:23 chy01 systemd[1]: Failed to start SYSV: http service.. 8月 11 00:23:23 chy01 systemd[1]: Unit nginx.service entered failed state. 8月 11 00:23:23 chy01 systemd[1]: nginx.service failed. (可以看到提示错误nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use) 提示的意思为80端口被使用) [root@chy01 conf]# /usr/local/apache2.4/bin/apachectl stop (将http关闭) [root@chy01 conf]# /etc/init.d/nginx start Starting nginx (via systemctl): [ 确定 ] (在进行启动,启动成功) [root@chy01 conf]# ps aux |grep nginx root 5655 0.0 0.0 20484 628 ? Ss 00:24 0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf nobody 5656 0.0 0.2 22928 3216 ? S 00:24 0:00 nginx: worker process nobody 5657 0.0 0.2 22928 3216 ? S 00:24 0:00 nginx: worker process root 5672 0.0 0.0 112664 976 pts/0 S+ 00:26 0:00 grep --color=auto nginx (可以看到子进程为root,主进程为nobody) [root@chy01 conf]# curl localhost <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html> (nginx 进行测试) [root@chy01 conf]# vim /usr/local/nginx/html/1.php (创建一个php的测试文件 <?php echo "this is nginx test page"; [root@chy01 conf]# curl localhost/1.php this is nginx test page[root@chy01 conf]# (如上解析成功) 本文转自我不是瘦子51CTO博客,原文链接:http://blog.51cto.com/chy940405/2049295,如需转载请自行联系原作者

优秀的个人博客,低调大师

Linux基础之任务计划(at,crontab)

在linux系统中你可能已经发现了为什么系统常常会自动的进行一些任务?这些任务到底是谁在支配他们工作的?在linux系统如果你想要让自己设计的备份程序可以自动在某个时间点开始在系统底下运行,而不需要手动来启动它,又该如何处置呢? 这些例行的工作可能又分为一次性定时工作与循环定时工作,在系统内又是哪些服务在负责? 命令at及crontab可以解决上述问题 at:未来的某时间点执行一次某任务 crontab:用于周期性运行某任务 二者的执行结果或通过邮件发送给用户。 at命令 通过命令yum provides atd查看at的包名 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 yumprovidesatdroot@localhost Loadedplugins:fastestmirror Loadingmirrorspeedsfromcachedhostfile base /7/x86_64/filelists_db |6.7MB00:00:00 epel /x86_64/filelists_db |8.1MB00:00:00 extras /7/x86_64/filelists_db |391kB00:00:00 updates /7/x86_64/filelists_db |1.5MB00:00:00 zabbix /x86_64/filelists_db |53kB00:00:00 zabbix-non-supported /x86_64/filelists |660B00:00:00 at-3.1.13-22.el7.x86_64:Jobspoolingtools Repo:base Matchedfrom: Filename: /usr/sbin/atd at-3.1.13-22.el7.x86_64:Jobspoolingtools Repo:@base Matchedfrom: Filename: /usr/sbin/atd 常用格式:at [option] ... TIME at允许使用一套相当复杂的指定时间的方法。他能够接受在当天的hh:mm(小时:分钟)式的时间指定。假如该时间已过去,那么就放在第二天执行。当然也能够使用midnight(深夜),noon(中午),teatime(饮茶时间,一般是下午4点)等比较模糊的 词语来指定时间。用户还能够采用12小时计时制,即在时间后面加上AM(上午)或PM(下午)来说明是上午还是下午。 也能够指定命令执行的具体日期,指定格式为month day(月 日)或mm/dd/yy(月/日/年)或dd.mm.yy(日.月.年)。指定的日期必须跟在指定时间的后面。 上面介绍的都是绝对计时法,其实还能够使用相对计时法,这对于安排不久就要执行的命令是很有好处的。指定格式为:now + count time-units ,now就是当前时间,time-units是时间单位,这里能够是minutes(分钟)、hours(小时)、days(天)、weeks(星期)。count是时间的数量,究竟是几天,还是几小时,等等。 更有一种计时方法就是直接使用today(今天)、tomorrow(明天)来指定完成命令的时间。 TIME:时间格式,这里可以定义出什么时候要进行 at 这项任务的时间,格式有: HH:MM ex>04:00 在今日的 HH:MM 时刻进行,若该时刻已超过,则明天的 HH:MM 进行此任务。 HH:MM YYYY-MM-DD ex>04:00 2016-09-19 强制规定在某年某月的某一天的特殊时刻进行该项任务 HH:MM[am|pm] [Month] [Date] ex>04pm September 17 也是一样,强制在某年某月某日的某时刻进行该项任务 HH:MM[am|pm] + number [minutes|hours|days|weeks] ex>now + 5 minutes ex>04pm + 3 days 就是说,在某个时间点再加几个时间后才进行该项任务。 常用选项: -l:查看作业队列,相当于atq -f:从指定文件中读取作业任务,而不用再交互式输入 -d:删除指定的作业,相当于atrm -c:查看指定作业的具体内容 -q:指明队列 注:作业执行结果是以邮件发送给提交作业的用户 在使用at命令前,我们需要先确认at所依赖的atd进程是否启用,使用命令:ps -ef | grep atd查看,若未启用则用/etc/init.d/atd start or restart开启。 执行方式: 1)交互式,在命令输入完成后使用ctrl+d保存退出;2)输入重定向;3)at -f 文件 示例1:2分钟后使用ls命令展开/tmp目录(交互式命令输入结束后使用ctrl+d保存退出) 1 2 3 4 [root@docker~] #atnow+2minutes at> ls /tmp at><EOT> job7atSunSep1809:17:002016 命令执行结果在mail里面看 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 [root@docker~] #mail HeirloomMailversion12.57 /5/10 .Type? for help. "/var/spool/mail/root" :9messages1unread 1user@localhost. local TueJul1916:4690 /2915 "[abrt]fullcrashreport" 2docker@docker.localdThuSep811:0016 /568 "Outputfromyourjob1" 3user@localhost. local MonSep1210:31353 /15306 "[abrt]fullcrashreport" 4user@localhost. local MonSep1210:31443 /17535 "[abrt]fullcrashreport" 5rootSunSep1809:0423 /998 "Outputfromyourjob3" 6rootSunSep1809:0819 /827 "Outputfromyourjob4" 7rootSunSep1809:13275 /2986 "Outputfromyourjob5" 8rootSunSep1809:1526 /552 "Outputfromyourjob6" >U9rootSunSep1809:1718 /776 "Outputfromyourjob7" >U9rootSunSep1809:1718 /776 "Outputfromyourjob7" &9 Message9: Fromroot@docker.localdomainSunSep1809:17:012016 Return-Path:<root@docker.localdomain> X-Original-To:root Delivered-To:root@docker.localdomain Subject:Outputfromyourjob7 To:root@docker.localdomain Date:Sun,18Sep201609:17:01+0800(CST) From:root@docker.localdomain(root) Status:RO systemd-private-2c8c4ebab1524b5c9f463bd2ec8ffea7-colord.service-gyAadP systemd-private-2c8c4ebab1524b5c9f463bd2ec8ffea7-cups.service-6gB4MM systemd-private-2c8c4ebab1524b5c9f463bd2ec8ffea7-rtkit-daemon.service-25oPVw systemd-private-2c8c4ebab1524b5c9f463bd2ec8ffea7-vmtoolsd.service-sW2CqM 示例2:明天14点中,重启系统。(使用输入重定向实现) 1 2 3 4 5 6 [root@docker~] #at14:00tomorrow>>time1<<eof >reboot >eof job8atMonSep1914:00:002016 [root@docker~] #atq 8MonSep1914:00:002016aroot 示例3:删除示例2的计划任务 1 2 [root@docker~] #at-d8 [root@docker~] #atq at命令的执行权限: 配置文件/etc/at.{allow,deny}决定了允许哪些用户可以使用at命令,哪些用户不可以。 加上这两个文件后, at 的工作情况是这样的: 先找寻 /etc/at.allow 这个文件,写在这个文件中的使用者才能使用 at ,没有在这个文件中的使用者则不能使用 at (即使没有写在 at.deny 当中); 如果 /etc/at.allow 不存在,就寻找 /etc/at.deny 这个文件,若写在这个 at.deny 的使用者则不能使用 at ,而没有在这个 at.deny 文件中的使用者,就可以使用 at 命令了。 如果两个文件都不存在,那么只有 root 可以使用 at 这个命令。 透过这个说明,我们知道 /etc/at.allow 是管理较为严格的方式,而 /etc/at.deny 则较为松散 (因为帐号没有在该文件中,就能够运行 at 了)。在一般的 distributions 当中,由于假设系统上的所有用户都是可信任的, 因此系统通常会保留一个空的 /etc/at.deny 文件,意思是允许所有人使用 at 命令的意思 (您可以自行检查一下该文件)。 不过,万一你不希望有某些使用者使用 at 的话,将那个使用者的帐号写入 /etc/at.deny 即可! 一个帐号写一行。 crontab命令 通过命令yum provides crontab查看crontab命令的包名 1 2 3 4 5 6 7 8 9 10 11 yumprovides crontab root@localhost Loadedplugins:fastestmirror Loadingmirrorspeedsfromcachedhostfile cronie-1.4.11-17.el7.x86_64:Crondaemon for executingprogramsat set times Repo:base Matchedfrom: Filename: /usr/bin/crontab cronie-1.4.11-14.el7_2.1.x86_64:Crondaemon for executingprogramsat set times Repo:@anaconda Matchedfrom: Filename: /usr/bin/crontab cron来源于希腊单词chronos(意为“时间”),是linux系统下一个周期性自动执行指定任务的程序 在使用cron前,需要确认crond守护进程处于运行状态,才能保证cron的正常运行。 可以通过命令:systemctl status crond 及ps -ef | grep crond查看服务cron是否处于运行状态。 向crond提交作业的方式与at不同,它需要使用专用的配置文件,此文件有固定格式,不建议使用文本编辑器直接编辑此文件;需要使用crontab命令; cron任务分为两类: 系统cron任务:主要用于实现系统自身的维护 手动编辑/etc/crontab文件 用户cron任务:使用命令crontab /etc/crontab文件 注: 1)每一行定义一个周期性任务;共7个字段 * * * * * :定义周期性时间 username:运行任务的用户身份 command to be executed:要执行的任务 2)此处的环境变量不同于用户登陆后获得的环境,因此建议命令使用绝对路径,或定义PATH环境变量 3)执行结果邮件发送给MAILTO指定的用户(发送给运行任务的用户) 时间表示法: (1)特定值; 给定时间点有效取值范围内的值; (2)* 给定时间点上有效取值范围内的所有值; 表示“每...”; 示例: 1> 3 * * * * :每小时的第三分钟执行一次 2> 3 4 * * 5 :每周的周五4:03执行一次 3> 5 6 7 * * :每月的7号6:05执行一次 4> 7 8 9 10 * :每年10月9号8点7分执行一次 (3)离散取值:在时间上使用逗号分隔的多个值:#,#,# 示例: 5> 9 8 * * 3,7 :每周三周日的8点9分执行一次 6> 0 8,20 * * 3,7 :每周三周日的8:00跟20:00执行一次 (4)连续取值:在时间点上使用-链接开头和结束:#-# 示例: 7> 0 9-18 * * 1-5 :从周一到周五的9点到18点每小时执行一次 (5)在指定时间范围上,定义步长: /#: #即为步长 注:1)指定时间点不能被步长整除时,其意义将不复存在: 2)最小时间单位为“分钟”,想完成“秒”级任务,需要借助于其他机制:定义成每分钟任务,而在利用脚本实现的每分钟之内循环多次 用户cron crontab命令定义,每个用户都有专用的cron任务文件:/var/spool/cron/USERNAME 只有该用户定义了cron任务才能通过该文件看到相应信息。 注:1)每行定义一个cron任务,共6个字段(不需要指定用户);2)邮件发送给当前用户 crontab命令 使用格式: crontab [-u user] [-l | -r | -e] [-i] -l: 列出所有任务; -e: 编辑任务; -r: 移除所有任务; -i:同-r一同使用,以交互式模式让用户有选择地移除指定任务; -u user: 仅root可运行,代为为指定用户管理cron任务; 注意:运行结果以邮件通知给相关用户;如果不想接收邮件则可使用如下命令实现 (1) COMMAND > /dev/null (2) COMMAND &> /dev/null 思考: (1) 如何在秒级别运行任务? * * * * * for min in 0 1 2; do echo "hi"; sleep 20; done (2) 如何实现每7分钟运行一次任务? sleep命令: sleep NUMBER[SUFFIX]... SUFFIX: s: 秒, 默认 m: 分 h: 小时 d: 天 练习: 1、每4小时备份一次/etc目录至/backup目录中,保存的文件名称格式为“etc-yyyy-mm-dd-HH.tar.xz”; 在/etc/crontab文件中添加如下: 1 2 3 4 5 6 7 04***. /test/bak_etc cat bak_etc #!/bin/bash #bakup/etcdiratory #autherchawandate:20160908 cp /etc/ * /bakup/etc $( date +%F-%H) xz /bakup/etc $( date +%F-%H) 2、每周2, 4, 7备份/var/log/messages文件至/logs目录中,文件名形如“messages-yyyymmdd”; * * * * 2,4,7 ./test/logs 1 2 3 4 5 cat /test/logs #!/bin/bash #bakup/var/log/messagesto/logs cp /var/log/messages /logs/messages $( date +%F) xz /logs/messages $( date +%F) 3、每两小时取出当前系统/proc/meminfo文件中以S或M开头的信息追加至/tmp/meminfo.txt文件中; 1 02*** cat /proc/meminfo | grep "^[SM]" >> /tmp/meminfo .txt 4、工作日时间内,对用户docker每小执行一次“ip addr show”命令; 切换至docker用户使用命令crontab -e进入编辑界面 加入"0 9-18 * * 1-5 docker ip addr show"信息后保存退出 1 2 [docker@docker~]$ crontab -l 09-18**1-5ipaddrshow 本文转自 紫色的茶碗 51CTO博客,原文链接:http://blog.51cto.com/chawan/1853509,如需转载请自行联系原作者

优秀的个人博客,低调大师

消息中间件(一)基础

消息中间件是用于分步式系统之间收发消息的组件。 消息中间件的作用 1. 应用解耦 2. 异步处理 比如用户注册场景,注册主流程完成以后,需要调用邮件系统发送邮件通知用户注册成功,可能还需要调用其他系统。这是串行的,如果一个系统依赖很多系统,那么这个主流程会比较长,耦合度高,整个系统维护成本也会越来越高。那么我们就可以使用消息中间件来进行解耦,通过发布订阅模式,完成用户注册之后,向中间件发送消息,这样就可以马上给用户返回,至于后续工作其他系统向中间件订阅这个消息并完成后续工作就好。这也就是一个解耦和异步处理过程。 中间件有下面两种模型 点对点模型 发布订阅模型 消息中间件的解耦和异步是两个最重要的需求点,除此之外还应该做一些其他事情比如: 保证一致性,产生消息和发送消息是一致的,也就是如果操作成功,那么消息一定发送成功;如果业务操作没有成功那么就不能发送消息 具备一定消息堆积能力,可以为后端挡住一些数据流保证后端不会被压垮 具备消息实时性,保证消息的低延迟 具备消息的可靠性,主要是可靠地存储和投递 消息系统里面应该有这样一个假设:消息一定会堆积。下游系统通常有很多,里面有重要的也不重要的,面对突发流量高峰,一定会有后端系统处理不过来的情况,从而造成消息堆积;当然还有一种情况是后端系统出现问题导致暂时无法消费消息从而造成消息中间件的消息堆积。所以中间件要起到蓄水池的作用。 数据一致性,这个很容易理解,因为是分布式异步的,但是又不能容忍数据出错,所以在性能和数据一致性方面就需要有所妥协,通常在互联网行业中采取最终一致性。需要注意的是最终一致性和弱一致性不同,弱一致性表示允许在异常情况下数据可能不一致,而最终一致性则是在某段时间内允许不一致但是最终会一致。 本文转自linuxjavachen 51CTO博客,原文链接:http://blog.51cto.com/littledevil/2068474,如需转载请自行联系原作者

优秀的个人博客,低调大师

【Android 基础】TextView的属性详解

android:autoLink :设置是否当文本为URL链接/email/电话号码/map时,文本显示为可点击的链接。可选值(none/web /email/phone/map/all) android:autoText :如果设置,将自动执行输入值的拼写纠正。此处无效果,在显示输入法并输入的时候起作用。 android:bufferType : 指定getText()方式取得的文本类别。选项editable 类似于StringBuilder :可追加字符,也就是说getText后可调用append方法设置文本内容。spannable :则可在给定的字符区域使用样式,参见这里1、这里2。 android:capitalize :设置英文字母大写类型。此处无效果,需要弹出输入法才能看得到,参见EditView此属性说明。 android:cursorVisible:设定光标为显示/隐藏,默认显示。 android:digits:设置允许输入哪些字符。如“1234567890.+-*/% ()” android:drawableBottom:在text的下方输出一个drawable,如图片。如果指定一个颜色的话会把text的背景设为该颜色,并且同时和background使用时覆盖后者。 android:drawableLeft:在text的左边输出一个drawable,如图片。 android:drawablePadding:设置text与drawable(图片)的间隔,与drawableLeft、 drawableRight、drawableTop、drawableBottom一起使用,可设置为负数,单独使用没有效果。 android:drawableRight:在text的右边输出一个drawable。 android:drawableTop:在text的正上方输出一个drawable。 android:editable:设置是否可编辑。 android:editorExtras:设置文本的额外的输入数据。 android:ellipsize:设置当文字过长时,该控件该如何显示。有如下值设置:”start”—?省略号显示在开头;”end” ——省略号显示在结尾;”middle”—-省略号显示在中间;”marquee” ——以跑马灯的方式显示(动画横向移动) android:freezesText:设置保存文本的内容以及光标的位置。 android:gravity:设置文本位置,如设置成“center”,文本将居中显示。 android:hintText:为空时显示的文字提示信息,可通过textColorHint设置提示信息的颜色。此属性在 EditView中使用,但是这里也可以用。 android:imeOptions:附加功能,设置右下角IME动作与编辑框相关的动作,如actionDone右下角将显示一个“完成”,而不设置默认是一个回车符号。这个在EditView中再详细说明,此处无用。 android:imeActionId:设置IME动作ID。 android:imeActionLabel:设置IME动作标签。 android:includeFontPadding:设置文本是否包含顶部和底部额外空白,默认为true。 android:inputMethod:为文本指定输入法,需要完全限定名(完整的包名)。例如:com.google.android.inputmethod.pinyin,但是这里报错找不到。 android:inputType:设置文本的类型,用于帮助输入法显示合适的键盘类型。在EditView中再详细说明,这里无效果。 android:linksClickable:设置链接是否点击连接,即使设置了autoLink。 android:marqueeRepeatLimit:在ellipsize指定marquee的情况下,设置重复滚动的次数,当设置为 marquee_forever时表示无限次。 android:ems:设置TextView的宽度为N个字符的宽度。这里测试为一个汉字字符宽度 android:maxEms:设置TextView的宽度为最长为N个字符的宽度。与ems同时使用时覆盖ems选项。 android:minEms:设置TextView的宽度为最短为N个字符的宽度。与ems同时使用时覆盖ems选项。 android:maxLength:限制显示的文本长度,超出部分不显示。 android:lines:设置文本的行数,设置两行就显示两行,即使第二行没有数据。 android:maxLines:设置文本的最大显示行数,与width或者layout_width结合使用,超出部分自动换行,超出行数将不显示。 android:minLines:设置文本的最小行数,与lines类似。 android:lineSpacingExtra:设置行间距。 android:lineSpacingMultiplier:设置行间距的倍数。如”1.2” android:numeric:如果被设置,该TextView有一个数字输入法。此处无用,设置后唯一效果是TextView有点击效果,此属性在EdtiView将详细说明。 android:password:以小点”.”显示文本 android:phoneNumber:设置为电话号码的输入方式。 android:privateImeOptions:设置输入法选项,此处无用,在EditText将进一步讨论。 android:scrollHorizontally:设置文本超出TextView的宽度的情况下,是否出现横拉条。 android:selectAllOnFocus:如果文本是可选择的,让他获取焦点而不是将光标移动为文本的开始位置或者末尾位置。 TextView中设置后无效果。 android:shadowColor:指定文本阴影的颜色,需要与shadowRadius一起使用。 android:shadowDx:设置阴影横向坐标开始位置。 android:shadowDy:设置阴影纵向坐标开始位置。 android:shadowRadius:设置阴影的半径。设置为0.1就变成字体的颜色了,一般设置为3.0的效果比较好。 android:singleLine:设置单行显示。如果和layout_width一起使用,当文本不能全部显示时,后面用“…”来表示。如android:text="test_ singleLine " android:singleLine="true" android:layout_width="20dp"将只显示“t…”。如果不设置singleLine或者设置为false,文本将自动换行 android:text:设置显示文本. android:textAppearance:设置文字外观。如 “?android:attr/textAppearanceLargeInverse”这里引用的是系统自带的一个外观,?表示系统是否有这种外观,否则使用默认的外观。可设置的值如下:textAppearanceButton/textAppearanceInverse/textAppearanceLarge/textAppearanceLargeInverse/textAppearanceMedium/textAppearanceMediumInverse/textAppearanceSmall/textAppearanceSmallInverse android:textColor:设置文本颜色 android:textColorHighlight:被选中文字的底色,默认为蓝色 android:textColorHint:设置提示信息文字的颜色,默认为灰色。与hint一起使用。 android:textColorLink:文字链接的颜色. android:textScaleX:设置文字之间间隔,默认为1.0f。 android:textSize:设置文字大小,推荐度量单位”sp”,如”15sp” android:textStyle:设置字形[bold(粗体) 0, italic(斜体) 1, bolditalic(又粗又斜) 2] 可以设置一个或多个,用“|”隔开 android:typeface:设置文本字体,必须是以下常量值之一:normal 0, sans 1, serif 2, monospace(等宽字体) 3] android:height:设置文本区域的高度,支持度量单位:px(像素)/dp/sp/in/mm(毫米) android:maxHeight:设置文本区域的最大高度 android:minHeight:设置文本区域的最小高度 android:width:设置文本区域的宽度,支持度量单位:px(像素)/dp/sp/in/mm(毫米),与layout_width 的区别看这里。 android:maxWidth:设置文本区域的最大宽度 android:minWidth:设置文本区域的最小宽度 附件:Android中的长度单位详解 Android中的长度单位详解(dp、sp、px、in、pt、mm)有很多人不太理解dp、sp 和px 的区别:现在这里介绍一下dp 和sp。dp 也就是dip。这个和sp 基本类似。如果设置表示长度、高度等属性时可以使用dp 或sp。但如果设置字体,需要使用sp。dp 是与密度无关,sp 除了与密度无关外,还与scale 无关。如果屏幕密度为160,这时dp 和sp 和px 是一样的。1dp=1sp=1px,但如果使用px 作单位,如果屏幕大小不变(假设还是3.2 寸),而屏幕密度变成了320。那么原来TextView 的宽度设成160px,在密度为320 的3.2 寸屏幕里看要比在密度为160 的3.2 寸屏幕上看短了一半。但如果设置成160dp 或160sp 的话。系统会自动将width 属性值设置成320px 的。也就是160 * 320 / 160。其中320 / 160 可称为密度比例因子。也就是说,如果使用dp 和sp,系统会根据屏幕密度的变化自动进行转换。 其他单位的含义 px:表示屏幕实际的象素。例如,320*480 的屏幕在横向有320个象素,在纵向有480 个象素。 in:表示英寸,是屏幕的物理尺寸。每英寸等于2.54 厘米。例如,形容手机屏幕大小,经常说,3.2(英)寸、3.5(英)寸、4(英)寸就是指这个单位。这些尺寸是屏幕的对角线长度。如果手机的屏幕是3.2 英寸,表示手机的屏幕(可视区域)对角线长度是3.2*2.54 = 8.128 厘米。读者可以去量一量自己的手机屏幕,看和实际的尺寸是否一致。 mm:表示毫米,是屏幕的物理尺寸。 pt:表示一个点,是屏幕的物理尺寸。大小为1 英寸的1/72。 本文转自叶超Luka博客园博客,原文链接:http://www.cnblogs.com/yc-755909659/archive/2012/08/18/2645415.html,如需转载请自行联系原作者

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册