一、文件读写

1.1 os.File

os.File封装所有文件相关操作, 是一个自定义的struct。

a. 打开一个文件进行读操作: os.Open(name string) (*File, error)

Open是以读的方式打开文件(底层调用的是Openfile函数)。

b. 关闭一个文件: File.Close()

1.2 文件操作简单实例

示例1:

package main

import (
"fmt"
"io" //读取文件末尾特殊情况需要用到
"os" //读取文件需要用到
) func main() {
filename := "c:/tmp.txt"
file, err := os.Open(filename) //返回2个参数,第一个file指针,第二个错误值
if err != nil { //如果打开文件有错误,在这里输出
fmt.Printf("open %s failed,err:%v\n", filename, err)
return
}
defer func() { //打开一个文件,最后我们必须要将其关闭
file.Close()
}() var content []byte //定义1个变量存读取到的所有数据
var buf []byte //定义一个4k的字节数组,每次读取一点,4k读性能高
for {
n, err := file.Read(buf[:]) //将整个数组转换成切片读进去,Read函数返回2个参数,第1个n是读到的字节数,第二个是err
if err != nil && err != io.EOF { //有一个特殊问题,当一个文件读读完,遇到文件末尾时,它也会返回一个错误,但是此时我已经读到文件末尾EOF,这个错误应该不算错误,所以应该把读到文件末尾这个错误给去掉。
fmt.Printf("read %s failed, err:%v\n", filename, err)
return //如果有错误就返回
} if err == io.EOF {
break //如果读取到文件末尾了,直接break退出。
} vaildBuf := buf[:n] //把有效数据都拿出来,不可能整个buf数组都是有效数据(最后一次读取到是很大可能是占据数组的一部分。),这里我们就需要借助切片。
//fmt.Printf("%s\n", string(vaildBuf))
content = append(content, vaildBuf...) //将有效的数据存到定义的变量切片中,另外将一个切片append到另一个切片中用...
}
fmt.Printf("content:%s\n", content)
}

执行结果:

示例2:

通过函数传参

package main

import (
"fmt"
"io"
"os"
) func Read(filename string) (string, error) {
//获得一个file
f, err := os.Open(filename)
if err != nil {
fmt.Println("read fail")
return "", err
} //把file读取到缓冲区中
defer f.Close()
var content []byte
var buf []byte
for {
//从file读取到buf中, n表示本次读到的字节数
n, err := f.Read(buf[:])
if err != nil && err != io.EOF {
fmt.Println("read buf fail", err)
return "", err
}
//说明读取结束
if err == io.EOF {
break
}
//读取到最终的缓冲区中
content = append(content, buf[:n]...)
}
fmt.Printf("content:%s\n", content)
return string(content), nil
} func main() {
a := "c:/tmp.txt"
Read(a)
}

执行结果:

1.3 使用bufio提高文件读取性能

之前我们是直接从文件读,因为读取文件是一个相对比较慢的操作,所以当我们读一个大的文件时,或者又多次io操作时会影响性能,所以我们使用bufio(缓存机制,跟redis(缓存)有点类似,可以把文件操作类比成数据库操作)提高文件读取性能。

bufio包go语言已经帮我们封装好了。

bufio包总结如下:

1)bufio 包实现了带缓存的 I/O 操作

2)它封装一个 io.Reader 或 io.Writer 对象

3)使其具有缓存和一些文本读写功能

参考网址:https://blog.csdn.net/wangshubo1989/article/details/70177928

代码示例1:

package main

