开源项目托管GitHub入门

demo


自从google code关闭了下载服务了之后,GitHub作为了目前最好用的免费开源项目托管站点,众多开源项目都托管在github,其中不乏著名的播放器MPC-HC。
不习惯于英文的朋友,难免少不了要进行摸索一番,甚至会因此头大而放弃。
这里将手把手地教大家一些本人的入门心得

注册github

要托管到github,那你就应该要有一个属于你自己的github帐号,所以你应该先到github.com注册
打开浏览器
在地址栏输入地址:github.com
填写用户名、邮箱、密码
点击Sign up即可简单地注册

demo

创建仓库

完成注册,进入github平台,
点击new repositories
新建一个新项目(你也可以加入到一个已有的项目)
新建项目的操作,其实很简单,输入项目名就可以直接Create了
如图

demo

下载仓库到本地

输入git clone 接着将先前记录下来的地址复制到后面,回车
将下载下来的项目文件夹的所有文件及文件夹,包括.git文件夹在内,全部拷贝到你的托管项目的根目录(或者将你的托管项目拷贝到该目录)
然后cd test进入到该托管项目的根目录。

配置用户信息

因为Git是分布式版本控制系统,所以需要填写用户名和邮箱作为一个标识。
  注意:git config –global 参数,有了这个参数,表示你这台机器上所有的Git仓库都会使用这个配置,当然你也可以对某个仓库指定的不同的用户名和邮箱。
demo

编辑需要提交的文件

我在版本库目录下新建一个记事本文件 readme.txt 内容如下:11111111

添加到缓存区

使用命令 git add readme.txt添加到暂存区里面去。如下:
demo

添加到本地仓库

用命令 git commit告诉Git,把文件提交到仓库。
demo
现在我们已经提交了一个readme.txt文件了,我们下面可以通过命令git status来查看是否还有文件未提交

获取ssh地址

demo

上传到github服务器

现在,我们根据GitHub的提示,在本地的testgit仓库下运行命令:
git remote add origin https://github.com/tugenhua0707/testgit.git
git push origin master
所有的如下:
demo

把本地库的内容推送到远程,使用 git push命令,实际上是把当前分支master推送到远程。

由于远程库是空的,我们第一次推送master分支时,加上了 –u参数,Git不但会把本地的master分支内容推送的远程新的master分支,还会把本地的master分支和远程的master分支关联起来,在以后的推送或者拉取时就可以简化命令。推送成功后,可以立刻在github页面中看到远程库的内容已经和本地一模一样了.

本地仓库管理Git入门

demo


Git是什么?

Git是目前世界上最先进的分布式版本控制系统。

在windows上如何安装Git?

这里下载git适合你电脑的版本
会弹出一个类似的命令窗口的东西,就说明Git安装成功。如下:
demo

创建工作目录

所以创建一个版本库也非常简单,如下我是D盘 –> www下 目录下新建一个testgit版本库。
demo

创建本地仓库

通过命令 git init 把这个目录变成git可以管理的仓库,如下:
demo
这时候你当前testgit目录下会多了一个.git的目录,这个目录是Git来跟踪管理版本的,没事千万不要手动乱改这个目录里面的文件,否则,会把git仓库给破坏了。

编辑目录内想提交的文件

我在版本库testgit目录下新建一个记事本文件 readme.txt 内容如下:11111111

添加到缓存区

使用命令 git add readme.txt添加到暂存区里面去。如下:
demo

提交到本地仓库

用命令 git commit告诉Git,把文件提交到仓库。
demo

查看状态

现在我们已经提交了一个readme.txt文件了,我们下面可以通过命令git status来查看是否还有文件未提交,如下:
demo

再查看状态

说明没有任何文件未提交,但是我现在继续来改下readme.txt内容,比如我在下面添加一行2222222222内容,继续使用git status来查看下结果,如下:
demo
上面的命令告诉我们 readme.txt文件已被修改,但是未被提交的修改。
接下来我想看下readme.txt文件到底改了什么内容,如何查看呢?

比较出修改的部分

git diff readme.txt 如下:
demo
如上可以看到,readme.txt文件内容从一行11111111改成 二行 添加了一行22222222内容。
知道了对readme.txt文件做了什么修改后,我们可以放心的提交到仓库了,提交修改和提交文件是一样的2步(第一步是git add 第二步是:git commit)。

