【Go语言】golang 文件读写

简单讨论一下golang中文件读写实现,并附上读写CSV文件的方法

文件读写,首先要有文件路径/文件名,读文件的时候,打开文件,读取数据,处理数据;写文件时,新建文件,关闭文件,打开文件,写入数据。基本思路就是这样子的,然后就上代码。代码注释很详细哒

package main
import (
"bufio"
"bytes"
"encoding/csv"
"fmt"
"io"
"io/ioutil"
"log"
"os"
"strings"
)

//读取文件内容
func readContent(path string) {
//打开文件
inputFile, err := os.Open(path)
checkError(err)
//关闭文件
defer inputFile.Close()
fmt.Println("读取到的内容是")
//读取
inputReader := bufio.NewReader(inputFile)
for {
inputString, err := inputReader.ReadString('\n')
//inputString, _, err := inputReader.ReadLine()
//到末尾就停止
if err == io.EOF {
return
}
//打印
fmt.Printf("%s", inputString)
}
}

//检查错误
func checkError(err error) {
if err != nil {
log.Fatal(err)
}
}

//读和写
func readAndWrite(inputFile, outputFile string) {
//读取文件
buffer, err := ioutil.ReadFile(inputFile)
//检查错误
checkError(err)
//打印
fmt.Printf("读到的内容是\n%s", buffer)
//写入文件
err = ioutil.WriteFile(outputFile, buffer, 0x664)
checkError(err)
}

//写CSV文件,输入文件名和data
func writeCSV(fileName string, data [][]string) {
//new buffer
buffer := new(bytes.Buffer)
//new writer
writer := csv.NewWriter(buffer)
//写数据
writer.WriteAll(data)
writer.Flush()
//打印数据
fmt.Println(buffer)
//新建文件
fileOut, err := os.Create(fileName)
defer fileOut.Close()
checkError(err)
//写入内容
fileOut.WriteString(buffer.String())
}

//读取CSV,输入文件名,返回data
func readCSV(fileName string) [][]string {
buffer, err := ioutil.ReadFile(fileName)
checkError(err)
reader := csv.NewReader(strings.NewReader(string(buffer)))
data, _ := reader.ReadAll()

//fmt.Println(data)
for k, v := range data {
fmt.Println(k, "###", v)
}
return data
}

func main() {
//读取文件内容
//path := "输入文件路径"
//readContent(path)

//读取和写入
//inputFile := "输入文件路径"
//outputFile := "输入文件名"
//readAndWrite(inputFile, outputFile)
//readContent(outputFile)

//读CSV文件,编码格式:UTF8!!!!!
//data := readCSV("请你自己输入!!!")
//写CSV文件
//writeCSV("请你自己写名字!!!", data)

}

就是这样了。
也许会有人问我代码是怎么这么写的?这个很简单:贴代码的时候用<pre></pre>这个标签包住就好了

刘凯宁@C2P
20140731

Share

【Go语言】golang 连接MySQL数据库

简要谈谈golang 连接数据库,并进行简单操作

首先,要有相关的驱动和相关的包

package main</code>
<code>
import (
"database/sql"
"fmt"
_ "github.com/go-sql-driver/mysql"
"log"
)

然后要确定相关参数

 var host string = "localhost" //主机
var port string = "3306" //端口
var user string = "root" //用户名
var password string = "" //密码
var database string = "golangtest" //数据库名字

现在就可以连接数据库了

 //链接数据库
func connect(host, port, user, password, database string) *sql.DB {
conn := user + ":" + password + "@tcp(" + host + ":" + port + ")/" + database + "?charset=utf8"
db, err := sql.Open("mysql", conn)
CheckError(err)
fmt.Println("数据库连接成功")
return db
}

加一个检查错误的函数,经常使用

 //检查错误
func CheckError(err error) {
if err != nil {
log.Fatal(err)
}
}

封装好查询语句

 //执行查询语句
func Query(db *sql.DB, sql_query string) *sql.Rows {
rows, err := db.Query(sql_query) //执行查询
CheckError(err)
fmt.Println("查询成功")
return rows
}

获取字段

 //获取字段
func getColumns(rows *sql.Rows) []string {
columns, err := rows.Columns()
CheckError(err)
for k, v := range columns {
fmt.Println(k, v)
}
return columns
}

查询一个表中所有的记录

 //查询所有数据