import (
"bufio"
"fmt"
"io"
"os"
) func main() {
filename := "c:/tmp.txt"
file, err := os.Open(filename) //返回2个参数,第一个file指针,第二个错误值
if err != nil { //如果打开文件有错误,在这里输出
fmt.Printf("open %s failed,err:%v\n", filename, err)
return
}
defer func() { //打开一个文件,最后我们必须要将其关闭
file.Close()
}() reader := bufio.NewReader(file) //要封装这个文件读写,需要把文件传到bufio里面去,然后在bufio里面操作这个缓存,这里我们传的是file文件对象
//为什么要传一个文件对象进去? 答:首先看缓存里有么有,有就读缓存,没有的话就用文件去读,也就是file这个文件对象(是一个结构体,里面包含很多用法)
var content []byte //定义1个变量存读取到的所有数据
var buf []byte //定义一个4k的字节数组,每次读取一点,4k读性能高
for {
n, err := reader.Read(buf[:]) //将整个数组转换成切片读进去,Read函数返回2个参数,第1个n是读到的字节数,第二个是err
if err != nil && err != io.EOF { //有一个特殊问题,当一个文件读读完,遇到文件末尾时,它也会返回一个错误,但是此时我已经读到文件末尾EOF,这个错误应该不算错误,所以应该把读到文件末尾这个错误给去掉。
fmt.Printf("read %s failed, err:%v\n", filename, err)
return //如果有错误就返回
} if err == io.EOF {
break //如果读取到文件末尾了,直接break退出。
} vaildBuf := buf[:n] //把有效数据都拿出来,不可能整个buf数组都是有效数据(最后一次读取到是很大可能是占据数组的一部分。),这里我们就需要借助切片。
//fmt.Printf("%s\n", string(vaildBuf))
content = append(content, vaildBuf...) //将有效的数据存到定义的变量切片中,另外将一个切片append到另一个切片中用...
}
fmt.Printf("content:%s\n", content)
}

执行结果:

代码示例2:函数传参

package main

import (
"bufio"
"fmt"
"io"
"os"
) func Read(filename string) (string, error) {
fi, err := os.Open(filename)
if err != nil {
return "", err
}
defer fi.Close()
r := bufio.NewReader(fi)
var content []byte
var buf []byte
for {
n, err := r.Read(buf[:])
if err != nil && err != io.EOF {
return "", err
}
if err == io.EOF {
break
}
content = append(content, buf[:n]...)
}
fmt.Printf("content:%s\n", content)
return string(content), nil
} func main() {
a := "c:/tmp.txt"
Read(a)
}

执行结果:

1.4 使用ioutil读取整个文件

针对小文件读取,十分方便

代码示例:

package main

import (
"fmt"
"io/ioutil"
) func main() {
filename := "c:/tmp.txt"
content, err := ioutil.ReadFile(filename)
if err != nil {
fmt.Printf("read file %s failed, err:%v\n", filename, err)
return
}
fmt.Printf("content:%s\n", string(content)) //因为上面返回的是一个字节数组,所以必须转一下
}

执行结果:

代码示例2:使用函数传参

package main

import (
"fmt"
"io/ioutil"
) func Read(filename string) (string, error) {
content, err := ioutil.ReadFile(filename)
if err != nil {
return "", err
}
fmt.Printf("content:%s\n", content)
return string(content), nil
} func main() {
a := "c:/tmp.txt"
Read(a)
}

执行结果:

1.5 读取压缩文件示例

gizp就相当于read,gzip使用传进去的文件对象去读取文件内容,解压完了在将数据返回。

下面我们通过几个例子来验证一系列理论

1.5.1 bufio读取压缩文件结果

package main

import (
"bufio"
"fmt"
"io"
"os"
) func main() {
fmt.Printf("start run...\n") filename := "c:/tmp.txt.gz"
file, err := os.Open(filename)
if err != nil {
fmt.Printf("open %s failed, err:%v\n", filename, err)
return
}
fmt.Printf("start0 read file\n")
defer file.Close() reader := bufio.NewReader(file)
var content []byte
var buf []byte
for {
n, err := reader.Read(buf[:])
if err != nil && err != io.EOF {
fmt.Printf("read %s failed, err:%v\n", filename, err)
return
} if err == io.EOF {
break
} vaildBuf := buf[:n]
content = append(content, vaildBuf...)
}
fmt.Printf("content:%s\n", content)
}

执行结果:

解释:

可以看到用bufio读取到的是压缩文件的二进制代码,也是乱码的。

1.5.2 读取压缩文件出现问题