nodejs用superagent发http请求

demo


0. 导入

1
var superagent = require("superagent");

1. GET

1
2
3
4
5
6
7
8
9
10
11
12
13
superagent
.get('/search')
.query({ name: 'Manny' })
.query({ num: '5' })
.query({ order: 'desc' })
.end(function(err, res){
if (err || !res.ok) {
alert('Oh no! error');
} else {
//
}
});

2. POST

1
2
3
4
5
6
7
8
9
10
11
12
13
14
superagent
.post('/api/pet')
.type("form")
.send({ name: 'Manny', species: 'cat' })
.set('X-API-Key', 'foobar')
.set('Accept', 'application/json')
.end(function(err, res){
if (err || !res.ok) {
alert('Oh no! error');
} else {
//
}
});

3. 服务端收不到POST参数问题

superagent的post函数调用之后别忘了加上.type("form") ,然后用nodejs解析获取POST参数的时候要用body-parser;

用c语言画ppm图片(二)


1. PPM介绍

关于PPM的介绍请看`用c语言画ppm图片(一)`这篇文章

2. 主代码

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
#include <iostream>
#include <cmath>
#include <cstdlib>
#define DIM 1024
#define DM1 (DIM-1)
#define _sq(x) ((x)*(x)) // square
#define _cb(x) abs((x)*(x)*(x)) // absolute value of cube
#define _cr(x) (unsigned char)(pow((x),1.0/3.0)) // cube root
unsigned char GR(int,int);
unsigned char BL(int,int);
unsigned char RD(int i,int j){
// YOUR CODE HERE
}
unsigned char GR(int i,int j){
// YOUR CODE HERE
}
unsigned char BL(int i,int j){
// YOUR CODE HERE
}
void pixel_write(int,int);
FILE *fp;
int main(){
fp = fopen("MathPic.ppm","wb");
fprintf(fp, "P6\n%d %d\n255\n", DIM, DIM);
for(int j=0;j<DIM;j++)
for(int i=0;i<DIM;i++)
pixel_write(i,j);
fclose(fp);
return 0;
}
void pixel_write(int i, int j){
static unsigned char color[3];
color[0] = RD(i,j)&255;
color[1] = GR(i,j)&255;
color[2] = BL(i,j)&255;
fwrite(color, 1, 3, fp);
}

3. 欣赏

1
2
3
4
5
6
7
8
9
10
11
unsigned char RD(int i,int j){
return (char)(_sq(cos(atan2(j-512,i-512)/2))*255);
}
unsigned char GR(int i,int j){
return (char)(_sq(cos(atan2(j-512,i-512)/2-2*acos(-1)/3))*255);
}
unsigned char BL(int i,int j){
return (char)(_sq(cos(atan2(j-512,i-512)/2+2*acos(-1)/3))*255);
}

4. 欣赏

1
2
3
4
5
6
7
8
9
10
11
12
unsigned char RD(int i,int j){
#define r(n)(rand()%n)
static char c[1024][1024];return!c[i][j]?c[i][j]=!r(999)?r(256):RD((i+r(2))%1024,(j+r(2))%1024):c[i][j];
}
unsigned char GR(int i,int j){
static char c[1024][1024];return!c[i][j]?c[i][j]=!r(999)?r(256):GR((i+r(2))%1024,(j+r(2))%1024):c[i][j];
}
unsigned char BL(int i,int j){
static char c[1024][1024];return!c[i][j]?c[i][j]=!r(999)?r(256):BL((i+r(2))%1024,(j+r(2))%1024):c[i][j];
}

5. 欣赏

1
2
3
4
5
6
7
8
9
10
11
unsigned char RD(int i,int j){
float x=0,y=0;int k;for(k=0;k++<256;){float a=x*x-y*y+(i-768.0)/512;y=2*x*y+(j-512.0)/512;x=a;if(x*x+y*y>4)break;}return log(k)*47;
}
unsigned char GR(int i,int j){
float x=0,y=0;int k;for(k=0;k++<256;){float a=x*x-y*y+(i-768.0)/512;y=2*x*y+(j-512.0)/512;x=a;if(x*x+y*y>4)break;}return log(k)*47;
}
unsigned char BL(int i,int j){
float x=0,y=0;int k;for(k=0;k++<256;){float a=x*x-y*y+(i-768.0)/512;y=2*x*y+(j-512.0)/512;x=a;if(x*x+y*y>4)break;}return 128-log(k)*23;
}

