Java使用BOM判断一个文件是不是UTF-8文件
查看16进制的源文件
例如test_utf8.py这个文件用的是utf-8+BOM编码的.
现在打开这个文件,然后以16进制的方式查看该文件。
可以看到该文件以EF BB BF
这三个字节开头,这三个字节表示该文件是UTF-8编码的。EF BB BF
转成字节表示就是-17,-69,-65
.不信来看下面的代码:
1 | public static void main(String[] args) |
运行结果:-17,-69,-65
判断文件是不是udf-8加BOM
利用BOM判断一个文件是不是utf-8文件:
1 | /** |
测试:
1 | public static void main(String[] args) throws IOException |
运行结果:
1 | D:\学习\python\test_utf8.py是utf-8编码的文件:true |
缺点
这么做的问题是只能判断带BOM的文件,如果不带BOM那就不好判断了。例如把上面的文件从utf-8+BOM改成utf-8格式,然后保存。
再切换到16进制视图查看:
可以看到不带BOM的utf-8格式的文件不以EF BB BF
这三个字节开头,这样来上述的方法就不好使了。
运行结果:
1 | D:\学习\python\test_utf8.py是utf-8编码的文件:false |
可以看到我明明是utf-8的文件,但是判断的结果却是false。
Hexo搭建
基本配置
Hexo安装
安装nodejs
安装Hexo
1 | npm install hexo-cli -g |
修改菜单
在菜单中添加链接。编辑 主题配置文件 , 取消categories
前面的注释#
,添加 categories 到 menu 中,如下:
1 | menu: |
然后,开启本地服务器,显示效果如下:
添加标签页面
创建页面
1 | hexo new page tags |
打开菜单
1 | menu: |
设置代码高亮主题
NexT 使用 Tomorrow Theme 作为代码高亮,共有5款主题供你选择。 NexT 默认使用的是 白色的 normal 主题,可选的值有 normal,night, night blue, night bright, night eighties:
在主题配置文件中,更改 highlight_theme
字段,将其值设定成你所喜爱的高亮主题,例如:
1 | highlight_theme: night |
这样,代码框部分就显示如下了。这个根据个人喜好配置。
设置头像
打开主题配置文件,查找avatar
,设置头像的路径(url):
1 | # Sidebar Avatar |
配置解释:
url: /images/avatar.jpg
,这个表示头像的路径在博客站点目录下source
目录下的images
目录下。这就是这样的形式\blog7\source\images
。rounded: true
表示图像显示的方式,false则显示方形,true则显示圆形rotated: false
表示当鼠标碰到头像的时候,是否旋转头像.opacity: 1
这个是不透明度值,可以设置从0到1的任意小数,如设置为0.5.
设置图标
在主题配置文件中,查找favicon:
,然后设置对应的图片。图片路径还是在博客站点目录下source
目录下的images
目录下。这就是这样的形式\blog7\source\images
。
1 | favicon: |
还有就是图片的名字不要乱改成其他名字,使用配置文件中默认的即可.这样在后续重新搭建一个hexo博客的时候,就可以吧images
目录直接复制过去使用.就不用再浪费时间重新配置一次。
图标显示N的问题
上面的设置后就可以正常显示图标了,如果图标还没显示出来,按下Ctrl+F5
直接从服务器加载开开.如果还不行的话,到主题的图标文件夹:\blog7\themes\next\source\images
中删除,或者替换同名的图片即可,也就是:
1 | favicon-16x16-next.png |
还有就是替换loading.gif
可以实现自定义的图片加载效果。
开启打赏
在主题配置文件中,查找reward:
然后设置对应的图片即可。图片要先放到博客站点目录下source
目录下的images
目录下。这就是这样的形式\blog7\source\images
。
1 | reward: |
修改内容区域显示宽度
http://theme-next.iissnan.com/faqs.html#custom-content-width
如何更改内容区域的宽度?
NexT 对于内容的宽度的设定如下:
- 700px,当屏幕宽度 < 1600px
- 900px,当屏幕宽度 >= 1600px
- 移动设备下,宽度自适应
如果你需要修改内容的宽度,同样需要编辑样式文件。 编辑主题的source/css/_variables/custom.styl
文件,新增变量:1
2
3
4// 修改成你期望的宽度
$content-desktop = 700px
// 当视窗超过 1600px 后的宽度
$content-desktop-large = 900px修改代码块字体
默认的字体太大了,会溢出代码块,为了避免反复拖拽滚动条,我选择把字体改小。
http://theme-next.iissnan.com/faqs.html#custom-font
编辑主题下的source/css/_variables/custom.styl
文件,新增下面变量变量:我这里调整代码时为了在移动端,可以多看点,免得我反复拖动.1
2// 代码字体的大小
$code-font-size = 12px插件
插件库
https://hexo.io/plugins/本地搜索
hexo-generator-search安装
1
npm install hexo-generator-search --save
修改站点配置文件
添加:1
2
3
4search:
path: search.xml
field: post
content: true修改Next主题配置文件
找到local_search:
,把enable改为true即可。1
2local_search:
enable: truegithub远程仓库推送
插件github:hexo-deployer-git
安装
1 | npm install hexo-deployer-git --save |
修改站点配置文件
1 | # Deployment |
持久化链接
插件位置:hexo-abbrlink
安装
1 | npm install hexo-addlink --save |
修改站点配置文件
站点配置文件
中查找permalink
:,把permalink: :year/:month/:day/:title/
修改为:
1 | permalink: blog/:abbrlink/ #blog可以修改为其他信息,blog |
站点配置文件
中设置算法:
1 | abbrlink: |
文章置顶
卸载hexo-generator-index插件
hexo站点目录下,输入下面命令卸载插件
1 | npm uninstall hexo-generator-index --save |
安装hexo-generator-index-pin-top插件
hexo站点目录下,输入下面命令安装插件
1 | npm install hexo-generator-index-pin-top --save |
添加front-matter
配置项
在需要置顶的文章的Front-matter
中加上top: true
即可实现文章置顶功能。
问题
端口被占用 则修改端口
临时改动
如果你想修改端口,可以通过如下命令来指定端口:
1 | hexo s -p 4007 |
这个是临时改动而已,当你下一次使用hexo s
,来启动的时候还是在默认端口4000
.
永久改动
永久改动的话,有的人推荐修改hexo-server
的源文件,但是我不建议这么做,这里可以通过批处理文件
实现,免去每次手动写出hexo s -p 4007
,首先创建一个名字为启动博客.bat
的批处理文件,然后写上如下几条命令:
1 | ::关闭回显 |
然后把启动博客.bat
放到桌面中,下次点击一下就可以在4007端口下启动博客了。这样做的好处就是可以,启动多个网站.
自定义样式
修改的文件位置:blog7\themes\next\source\css\_custom\custom.styl
.
修改代码段样式
打开blog7\themes\next\source\css\_custom\custom.styl
这个文件,添加如下的样式代码:
1 | /* 自定义代码块样式 */ |
这个样式是我从CSDN上的代码段样式中复制下来的,个人觉得比较好看.
参考资料
linux下删除目录及其子目录下某种类型文件
问题描述
Linux下,如果想要删除目录及其子目录下某种类型文件,比如说所有的txt文件,则可以使用下面的命令:
命令
1 | find . -name "*.txt" -type f -print -exec rm -rf {} \; |
执行结果:
1 | $ find . -name "*.txt" -type f -print -exec rm -rf {} \; |
可以看到,当前目录下的a.txt
,b.txt
,子目录./Java/
下的c.txt
,子目录./其他/
下的d.txt
都被删除掉了。
参数说明
.
: 表示在当前目录下
1 | -name "*.txt" |
表示查找所有后缀为txt的文件
1 | -type f |
表示文件类型为一般正规文件
1 |
表示将查询结果打印到屏幕上
1 | -exec command |
command
为其他命令,-exec
后可再接其他的命令来处理查找到的结果,上式中,{}
表示”由find
命令查找到的结果“,如上所示,find所查找到的结果放置到{}位置,-exec一直到”;“是关键字,表示find
额外命令的开始(-exec
)到结束(\;
),这中间的就是find命令的额外命令,上式中就是 rm -rf
参考资料
JavaIO流 节点流和处理流
常用处理流(关闭处理流使用关闭里面的节点流)
- 缓冲流:BufferedInputStrean BufferedOutputStream BufferedReader BufferedWriter—增加缓冲功能,避免频繁读写硬盘。
- 转换流:InputStreamReader OutputStreamReader实现字节流和字符流之间的转换。
- 数据流 DataInputStream DataOutputStream 等-提供将基础数据类型写入到文件中,或者读取出来.
流的关闭顺序
- 一般情况下是:先打开的后关闭,后打开的先关闭
- 另一种情况:看依赖关系,如果流a依赖流b,应该先关闭流a,再关闭流b。例如,处理流a依赖节点流b,应该先关闭处理流a,再关闭节点流b
- 可以只关闭处理流,不用关闭节点流。处理流关闭的时候,会调用其处理的节点流的关闭方法。
注意:
- 如果将节点流关闭以后再关闭处理流,会抛出IO异常。
- 如果关闭了处理流,在关闭与之相关的节点流,也可能出现IO异常。(hadoop编程文件流操作中遇到了。)
总结:通常在IO的继承树中,继承自Filter开头的流
或者转换流(InputStreamReader,OutputStreamReader)都是处理流,其他的都是节点流。
正则表达式 匹配IP地址
正则表达式匹配IP地址
正则表达式,又称规则表达式。接下来通过本文给大家介绍正则表达式匹配
IP
的表达式,非常不错,具有参考借鉴价值,需要的的朋友参考下吧
这里给大家详细讲解一下一个匹配IP地址的正则表达式,
有关正则方面的知识,会在详细的讲解中提到。
在讲解之前,我先给大家介绍一下,ip地址的生成规则。
IP地址,是由32位数字二进制转为四个十进制的字符串组成。
怎么转化?下面讲解:
二进制:11111111111111111111111111111111
分为四部分:11111111.11111111.11111111.11111111
转化:2^7+2^6+2^5+2^4+2^3+2^2+2^1+2^0=255
转为十进制范围:0~255.0~255.0~255.0~255
这就是IP
地址的范围。
根据这个生成IP
的规则和范围,我们可以用正则表达式来匹配出IP
地址,但怎么匹配呢?各人有各人的方法,这里我讲解一下我的思路。
根据IP地址的字符串规律,我把匹配IP地址的表达式分为两部分来考虑。
第一部分:匹配3个0~255.
(注意后面的一个点)
第二部分:匹配最后的数字0~255
也就是说,先匹配出 0~255.
(注意后面的一个点) 这个字符串,然后重复匹配3次,然后再匹配最后的数字部分0~255。这就是我匹配IP
地址的思路。
首先,我要提一下,正则是没有办法做数字运算的,所以,我们无法用数字运算的方式筛选出IP的数字范围。既然没法用数字运算的方式筛选出IP的数字范围,那么我们应该用什么其他方式来筛选这个数字范围呢?我的思路是分组讨论,然后再把这些分组合并起来组成IP的数字范围。
匹配一个合法的数字
三位数的情况:
- 假设百位是
2
,那么根据IP
数字的范围规则,这里又要分为两种情况,为什么?你想想,最大数字是255
,当十位数为5
时,个位数最大只能为5
是吧?(250-255
).而当十位数为0到4
时,个位数可以是任意数字对吧?(200-249
)
所以,这里的两种情况分别为:2[0-4][0-9]
25[0-5]
- 假设百位数是
1
,那么这个数字的范围为100-199
,对应正则表达式就为1[0-9][0-9]
。这个应该不难理解,就不解释。
两位数的情况
分析完了三位数的情况,接下来就是两数的情况了,假如是两位数,那么十位数的前面第一个数不能为零是吧?也就是范围为10-99
(10,11...,19,20,...,99
),对应的正则表达式为[1-9][0-9]
一位数的情况
剩下的就是个位数的情况了,个位数的情况,大家应该很容易得出结论,就是:[0-9]
。
四种情况分析下来,我们得出了IP数字的范围分组为:
25[0-5]
2[0-4][0-9]
1[0-9][0-9]
[1-9][0-9]
[0-9]
匹配一个合法的数字
所以匹配IPv4中一个和法的数组的正则表达式为(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])
优化:
- 可以把两位数的正则
[1-9][0-9]
和一位数的正则[0-9]
合并,写为[1-9]?[0-9]
. - 用简写
\d
替代[0-9]
所以优化后的一个合法的数字的正则表达式为:(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)
匹配一个合法的数字和点号三次 ##:
需要注意的是,点号要转义为\.
,所以得到的正则表达式为:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}
最终的表达式:
三组数字和点号之后,后面还有一组数字。这样的话综合起来就是:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)
优化:
上面我们使用了括号(...)
来限定量词和多选的作用范围。但是这样也会在匹配的时候进行捕获,捕获的话会造成不必要的开销,这里使用(?:...)
来限定,这样省去捕获分组的开销。(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)
总结
匹配IP地址中的一个数
支持0开头,捕获分组:
1 | (25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]?\d) |
不支持0开头,不捕获分组:
1 | (?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d) |
不支持0开头,匹配整个IP地址
1 | (?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d) |
匹配整个IP地址,并捕获每个数字:
1 | (25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]?\d)\.(25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]?\d)\.(25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]?\d)\.(25[0-5]|2[0-4]\d|[0-1]\d{2}|[1-9]?\d) |
markdown表格支持单元格合并
问题描述
MarkDown语法并不支持表格单元格合并,不过可以插入html表格标签来实现。
1 | <table> |
效果
序号 | OSI的体系结构 | TCP/IP的体系结构 |
---|---|---|
7 | 应用层 | 应用层 (各种应用层协议如 TELNET, FTP, SMTP 等) |
6 | 表示层 | |
5 | 会话层 | |
4 | 传输层 | 传输层 |
3 | 网络层 | 互连网络层 |
2 | 数据链路层 | 网络接入层 |
1 | 物理层 |
1 | <table><tr><th>序号</th><th>OSI的体系结构</th> <th>TCP/IP的体系结构</th></tr><tr><td>7</td><td>应用层</td><td rowspan="3">应用层 (各种应用层协议如 TELNET, FTP, SMTP 等)</td></tr><tr><td>6</td><td>表示层</td> </tr><tr><td>5</td><td>会话层</td> </tr><tr><td>4</td> <td>传输层</td> |
序号 | OSI的体系结构 | TCP/IP的体系结构 |
---|---|---|
7 | 应用层 | 应用层 (各种应用层协议如 TELNET, FTP, SMTP 等) |
6 | 表示层 | |
5 | 会话层 | |
4 | 传输层 | 传输层 |
3 | 网络层 | 互连网络层 |
2 | 数据链路层 | 网络接入层 |
1 | 物理层 |
JavaIO流 PrintStream类
继承关系
1 | java.lang.Object |
public class PrintStream extends FilterOutputStream implements Appendable
, Closeable
PrintStream
为其他输出流添加了功能,使它们能够方便地打印各种数据值表示形式。它还提供其他两项功能。与其他输出流不同,PrintStream
永远不会抛出 IOException
;而是,异常情况仅设置可通过 checkError
方法测试的内部标志。另外,为了自动刷新,可以创建一个 PrintStream
;这意味着可在写入 byte
数组之后自动调用 flush
方法,可调用其中一个 println
方法,或写入一个换行符或字节 (‘\n
‘)。
PrintStream
打印的所有字符都使用平台的默认字符编码转换为字节。在需要写入字符而不是写入字节的情况下,应该使用 PrintWriter
类。
构造方法
方法 | 描述 |
---|---|
PrintStream(File file) |
创建具有指定文件且不带自动行刷新的新打印流。 |
PrintStream(File file, String csn) |
创建具有指定文件名称和字符集且不带自动行刷新的新打印流。 |
PrintStream(OutputStream out) |
创建新的打印流。 |
PrintStream(OutputStream out, boolean autoFlush) |
创建新的打印流。 |
PrintStream(OutputStream out, boolean autoFlush, String encoding) |
创建新的打印流。 |
PrintStream(String fileName) |
创建具有指定文件名称且不带自动行刷新的新打印流。 |
PrintStream(String fileName, String csn) |
创建具有指定文件名称和字符集且不带自动行刷新的新打印流。 |
成员方法
write(…)方法
方法 | 描述 |
---|---|
void write(byte[] buf, int off, int len) |
将 len 字节从指定的初始偏移量为 off 的 byte 数组写入此流。 |
void write(int b) |
将指定的字节写入此流。 |
write(int b)源码:
1 | public void write(int b) { |
write(int b)详细描述
将指定的字节写入此流,如果这个字节是换行符而且开启了自动刷新的话,就会调用flush()方法
注意,字节是按给定的方式写入的。 要根据平台的默认字符编码编写一个字符,请使用print(char)或println(char)方法。
参数: b 将要写入的字节
覆盖:类 FilterOutputStream 中的 write
关于自动刷新
所以如果开启了自动刷新,write(int b)方法在写入回车符的时候会调用flush()方法
write(byte buf[], int off, int len)源码
1 | public void write(byte buf[], int off, int len) { |
write(byte buf[], int off, int len)详细描述
将 len 字节从指定的初始偏移量为 off 的 byte 数组写入此流。如果启用自动刷新,则调用 flush 方法。
注意,字节将按给定的方式写入;
要根据平台的默认字符编码来写入,请使用print(char)
或println(char)
方法。
参数: buf 字节数组
参数: off 相对于字节数组开始位置的偏移量
参数: len 需要写入的字节数
print(char c)方法源码
1 | public void print(char c) { |
print(char c)方法详细描述
打印一个字符,根据平台默认字符编码把这个字符转换为一个或者多个字节,然后这些字节完全以write(int)
方法的方式进行写入。
print(int i)方法源码
1 | public void print(int i) { |
print(int i)方法详细描述
打印整数。按照平台的默认字节编码将 String.valueOf(i)
生成的字符串转换为字节,并完全以 write(int)
方法的方式写入这些字节。
参数:
i - 要打印的 int
print(long l)方法源码
1 | public void print(long l) { |
打印
long
整数,按照平台默认字节编码将String.valueOf(l)
生成的字符串转换为字节,并完全以write(int)
方法的方式写入这些字节
1 | public void print(float f) { |
其他print(…)方法源码
1 | public void print(double d) { |
println(…)方法
方法 | 描述 |
---|---|
void println() |
通过写入行分隔符字符串终止当前行。 |
void println(boolean x) |
打印 boolean 值,然后终止行。 |
void println(char x) |
打印字符,然后终止该行。 |
void println(char[] x) |
打印字符数组,然后终止该行。 |
void println(double x) |
打印 double,然后终止该行。 |
void println(float x) |
打印 float,然后终止该行。 |
void println(int x) |
打印整数,然后终止该行。 |
void println(long x) |
打印 long,然后终止该行。 |
void println(Object x) |
打印 Object,然后终止该行。 |
void println(String x) |
打印 String,然后终止该行。 |
println(…)方法源码
1 | /* Methods that do terminate lines */ |
通过写入行分隔符字符串终止当前行。行分隔符字符串由系统属性 line.separator
定义,不一定是单个换行符 (‘\n
‘)。
1 | public void println(boolean x) { |
打印 boolean 值,然后终止行。此方法的行为就像先调用 print(boolean) 然后调用 println() 一样。
参数:
x - 要打印的 boolean
1 | public void println(char x) { |
打印字符,然后终止该行。此方法的行为就像先调用 print(char) 然后调用 println() 一样。
参数:
x - 要打印的 char。
1 | public void println(int x) { |
打印整数,然后终止该行。此方法的行为就像先调用 print(int) 然后调用 println() 一样。
参数:
x - 要打印的 int。
1 | public void println(long x) { |
打印 long,然后终止该行。此方法的行为就像先调用 print(long) 然后调用 println() 一样。
参数:
x - 要打印的 long。
1 | public void println(float x) { |
打印 float,然后终止该行。此方法的行为就像先调用 print(float) 然后调用 println() 一样。
参数:
x - 要打印的 float。
1 | public void println(double x) { |
打印 double,然后终止该行。此方法的行为就像先调用 print(double) 然后调用 println() 一样。
参数:
x - 要打印的 double。
1 | public void println(char x[]) { |
打印字符数组,然后终止该行。此方法的行为就像先调用 print(char[]) 然后调用 println() 一样。
参数:
x - 要打印的字符数组。
1 | public void println(String x) { |
打印 String,然后终止该行。此方法的行为就像先调用 print(String) 然后调用 println() 一样。
参数:
x - 要打印的 String。
1 | public void println(Object x) { |
打印 Object,然后终止该行。此方法首先调用 String.valueOf(x) 获取打印对象的字符串值,然后的行为如同先调用 print(String) 再调用 println() 一样。
参数:
x - 要打印的 Object。
format(…)方法
方法 | 描述 |
---|---|
PrintStream format(Locale l, String format, Object... args) |
使用指定格式字符串和参数将格式化字符串写入此输出流中。 |
PrintStream format(String format, Object... args) |
使用指定格式字符串和参数将格式化字符串写入此输出流中。 |
PrintStream printf(Locale l, String format, Object... args) |
使用指定格式字符串和参数将格式化的字符串写入此输出流的便捷方法。 |
PrintStream printf(String format, Object... args) |
使用指定格式字符串和参数将格式化的字符串写入此输出流的便捷方法。 |
format(…)方法源码
1 | public PrintStream format(String format, Object ... args) { |
使用指定格式字符串和参数将格式化字符串写入此输出流中。
始终使用的语言环境是由 Locale.getDefault() 返回的语言环境,不管以前在此对象上调用了其他什么样的格式化方法。
1 | public PrintStream format(Locale l, String format, Object ... args) { |
使用指定格式字符串和参数将格式化字符串写入此输出流中。
参数:
- l 格式化过程中应用的 locale。如果 l 为 null,则不应用本地化。
- format 在格式字符串的语法中描述的格式字符串
- args 格式字符串中的格式说明符引用的参数。如果参数多于格式说明符,则忽略额外的参数。参数的数量是可变的,并且可以为零。参数的最大数量受到 Java Virtual Machine Specification 定义的 Ja
- va 数组的最大维数的限制。针对 null 参数的行为依赖于 conversion。
返回: 此输出流
抛出: - IllegalFormatException 如果格式字符串包含非法语法、与给定参数不兼容的格式说明符、对给定格式字符串而言不够充足的参数或其他非法条件。有关所有可能的格式错误的规范,请参阅 formatter 类规范的详细信息部分。
- NullPointerException 如果 format 为 null
从以下版本开始:
1.5
append(…)方法
方法 | 描述 |
---|---|
PrintStream append(char c) |
将指定字符添加到此输出流。 |
PrintStream append(CharSequence csq) |
将指定字符序列添加到此输出流。 |
PrintStream append(CharSequence csq, int start, int end) |
将指定字符序列的子序列添加到此输出流。 |
1 | public PrintStream append(CharSequence csq, int start, int end) { |
将指定字符序列添加到此输出流。
此方法调用 out.append(csq) 的行为与调用下列方法完全相同:
1 out.print(csq.toString())可能不添加整个序列,也可能添加,具体取决于字符序列 csq 的 toString 规范。例如,调用一个字符缓冲区的 toString 方法将返回一个子序列,其内容取决于缓冲区的位置和限制。
指定者:接口 Appendable 中的 append
参数:csq - 要添加的字符序列。如果 csq 为 null,则向此输出流添加四个字符 “null”。
返回:此输出流
从以下版本开始: 1.5
1 | /** |
错误相关方法
方法 | 描述 |
---|---|
boolean checkError() |
刷新流并检查其错误状态。 |
protected void clearError() |
清除此流的内部错误状态。 |
void close() |
关闭流。 |
void flush() |
刷新该流的缓冲。 |
protected void setError() |
将该流的错误状态设置为 true。 |