这个问题目前只有读取压缩文件的实例存在,直接读取、bufio、ioutil都不存在这个问题,下面我们通过实例来演示一下。

package main

import (
_ "bufio"
"compress/gzip" //gzip要用到
"fmt"
"io"
"os"
) func main() {
fmt.Printf("start run...\n") filename := "c:/tmp.txt.gz"
file, err := os.Open(filename)
if err != nil {
fmt.Printf("open %s failed, err:%v\n", filename, err)
return
}
fmt.Printf("start0 read file\n")
defer file.Close()
/*
defer func() {
file.Close()
}()
*/ reader, err := gzip.NewReader(file) //用gzip构建文件对象,reader就变成了一个读对象
if err != nil {
fmt.Printf("gzip read failed, err:%v\n", err)
return
} var content []byte
var buf []byte
for {
//reader.Read
fmt.Printf("start read file\n")
n, err := reader.Read(buf[:])
fmt.Printf("read %d err:%v\n", n, err)
if err != nil && err != io.EOF {
fmt.Printf("read %s failed, err:%v\n", filename, err)
return
} //读到文件末尾了,文件已经读取完毕,Read方法会返回一个io.EOF错误。
if err == io.EOF {
break
}
validBuf := buf[:n]
content = append(content, validBuf...)
} fmt.Printf("content:%s\n", content)
}

执行结果:

解释:

可以发现出现了一个严重问题就是当我们每次读取100字节,分多次读取,会出现最后一次读取不到100字节(是52字节),但是err确是EOF,这个时候按照我们上面代码就会break退出,而此次读取到的52字节也会随之丢失,最终实际的结果也是造成了数据丢失。

1.5.3 读取压缩文件完整代码(解决文件丢失问题)

package main

import (
_ "bufio"
"compress/gzip" //gzip要用到
"fmt"
"io"
"os"
) func main() {
fmt.Printf("start run...\n") filename := "c:/tmp.txt.gz"
file, err := os.Open(filename)
if err != nil {
fmt.Printf("open %s failed, err:%v\n", filename, err)
return
}
fmt.Printf("start0 read file\n")
defer file.Close()
/*
defer func() {
file.Close()
}()
*/ reader, err := gzip.NewReader(file) //用gzip构建文件对象,reader就变成了一个读对象
if err != nil {
fmt.Printf("gzip read failed, err:%v\n", err)
return
} //reader := bufio.NewReader(file)
var content []byte
var buf []byte
for {
//reader.Read
fmt.Printf("start read file\n")
n, err := reader.Read(buf[:])
fmt.Printf("read %d err:%v\n", n, err)
if err != nil && err != io.EOF {
fmt.Printf("read %s failed, err:%v\n", filename, err)
return
} if n > { //做一个判断,只要有字节就追加到储存读取到内容的切片
validBuf := buf[:n]
content = append(content, validBuf...)
} //读到文件末尾了,文件已经读取完毕,Read方法会返回一个io.EOF错误。
if err == io.EOF {
break
}
} fmt.Printf("content:%s\n", content)
}

执行结果:

因输出结果太长,此处截图只截取部分内容。

解释:

通过对读取的字节数进行判断,避免了数据丢失的问题。

1.5.4 补充

下面实例有部分用法可能会有疑问,但是写法比较标准,可以学习借鉴。

package main

import (
"bufio"
"compress/gzip"
"fmt"
"os"
) func main() {
fName := "c:/tmp.txt.gz"
var r *bufio.Reader
fi, err := os.Open(fName)
if err != nil {
fmt.Fprintf(os.Stderr, "%v, Can’t open %s: error: %s\n", os.Args[], fName, err)
os.Exit()
}
fz, err := gzip.NewReader(fi)
if err != nil {
fmt.Fprintf(os.Stderr, "open gzip failed, err: %v\n", err)
return
}
r = bufio.NewReader(fz)
for {
line, err := r.ReadString('\n')
if err != nil {
fmt.Println("Done reading file")
os.Exit()
}
fmt.Println(line)
}
}