6. 欣赏

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
unsigned char RD(int i,int j){
double a=0,b=0,c,d,n=0;
while((c=a*a)+(d=b*b)<4&&n++<880)
{b=2*a*b+j*8e-9-.645411;a=c-d+i*8e-9+.356888;}
return 255*pow((n-80)/800,3.);
}
unsigned char GR(int i,int j){
double a=0,b=0,c,d,n=0;
while((c=a*a)+(d=b*b)<4&&n++<880)
{b=2*a*b+j*8e-9-.645411;a=c-d+i*8e-9+.356888;}
return 255*pow((n-80)/800,.7);
}
unsigned char BL(int i,int j){
double a=0,b=0,c,d,n=0;
while((c=a*a)+(d=b*b)<4&&n++<880)
{b=2*a*b+j*8e-9-.645411;a=c-d+i*8e-9+.356888;}
return 255*pow((n-80)/800,.5);
}

7. 欣赏

1
2
3
4
5
6
7
8
9
10
11
unsigned char RD(int i,int j){
static double k;k+=rand()/1./RAND_MAX;int l=k;l%=512;return l>255?511-l:l;
}
unsigned char GR(int i,int j){
static double k;k+=rand()/1./RAND_MAX;int l=k;l%=512;return l>255?511-l:l;
}
unsigned char BL(int i,int j){
static double k;k+=rand()/1./RAND_MAX;int l=k;l%=512;return l>255?511-l:l;
}

8. 欣赏

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
unsigned char RD(int i,int j){
float s=3./(j+99);
float y=(j+sin((i*i+_sq(j-700)*5)/100./DIM)*35)*s;
return (int((i+DIM)*s+y)%2+int((DIM*2-i)*s+y)%2)*127;
}
unsigned char GR(int i,int j){
float s=3./(j+99);
float y=(j+sin((i*i+_sq(j-700)*5)/100./DIM)*35)*s;
return (int(5*((i+DIM)*s+y))%2+int(5*((DIM*2-i)*s+y))%2)*127;
}
unsigned char BL(int i,int j){
float s=3./(j+99);
float y=(j+sin((i*i+_sq(j-700)*5)/100./DIM)*35)*s;
return (int(29*((i+DIM)*s+y))%2+int(29*((DIM*2-i)*s+y))%2)*127;
}

9. 欣赏

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
unsigned char RD(int i,int j){
#define D DIM
#define M m[(x+D+(d==0)-(d==2))%D][(y+D+(d==1)-(d==3))%D]
#define R rand()%D
#define B m[x][y]
return(i+j)?256-(BL(i,j))/2:0;
}
unsigned char GR(int i,int j){
#define A static int m[D][D],e,x,y,d,c[4],f,n;if(i+j<1){for(d=D*D;d;d--){m[d%D][d/D]=d%6?0:rand()%2000?1:255;}for(n=1
return RD(i,j);
}
unsigned char BL(int i,int j){
A;n;n++){x=R;y=R;if(B==1){f=1;for(d=0;d<4;d++){c[d]=M;f=f<c[d]?c[d]:f;}if(f>2){B=f-1;}else{++e%=4;d=e;if(!c[e]){B=0;M=1;}}}}}return m[i][j];
}

10. 欣赏

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
unsigned char RD(int i,int j){
#define A float a=0,b,k,r,x
#define B int e,o
#define C(x) x>255?255:x
#define R return
#define D DIM
R BL(i,j)*(D-i)/D;
}
unsigned char GR(int i,int j){
#define E DM1
#define F static float
#define G for(
#define H r=a*1.6/D+2.4;x=1.0001*b/D
R BL(i,j)*(D-j/2)/D;
}
unsigned char BL(int i,int j){
F c[D][D];if(i+j<1){A;B;G;a<D;a+=0.1){G b=0;b<D;b++){H;G k=0;k<D;k++){x=r*x*(1-x);if(k>D/2){e=a;o=(E*x);c[e][o]+=0.01;}}}}}R C(c[j][i])*i/D;
}