func selectAll(db *sql.DB, table string) {
sql := "select * from " + table
rows := Query(db, sql) //执行查询
column := getColumns(rows) //获取字段
values := make([]string, len(column)) //保存value
scan := make([]interface{}, len(values)) //构造scan获取value
for i := range values {
scan[i] = &amp;values[i] //保存value
}

取得每一行

 //取得一行
for rows.Next() {
rows.Scan(scan...) //scan
for i := 0; i &lt; len(values); i++ {
fmt.Print(column[i], " : ") //打印
fmt.Println(values[i])
}
fmt.Println("#####")
}
}
func main() {
//连接数据库
db := connect(host, port, user, password, database)
//指定表
table := "tb_student"
//查出所有的记录
selectAll(db, table)
//构造sql
sql := "insert " + table + " set name=?,age=?,tel=?,qq=?"
//传参数
src := `"lkn", 1123, "13200902342", "211234245"`
//准备执行
stmt, err := db.Prepare(sql)
CheckError(err)
//执行SQL
stmt.Exec(src)
}

其实最原生态的数据库操作已经不怎么使用了,一般都是ORM实现。有时间专门讨论一下ORM的方式操作数据库。

刘凯宁@C2P
20140730

Share

【Go语言】interface 和 struct 简单使用

昨天,2014年7月29日,SAE二级域名又一次打不开了……今天竟然不给补贴豆豆,真生气!!!

今天讨论一下interface和struct在golang中的简单用法。
interface ,翻译过来是接口 ,在JAVA和C++中也有接口的概念,并且接口是面向对象语言的基本概念。在golang中,接口并不是传统的那种意义,并且说,应该是很不相同的,只不过也用interface来表示。所以有时候英语还是有一点儿用的,你翻译过来,就没有那种感觉了。先来看看golang权威书籍:《The way to Go》中是怎么描述interface的

{我就不用翻译了吧……看英语顺眼(⊙o⊙)}

总之正是因为有了interface ,于是很多面向对象(我想是下次是应该用OO这个高大上的词)的功能都可以实现了。正如书中所说:接口只是提供一些方法的集合但并不去实现那些方法,是一种抽象的概念,而要实现某一个interface,只需要contains all methods 就可以了,并没有“继承”的概念。OO中的很多概念我们在Go中是不需要的,于是现在要说Golang是POP还是OOP,我是觉得没有必要做区分了:Golang is the 21st century  C.  这个定位才最准确!
下面先上一段代码:

可以看出前两个是interface 最后一个是struct。你可能有一点儿疑问:为什么CollageStudenter 这个interface 竟然有一个Studenter 的字段?事实上就是如此:这种就是表明了那种类似的继承关系,Studenter有Say和Play的方法,并且做了 CollageStudenter 的字段,那么CollageStudenter也就有了Say和Play 的方法了。同时再拥有了自己的Research的方法,其实CollageStudent这个interface 有三个方法的。
结构体struct这个东东和C语言中很类似,类比Java/C++等OO语言其实就是class,有属性,有方法,只是定义的方式不同,感觉都是一样的。
下面来看看struct的方法怎么定义:

struct只要实现了interface 的方法,那么就是实现了相应的interface  这个就是重点了,同时struct也可以有自己的method 的,这个不冲突。更加直接的精确的描述在下图:

大家千万要注意在给结构体定义方法的时候,是使用了 self *struct这种的方式,严格说来现代编程语言中是忌讳指针的,此处的使用却是相当合理的,并且也是最标准的指针使用方式,self这个和python中的self以及java中的this 都是异曲同工,功能也很类似,不赘述。

我们在使用interface时可以很灵活,但是正是因为灵活,往往也会出一些错误,这么说吧,interface其实和OO中,特别是Java中的Object class 很是类似,而有的时候在传递消息是,又和泛型<T>差不多。今天先简单讲一讲,后期会有专门的interface使用讨论。

Ok,既然都已经定义好了,那么就可以使用了,看下面的图,千万不要惊讶!

我尽量把每一个对象中所有能被调用的方法都调用出来了,你可以清晰的看到,两个interface之间的区别,interface和struct之间的区别。struct只要实现了某一个interface,就可以实例化一个interface的元素,而struct可以调出相关的属性字段,这个和interface是稍微有一点区别的。

OK,今天就先到这儿。

刘凯宁@C2P
2014年7月30日

 

 

Share

【Go语言】存储密码小技巧

今天简单谈谈密码储存安全

一般一个网站都会有登陆注册等等功能,我们就遇到了怎么保存用户信息这样子的问题,而同时我们最关心的是密码的保存。很多做web 开发的同学都不怎么处理密码,存进数据库的时候也是明文存储,这样子很危险。我们作为开发者要尽量避免自己写的代码出问题,那么现在就简单谈一谈在平时开发中保存密码的小技巧。