执行结果:

解释:

先用gizp解压,再用bufio缓存

1.6 文件写入

1)    os.OpenFile("filename",os.O_WRONLY|os.O_CREATE,066)

第一个参数是文件名

第二个参数是文件的打开模式:

os.O_WRONLY:只写

os.O_CREATE:创建文件

os.O_RDONLY:只读

os.O_RDWR:读写

os.O_TRUNC:清空

os.O_APPEND:文件存在以追加方式写入

第三个参数:权限控制

r-->4

w-->2

x-->1

2)    os.Create("output.dat")

用途:如果文件不存在需要先创建文件,用到的就是os.Create方法。(如果要创建的这个文件本来就存在,还要用Create(底层调用的Openfile函数)方法创建该文件,那么该文件就会被清空)

1.7 文件写入实例

示例1:

package main

import (
"fmt"
"os"
) func isFileExists(filename string) bool { //判断文件是否存在
_, err := os.Stat(filename) //os.Stat会返回文件是否存在的相关属性
if os.IsNotExist(err) {
return false
}
return true
} func main() {
filename := "c:/tmp.txt" var file *os.File
var err error
if isFileExists(filename) {
file, err = os.OpenFile(filename, os.O_APPEND, ) //如果文件存在则追加进去
//file, err = os.OpenFile(filename, os.O_APPEND|os.O_WRONLY, 0755) //mac系统追加时还需要在加一个os.O_WRONLY方法
} else {
file, err = os.Create(filename) //不存在就创建该文件
} if err != nil {
fmt.Printf("open %s failed, err:%v\n", filename, err)
return
} defer file.Close() //给文件中写入内容
n, err := file.WriteString("hello world") //WriteString可以传入字符串
//io.WriteString(file,"hello world") //io.WriteString也可以用来进行传入
if err != nil {
fmt.Printf("write failed, err:%v\n", err)
return
}
fmt.Printf("write %d succ\n", n)
}

执行结果:

查看文件内容:可以发现新追加的也添加进去了。

示例2:

package main

import (
"io"
"os"
) func CheckFileExist(fileName string) bool {
_, err := os.Stat(fileName)
if os.IsNotExist(err) {
return false
}
return true
} func Write(fileName string) error {
var f *os.File
var err error
if CheckFileExist(fileName) { //文件存在
f, err = os.OpenFile(fileName, os.O_APPEND, ) //打开文件
if err != nil {
return err
}
} else { //文件不存在
f, err = os.Create(fileName) //创建文件
if err != nil {
return err
}
}
_, err = io.WriteString(f, "strTest")
if err != nil {
return err
}
return nil
} func main() {
Write("c:/tmp.txt")
}

执行结果:

查看文件内容:

示例3:Fprintf

fmt包的Printf底层调用的就是Fprintf

实例如下:

package main

import (
"fmt"
"os"
) func isFileExists(filename string) bool {
_, err := os.Stat(filename)
if os.IsNotExist(err) {
return false
} return true
} func main() {
filename := "c:/tmp.txt" var file *os.File
var err error
if isFileExists(filename) {
//mac机器
file, err = os.OpenFile(filename, os.O_APPEND|os.O_WRONLY, )
} else {
file, err = os.Create(filename)
} if err != nil {
fmt.Printf("open %s failed, err:%v\n", filename, err)
return
} defer file.Close() fmt.Fprintf(file, "%d %d is good", , ) //这里主要是为了演示一下Printf的底层调用Fprintf,我们可以通过传入文件对象,将其写入文件
}

执行结果如下:

查看文件内容:

1.8 使用ioutil直接文件写入

ioutil相当于每次把要写入的内容以覆盖形式写入到文件内

实例1:

package main

import (
"fmt"
"io/ioutil"
) func main() {
filename := "c:/tmp.txt"
str := "dkfslfjdsklfjlskjflsjflsjflsjflks"
err := ioutil.WriteFile(filename, []byte(str), )
if err != nil {
fmt.Println("write fail")
}
fmt.Println("write success")
}