用c语言画ppm图片(一)


1. PPM介绍

PPM(Portable PixMap)是portable像素图片,是有netpbm项目定义的一系列的portable图片格式中的一个。这些图片格式都相对比较容易处理,跟平台无关,所以称之为portable,简单理解,就是比较直接的图片格式,比如PPM,其实就是把每一个点的RGB分别保存起来。所以,PPM格式的文件是没有压缩的,相对比较大,但是由于图片格式简单,一般作为图片处理的中间文件(不会丢失文件信息),或者作为简单的图片格式保存。

2. PPM格式分析

netpbm的几种图片格式是通过其表示的颜色类型来区别的,PBM是位图,只有黑色和白色,PGM是灰度图片,PPM是代表完整的RGB颜色的图片。

(1) 文件头

文件头由三个部分(或者认为是四个部分)组成:这几个部分之间用回车或换行分隔(但是PPM标准中要求是空格)

* 第一部分是文件magic number:
每一个netpbm图片由两个字节的magic number (ASCII)组成,来标识文件的类型(PMB/PGM/PPM)以及文件的编码(ASCII或binary).
所以PPM格式的起始两个字节为P3或者P6.
关于编码(ASCII或binary): 其区别是ASCII编码的文件是对于阅读友好的,可以字节用文本编辑器打开,并读取其对应的图片的数据(比如RGB的值),然后中间会有空格回车等隔开。binary就是按照二进制的形式,顺序存储图片信息,没有空格回车分隔。所以很显然,binary格式的图片处理起来更快(不需要判断空格回车),而且图片会更小,但是ASCII阅读调试更为直接。

* 第二部分是图像宽度和高度(空格隔开),用ASCII表示。

* 第三部分是描述像素的最大颜色组成,允许描述超过一个字节(0-255)的颜色值。
另外,在上面的三个部分里面,都可以使用"#"插入注释,注释是#到行尾(回车或换行)部分。

(2) 图像数据部分

对于ASCII格式,就是按照RGB的顺序排列,以ASCII存储,并且,RGB中间用空格隔开,图片每一行用回车隔开。
对于binary格式,就是每一个像素点的RGB值分别顺序存储并且按二进制写入文件(fwrite),没有任何分隔。
比如下面这个图片 (一共六个像素点,图片宽度为3,高度为2):

3. 代码如下:

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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include <stdio.h>
#include <stdlib.h>
int writePPMHeader(FILE *f, char magic, int w, int h, int color) {
if (f==NULL) {
printf("FILE error\n");
exit(0);
}
if (magic=='A') {// ASCII
fprintf(f, "P3\n");
} else if (magic=='B') {
fprintf(f, "P6\n");
} else {
printf("Magic can only be A(ASCII) or B(binary)\n");
exit(0);
}
fprintf(f, "%d %d\n", w, h);
fprintf(f, "%d\n", color);
return 0;
}
int writePPMdataP3(FILE* f, unsigned char* img, int w, int h) {
int i,j;
for(i=0;i<h;i++) { // every rwo
for(j=0;j<w;j++) { // every line
fprintf(f, "%d ",img[i*w*3+3*j]);
fprintf(f, "%d ",img[i*w*3+3*j+1]);
fprintf(f, "%d ",img[i*w*3+3*j+2]);<span style="white-space:pre"> </span>// PS: 对于j=w-1的时候,最后一个空格可以不写,但是这里就不考虑了
}
fprintf(f, "\n");
}
}
int writePPMdataP6(FILE* f, unsigned char* img, int w, int h) {
int i,j;
for(i=0;i<w;i++) {
for(j=0;j<h;j++) {
fwrite(img, w*h, 3, f);
}
}
}
#define WIDTH 3
#define HEIGHT 2
unsigned char img[WIDTH*HEIGHT*3]={255,0,0,0,255,0,0,0,255,255,255,0,255,255,255,0,0,0};
int main() {
char *filename1 = "testP3.ppm";
char *filename2 = "testP6.ppm";
FILE *f3 = fopen(filename1, "w");
if (f3==NULL) {
printf("FILE error\n");
exit(0);
}
FILE *f6 = fopen(filename2, "w");
if (f6==NULL) {
printf("FILE error\n");
exit(0);
}
writePPMHeader(f3, 'A', WIDTH, HEIGHT, 255);
writePPMdataP3(f3, img, WIDTH, HEIGHT);
writePPMHeader(f6, 'B', WIDTH, HEIGHT, 255);
writePPMdataP6(f6, img, WIDTH, HEIGHT);
fclose(f3);
fclose(f6);
return 0;
}