【Tip 1】自定义加密函数
这种其实是最容易想到的,也是最容易实现的。例如,我们可以用一套简单的规则将原本看起来有规律的密码变成另一串毫不相关的字符串。主要的思想就是制定一套转化规则,例如:“数字、字母按照顺序收尾相接,所有的数字d 都做前移3位处理,所有的字母都做后移5位处理”,这样的规则就有了如下的对应关系:2->5  ,  7->0  ,  9->2 ,  a->v , s->n , g-> b , 等等这样子。代码实现如下:

这样的一个函数就可以实现上述规则。

这样的处理看起来还是有一点儿用的,只是在当代真的很不适合使用。这种规则性的东西,计算机可以暴力破解,所以只能出现在简单的场景中。

【Tip 2】单向哈希算法
这种就是算是现在使用很广泛的了,用哈希算法加密以后,我们就可以获得一个唯一的字符串,并且这种算法当下很是流行。MD5加密的串一般是没有办法解密的。代码如下:使用前要引入:  “crypto/md5″ 这个包

golang 提供标准的MD5算法,很多语言中都是提供的,这种方式相对来说比较保险。
常见的还有SHA-1和SHA-256算法,在golang中都是大同小异的处理方式。

在一般的应用中,我们可以用md5算法等等单向哈希方式加密我们的密码存在数据库中,而验证的时候也要把用户的密码先md5一下然后去比较这两个字符串是否一致。要记住数据库中存的密码一定要加密!

【Tip 3】“加盐”单向哈希法
单向哈希一直是个好方式,于是就变成了不好的方式了:知名度太广了!用的人太多了!还有很多专门做破解MD5为生的!那么我们就必须要换另外一种更加安全的方式。也许有人会想到二次哈希,三次哈希这种的方式,其实我们能想到,黑客想的肯定比我们多。现在介绍了一种加盐的方式,感觉还是很不错的,先上代码:

这次用的是SHA-256算法,这个加密的串比md5加密的更长。加盐法就是有这么一个技巧:在用户输入的密码上加一点额外的东西,然后在哈希。我们可以定义一个头定义一个尾,这种只有我们自己能够知晓。这样子的处理会将破解难度提高到一个新的档次,因为黑客们没有办法知道你究竟前面指定了哪些规则,不看代码是没有办法的!这样是前两种方式的结合,安全性大大提高,我们开发的时候最好使用这种方式!

OK ,今天就讲到这里。总之密码的保护是非常重要的,希望读者能够有所启发,在今后的开发中注意密码的安全。

刘凯宁@C2P
20140728

Share

【非技术】第三周实习总结

今天7月26日,来到上海22天,实习三周整。

这一周过得很快,上周六张江高科之行和上周日交大之行情景都仿佛就是昨天。这一周主要还是改写脚本,越来越喜欢Golang了。其实语言什么的自己用的舒服就好,真心没有必要去比来比去的,如果你要写一个东西,然后某一种语言能够很快的实现你的想法,那么这就是好的。作为学习者而不是研究者,需要的是能够解决实际问题,而不是OOP,AOP这些概念。其实很多语言入门一个小时足够,只是你需要知道它究竟能用来做什么。

这周博客还是坚持在写,每天讨论一个小问题,进步一点点就够了。

没有必要强制要求别人去做什么事情,我们毕竟都是有独立思想的大学生。大三的路怎么走我真的没有怎么好好想过。回想这两年,似乎都是按照一种既定的模式在发展,只不过走的有一点儿快。当时追求着大二暑假的实习现在正在享受着,却突然发现没有了下一步努力的方向。仿佛回到了大一刚来的那个时候。

应该怎么过好大学?很多理论很多研究只是真的只能说每个人都是独立的个体。当你每天敲着代码解决着老大交给你的工作任务,吃饭,回家,睡觉,或许这就是以后长时间的工作状态。大公司小公司的区别究竟有多重要,15届毕业的学长学姐又开始校招了,而我们呢?我不知道要不要再去那么疯狂的追逐。下学期,要做什么,对不起我真的没有想好。

加了一个QQ群,当今Golang大牛都在群里,于是我知道了一个行业究竟在讨论什么。程序员怎么了?我就是一个程序员,我喜欢敲代码,我喜欢用自己的思想去做一点小小的改变,即使我做的东西也有这么多人在做。但这就是程序员。

实习8周,现在是第三周结束。
期待。

刘凯宁@C2P
20140726

Share