执行结果:

查看文件内容:

实例2:

package main

import (
"fmt"
"io/ioutil"
) func Write() {
fileName := "c:/tmp.txt"
strTest := "测试测试"
var d = []byte(strTest)
err := ioutil.WriteFile(fileName, d, )
if err != nil {
fmt.Println("write fail")
}
fmt.Println("write success")
} func main() {
Write()
}

执行结果:

查看文件内容:

1.9 使用bufio进行文件写入

bufio会减少写入文件的次数,先写到缓存中,然后会调用Flush方法将内存中的内容刷新到磁盘中。

bufio写入的缺点:

会造成文件丢失(当要写入的内容还在缓存中,还未被写入到磁盘时,程序挂了,那这些数据就丢失了。)

示例1:

package main

import (
"bufio"
"fmt"
"os"
) func isFileExists(filename string) bool {
_, err := os.Stat(filename)
if os.IsNotExist(err) {
return false
} return true
} func main() {
filename := "c:/tmp.txt" var file *os.File
var err error file, err = os.Create(filename)
if err != nil {
fmt.Printf("open %s failed, err:%v\n", filename, err)
return
} defer file.Close() writer := bufio.NewWriter(file)
writer.WriteString("hello worldldfdsfsfsf") writer.Flush()
}

执行结果:

查看文件内容:

示例2:

package main

import (
"bufio"
"fmt"
"os"
) func Write() {
fileName := "c:/tmp.txt"
f, err3 := os.Create(fileName) //创建文件
if err3 != nil {
fmt.Println("create file fail")
}
w := bufio.NewWriter(f) //创建新的 Writer 对象
n4, err3 := w.WriteString("bufferedn") //此时还是写入在内存中
fmt.Printf("写入 %d 个字节\n", n4)
w.Flush() //刷新了磁盘
defer f.Close()
} func main() {
Write()
}

执行结果:

查看文件内容:

1.10 拷贝文件

就相当于一个读另一个写,很简单,核心是io.Copy(其就相当于一个for循环,不断读取源文件内容,然后写入目标文件)

示例如下:

package main

import (
"fmt"
"io"
"os"
) func main() {
CopyFile("c:/tmp.txt", "d:/tmp.txt") //目标文件,源文件
fmt.Println("Copy done!")
}
func CopyFile(dstName, srcName string) (written int64, err error) {
src, err := os.Open(srcName) //打开文件
if err != nil {
return
}
defer src.Close()
dst, err := os.OpenFile(dstName, os.O_WRONLY|os.O_CREATE, ) //写入文件
if err != nil {
return
}
defer dst.Close()
return io.Copy(dst, src) //核心在这里,io.Copy 一行代码搞定
}

执行结果如下:

查看源文件和拷贝文件:

二、终端读写

2.1 终端读写相关介绍

操作终端相关文件句柄常量

os.Stdin:标准输入

os.Stdout:标准输出

os.Stderr:标准错误输出

2.2 终端读写实例

package main

import (
"fmt"
) var (
firstName, lastName, s string
i int
f float32
input = "56.12 / 5212 / Go"
format = "%f / %d / %s"
) func main() {
fmt.Println("Please enter your full name: ")
fmt.Scanln(&firstName, &lastName)
// fmt.Scanf("%s %s", &firstName, &lastName)
fmt.Printf("Hi %s %s!\n", firstName, lastName) // Hi Chris Naegels
fmt.Sscanf(input, format, &f, &i, &s)
fmt.Println("From the string we read: ", f, i, s)
}

执行结果:

2.3 带缓冲区的读写

终端(底层就是一个文件操作)就像1个文件,我们该如何像操作文件一样去操作终端呢?

实例1:

package main