4. 更多图形

更多图形请看用c语言画ppm图片(二)这篇文章。

java发起http请求

demo


0. HttpUtil 类

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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
package com.kompasim.utils;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
public class HttpUtil {
String path = null;
URL url = null;
HttpURLConnection urlConnection = null;
private String resultData = "";
public HttpUtil(String p){
path = p;
}
public void open(String string){
try {
url = new URL(path + "?" + string);
System.out.println("url is : " + url);
urlConnection = (HttpURLConnection)url.openConnection();
} catch (Exception e) {
e.printStackTrace();
}
}
public void setHeader(String name, String value){
urlConnection.addRequestProperty(name,value);
}
public String get(){
try {
//headers
urlConnection.setRequestMethod("GET");
urlConnection.setUseCaches(false);
urlConnection.setConnectTimeout (5000);
urlConnection.connect();
if (urlConnection.getResponseCode()!=200){
System.out.println("err : get网络请求失败,返回200");
return "error";
}else {
InputStreamReader isr = new InputStreamReader(urlConnection.getInputStream());
BufferedReader br = new BufferedReader(isr);
String line = null;
while((line=br.readLine())!=null){
resultData += line;
}
isr.close();
br.close();
urlConnection.disconnect();
return resultData.toString();
}
}catch (Exception e){
e.printStackTrace();
System.out.println("err : " + e.getStackTrace().toString());
return "error";
}
}
public String post(String encodedString){
try {
urlConnection.setDoOutput(true);
urlConnection.setDoInput(true);
urlConnection.setConnectTimeout(5*1000);
}catch (Exception e){
System.out.println("err : " + e.getStackTrace().toString());
}
try{
urlConnection.setRequestMethod("POST");
urlConnection.setUseCaches(false);
urlConnection.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
urlConnection.connect();
DataOutputStream out = new DataOutputStream(urlConnection.getOutputStream());
// 参数
// 将要上传的内容写入流中
out.writeBytes(encodedString);
// 刷新关闭
out.flush();
out.close();
if (urlConnection.getResponseCode()!=200){
System.out.println("err : post网络请求失败,返回200");
return "error";
}else {
InputStreamReader isr = new InputStreamReader(urlConnection.getInputStream());
BufferedReader br = new BufferedReader(isr);
String line = null;
while((line=br.readLine())!=null){
resultData += line;
}
isr.close();
urlConnection.disconnect();
return resultData.toString();
}
}catch(Exception e){
System.out.println("err : " + e.getStackTrace().toString());
return "error";
}
}
}

1. 发起get请求

1
2
3
4
5
6
HttpUtil httpUtil = new HttpUtil("http://api.kompasim.cn/humor.php");
String queryStr = "bodyName1=" + URLEncoder.encode("bodyValue1","UTF-8") + "&bodyName2=" + URLEncoder.encode("bodyValue2","UTF-8");
httpUtil.open(queryStr);
httpUtil.setHeader("headerNmae1", "headerValue1");
httpUtil.setHeader("headerNmae2", "headerValue2");
String resultStr = httpUtil.get();

2. 发起post请求

1
2
3
4
5
6
HttpUtil httpUtil = new HttpUtil("http://api.kompasim.cn/humor.php");
httpUtil.open("");
httpUtil.setHeader("headerNmae1", "headerValue1");
httpUtil.setHeader("headerNmae2", "headerValue2");
String queryStr = "bodyName1=" + URLEncoder.encode("bodyValue1","UTF-8") + "&bodyName2=" + URLEncoder.encode("bodyValue2","UTF-8");
String resultStr = httpUtil.post(queryStr);