import (
"bufio"
"fmt"
"os"
) func main() {
//标准输出
writer := bufio.NewWriter(os.Stdout) //写的话相当于从终端输出,读的话相当于从终端输入
writer.WriteString("hello world")
writer.Flush() //因为bufio还写在内存中,需要flush一下 fmt.Printf("hello world")
//标准输入
reader := bufio.NewReader(os.Stdin) //从终端读入
data, err := reader.ReadString('\n') //readstring方法是传入分隔符,此处传入\n表示直到读入\n为止,也就相当于读一行内容即可
if err != nil {
fmt.Printf("read from console failed, err:%v\n", err)
return
}
fmt.Fprintf(os.Stdout, "data:%s\n", data)
}

执行结果:

实例2:

package main

import (
"bufio"
"fmt"
"os"
) var inputReader *bufio.Reader
var input string
var err error func main() {
inputReader = bufio.NewReader(os.Stdin)
fmt.Println("Please enter some input: ")
input, err = inputReader.ReadString('\n')
if err == nil {
fmt.Printf("The input was: %s\n", input)
}
}

执行结果:

三、命令行参数

3.1 os.Args

os.Args是一个string的切片,用来存储所有的命令行参数。

package main

import (
"fmt"
"os"
) func main() {
fmt.Printf("args count:%d\n", len(os.Args)) //获取当前程序的参数个数
for index, v := range os.Args {
fmt.Printf("args%d, value:%s\n", index, v)
}
}

执行结果如下:

3.2 flag包使用

布尔:flag.BoolVar(&test, "b", false, "print on newline")

字符串:flag.StringVar(&str, "s", "", "print on newline")

整型:flag.IntVar(&count, "c", 1001, "print on newline")

flag要传入的参数依次是:传入值-终端参数-默认值-用法

实例:

package main

import (
"flag"
"fmt"
) func main() {
var num int
var mode string flag.IntVar(&num, "num", , "-num the passwd length") //IntVar参数依次是:传入值-终端参数-默认值-用法
flag.StringVar(&mode, "mode", "mix", "-mode the password generate mode") flag.Parse() //真正解析命令行参数,IntVar、StringVar只是设置命令行需要的一些参数 fmt.Printf("num:%d mode:%s\n", num, mode)
}

执行结果如下:

可以发现传入的参数直接就被flag包解析了。更牛逼的是连--help都直接帮我们做好了

3.3 命令行参数解析

实例:

package main

import (
"flag" // command line option parser
"fmt"
) func main() {
var test bool
var str string
var count int
flag.BoolVar(&test, "b", false, "print on newline")
flag.StringVar(&str, "s", "", "print on newline")
flag.IntVar(&count, "c", , "print on newline")
flag.Parse()
fmt.Println(test)
fmt.Println(str)
fmt.Println(count)
}

执行结果:

3.4 带缓冲区的终端读写

实例:

package main

import (
"bufio"
"fmt"
"os"
) func main() {
fmt.Fprintf(os.Stdout, "%s\n", "hello world! - unbuffered")
buf := bufio.NewWriter(os.Stdout)
fmt.Fprintf(buf, "%s\n", "hello world! - buffered")
buf.Flush()
}

执行结果:

Go语言基础之15--文件基本操作的更多相关文章

  1. (大数据工程师学习路径)第一步 Linux 基础入门----目录结构及文件基本操作

    Linux 目录结构及文件基本操作 介绍 1.Linux 的文件组织目录结构. 2.相对路径和绝对路径. 3.对文件的移动.复制.重命名.编辑等操作. 一.Linux 目录结构 在讲 Linux 目录 ...

  2. Python Cookbook(第3版)中文版:15.19 从C语言中读取类文件对象

    15.19 从C语言中读取类文件对象¶ 问题¶ 你要写C扩展来读取来自任何Python类文件对象中的数据(比如普通文件.StringIO对象等). 解决方案¶ 要读取一个类文件对象的数据,你需要重复调 ...

  3. 文件基本操作 (C语言)

    一切皆文件 ---Linux 头文件 <stdio.h> 中定义了文件的相关操作 #include <stdio.h> 文件操作基本流程: 打开:fopen 相关操作 关闭:f ...

  4. GO学习-(15) Go语言基础之包

    Go语言基础之包 在工程化的Go语言开发项目中,Go语言的源码复用是建立在包(package)基础之上的.本文介绍了Go语言中如何定义包.如何导出包的内容及如何导入其他包. Go语言的包(packag ...

  5. python基础知识六 文件的基本操作+菜中菜

    基础知识六 文件操作 ​ open():打开 ​ file:文件的位置(路径) ​ mode:操作文件模式 ​ encoding:文件编码方式 ​ f :文件句柄 f = open("1.t ...

  6. 单片机教程4.C语言基础以及流水灯的实现

    单片机教程4.C语言基础以及流水灯的实现 C语言,没接触过计算机编程语言的人会把它看的很神秘,感觉非常的难,而在我看来,C语言的逻辑和运算,就是小学水平,所以大家不要怕它,我尽可能的从小学数学逻辑方式 ...

  7. 《MSSQL2008技术内幕:T-SQL语言基础》读书笔记(下)

    索引: 一.SQL Server的体系结构 二.查询 三.表表达式 四.集合运算 五.透视.逆透视及分组 六.数据修改 七.事务和并发 八.可编程对象 五.透视.逆透视及分组 5.1 透视 所谓透视( ...

  8. C#语言基础

    第一部分 了解C# C#是微软公司在2000年7月发布的一种全新且简单.安全.面向对象的程序设计语言,是专门为.NET的应用而开发的.体现了当今最新的程序设计技术的功能和精华..NET框架为C#提供了 ...

  9. C语言基础回顾

    第一章 C语言基础 1.  C语言编译过程 预处理:宏替换.条件编译.头文件包含.特殊符号 编译.优化:翻译并优化成等价的中间代码表示或汇编代码 汇编:生成目标文件,及与源程序等效的目标的机器语言代码 ...

随机推荐

  1. 使用git将代码传到github

    廖雪峰git教程:https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000 注:add加入 ...

  2. node Util 模块

    该util模块主要设计用于支持Node.js自己的内部API的需求.但是,许多实用程序对于应用程序和模块开发人员也很有用.它可以通过以下方式访问: const util = require('util ...

  3. Node.js的__dirname,__filename,process.cwd(),./的含义

    简单说一下这几个路径的意思,: __dirname: 获得当前执行文件所在目录的完整目录名 __filename: 获得当前执行文件的带有完整绝对路径的文件名 process.cwd():获得当前执行 ...

  4. 01 json环境搭建【spring + pringMVC】

    1 导包 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.o ...

  5. Java-马士兵设计模式学习笔记-工厂模式-简单工厂

    一.概述 1.目标:要控制任意类型交通工具的生产模式 2.目标有两层意思(1)任意类型 (2)生产模式,所以对应的,要这两个层面上抽象(Movable,VehicleFactory),利用接口,实现多 ...

  6. iOS Simulator hang up ( Xcode4.6.3)

    最近遇见个Xcode的bug,搞的十分郁闷. 具体现象是:程序前段时间都是好好的,可以运行,第二天开机,调试就无法进入模拟器.就连main()函数都进不了.模拟器完全挂起了.具体说来就是代码一句都没改 ...

  7. Entity Framework Tutorial Basics(6):Model Browser

    Model Browser: We have created our first Entity Data Model for School database in the previous secti ...

  8. kaggle Data Leakage

    What is Data Leakage¶ Data leakage is one of the most important issues for a data scientist to under ...

  9. POJ 1795 DNA Laboratory (贪心+状压DP)

    题意:给定 n 个 字符串,让你构造出一个最短,字典序最小的字符串,包括这 n 个字符串. 析:首先使用状压DP,是很容易看出来的,dp[s][i] 表示已经满足 s 集合的字符串以 第 i 个字符串 ...

  10. 零点起飞学HTML+CSS (顼宇峰) PDF扫描版

    零点起飞学HTML+CSS系统地介绍了网站制作中各种常用的HTML标签和CSS属性,以及网站各个部分和各种布局的实现方法,还提供了大量实例来引导读者学习,力求让读者获得真正实用的知识.本书涉及面广,从 ...