3. 线程间通信

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
// handler
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 1:
String resultStr = (String)msg.obj;
// do something
TextView textView = (TextView)findViewById(R.id.textView);
textView.setText(resultStr);
break;
default:
break;
}
}
};
// timer task
TimerTask tt = new TimerTask() {
@Override
public void run() {
// do post or do get
String resultStr = "";
Message msg = new Message();
msg.what = 5;
msg.obj = resultStr;
handler.sendMessage(msg);
}
};
Timer t = new Timer(true);
t.schedule(tt, 0, 1000);

Nginx在Ubuntu上的基本知识

demo


1.在线安装

$sudo apt-get install nginx

ubuntu安装Nginx之后的文件结构如下:

所有的配置文件都在/etc/nginx下,并且每个虚拟主机已经安排在了/etc/nginx/sites-available下

启动程序文件在/usr/sbin/nginx

日志放在了/var/log/nginx中,分别是access.log和error.log

并已经在/etc/init.d/下创建了启动脚本nginx

默认的虚拟主机的目录设置在了/usr/share/nginx/www

2.源代码安装

下载地址:http://nginx.org/download/

我这里下载的是 nginx-1.3.9.tar.gz,安装过程很简单,如下:

$./configure

$make

$make install

安装成功之后,nginx放置在/usr/local/nginx目录下,主要的配置文件为conf目录下的nginx.conf,nginx的启动文件在sbin目录下的nginx文件。

3.修改监听端口

修改nginx的配置文件nginx.conf,将一下这一行 listen 80; 修改为 listen 8080; 然后就可以访问了,http://localhost:8080/

4. 配置文件

Nginx的配置文件是/etc/nginx/nginx.conf,其中设置了一些必要的参数,我们发现其中这样的语句:
include /etc/nginx/sites-enabled/* 可以看出 /etc/nginx/sites-enabled/default 文件也是一个核心的配置文件,其中包含了主要的配置信息,如服务器跟目录、服务器名称、location信息和server信息。

对于源代码安装的nginx,配置文件为 /usr/local/nginx/conf/nginx.conf

5. location的匹配规则

(1)= 前缀的指令严格匹配这个查询。如果找到,停止搜索。

(2)剩下的常规字符串,最长的匹配优先使用。如果这个匹配使用 ^~ 前缀,搜索停止。

(3)正则表达式,按配置文件里的顺序,第一个匹配的被使用。

(4)如果第三步产生匹配,则使用这个结果。否则使用第二步的匹配结果。

在location中可以使用常规字符串和正则表达式。如果使用正则表达式,你必须使用以下规则:

  • ~* 前缀选择不区分大小写的匹配
  • ~ 选择区分大小写的匹配
1
2
3
4
location = / {
# 只匹配 / 查询。
[ configuration A ]
}
1
2
3
4
5
location / {
# 匹配任何查询,因为所有请求都以 / 开头。
# 但是正则表达式规则和长的块规则将被优先和查询匹配。
[ configuration B ]
}
1
2
3
4
5
location ^~ /images/ {
# 匹配任何以 /images/ 开头的任何查询并且停止搜索。
# 任何正则表达式将不会被测试。
[ configuration C ]
}
1
2
3
4
5
location ~* \.(gif|jpg|jpeg)$ {
# 匹配任何以 gif、jpg 或 jpeg 结尾的请求。
# 然而所有 /images/ 目录的请求将使用 Configuration C。
[ configuration D ]
}

6. 常用命令

-?,-h : this help

-v : show version and exit

-V : show version and configure options then exit

-t : test configuration and exit

-q : suppress non-error messages during configuration testing

-s signal : send signal to a master process: stop, quit, reopen, reload

-p prefix : set prefix path (default: /usr/local/nginx/)

-c filename : set configuration file (default: conf/nginx.conf)

-g directives : set global directives out of configuration file

Ubuntu上配置Nginx服务器

demo


0.Nginx的介绍

Nginx是一个非常轻量级的HTTP服务器,Nginx,它的发音为“engine X”, 是一个高性能的HTTP和
反向代理服务器,同时也是一个IMAP/POP3/SMTP 代理服务器。

1.安装Nginx

apt-get install nginx

2.启动Nginx

service nginx start

3.访问服务器IP

如果看到“Welcome to nginx!”说明安装好了。

4.安装PHP

apt-get install php5-fpm

5.配置Nginx

vim /etc/nginx/sites-available/default

找到下列代码,去掉相应注释

1
2
3
4
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php5-fpm.sock;
}

重启服务

service nginx restart

6.默认的网站根目录在/var/www/html

vim /var/www/html/test.php

输入以下内容,并保存

1
2
3
<?php
echo phpinfo();
?>

访问网站IP/test.php,如果可以看到phpinfo的信息说明php安装成功。

7.参考

CSDN Lnho的专栏

php简单文件上传和下载

demo


php简单实现文件上传和下载
当然实际应用中还是要检测文件大小呀,格式呀什么的…

1. html

index.php

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
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="Generator" content="EditPlus®">
<meta name="Author" content="">
<meta name="Keywords" content="">
<meta name="Description" content="">
<title>Document</title>
<style>
*{
font-family:'';
}
</style>
</head>
<body>
<center>
<h2>upload a file<h2>
<form style='width:400px;height:400px;border:solid 5px red;border-radius:10px' enctype='multipart/form-data' method='post' action='upload.php'>
<input type='file' name='file'>
</br>
<input type='submit' value='submit'>
</br>
</br>
<form>
</center>
</body>
</html>

2. upload

upload.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<center>
<?php
header('content-type:text/html;charset=utf-8');
$file=$_FILES;
//echo '';
if(!is_uploaded_file($file['file']['tmp_name'])){
echo 'please select a file ...';
}else{
move_uploaded_file($file['file']['tmp_name'],$file['file']['name']);
echo "<a href='download.php?a=".$file['file']['name']."'>".$file['file']['name']."</a>";
}
?>
</center>

3. download

download.php

1
2
3
4
5
6
7
8
9
10
<?php
//$filename="http://liaoxuefeng-static.oss-cn-hangzhou.aliyuncs.com/static-img/maiziedu.jpg";
$filename=$_GET["a"];
header('content-type:text/html;charset=utf-8');
header("Content-type: octet/stream");
header("content_type:application/octed-stream");
header('Content-Disposition: attachment; filename='.$filename);
ob_clean ();
readfile($filename);
?>

4. HTML5

1
<a href="photo.jpg" download="photo_name">download</a>

android的webview和back键


这是一个简单的webview实例,你可以看到当单击back键的时候,
如果webview有浏览历史的话history会弹出栈,
如果没有浏览历史的话如果两秒内点击两次侧推出app,不然没有响应。

1. 代码

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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package com.example.mywork;
import java.util.Timer;
import java.util.TimerTask;
import android.support.v7.app.ActionBarActivity;
import android.support.v4.app.Fragment;
import android.app.Activity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.webkit.WebView;
import android.os.Build;
import android.webkit.WebViewClient;
import android.widget.Toast;
public class MainActivity extends Activity {
private WebView webView;
private static boolean mBackKeyPressed = false;//记录是否有首次按键
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
this.initWebView();
}
protected void initWebView(){
this.webView = (WebView)findViewById(R.id.webView);
this.webView.getSettings().setJavaScriptEnabled(true);
this.webView.setWebViewClient(new WebViewClient());
this.webView.loadUrl("http://www.1tamche.com");
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
if(keyCode==KeyEvent.KEYCODE_BACK){
if(this.webView.canGoBack()){
//需要处理
this.webView.goBack();
return true;
}else{
if(!mBackKeyPressed){
mBackKeyPressed = true;
new Timer().schedule(new TimerTask() {
@Override
public void run() {
// TODO Auto-generated method stub
mBackKeyPressed = false;
}//延时两秒,如果超出则擦错第一次按键记录
}, 2000);
return true;
}
else{//退出程序
this.finish();
System.exit(0);
}
}
}
return super.onKeyDown(keyCode,event);
}
}
class webViewClient extends WebViewClient{
//重写shouldOverrideUrlLoading方法,使点击链接后不使用其他的浏览器打开。
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
//如果不需要其他对点击链接事件的处理返回true,否则返回false
return true;
}
}
,