go语言之行--文件操作、命令行参数、序列化与反序列化详解
一、简介
文件操作对于我们来说也是非常常用的,在python中使用open函数来对文件进行操作,而在go语言中我们使用os.File对文件进行操作。
二、终端读写
操作终端句柄常量
os.Stdin: 标准输入
os.Stdout: 标准输出
os.Stderr: 标准错误输出
读写示例:
package main import (
"fmt"
"os"
) var(
username,password string
) func main() {
fmt.Println("请输入用户名:")
fmt.Scanf("%s", &username) // 键盘输入
fmt.Println("请输入密码:")
fmt.Scanf("%s", &password)
fmt.Printf("username:%s password:%s\n", username, password)
var msg []byte
fmt.Println("请输入名称:")
n, err := os.Stdin.Read(msg[:])
if err == nil {
fmt.Printf("len: %d ,msg : %s", n, msg[:])
return
}
}
//请输入用户名:
//wd
//请输入密码:
//123
//username:wd password:123
//请输入名称:
//ad
//len: 3 ,msg : ad
三、文件操作
os.File是一个结构体,其封装了诸多操作文件的方法:
func Create(name string) (*File, error) //Create采用模式0666(任何人都可读写,不可执行)创建一个名为name的文件,如果文件已存在会截断它(为空文件)。如果成功,返回的文件对象可用于I/O;对应的文件描述符具有O_RDWR模式。如果出错,错误底层类型是*PathError。
func NewFile(fd uintptr, name string) *File //NewFile使用给出的Unix文件描述符和名称创建一个文件。
func Open(name string) (*File, error) //Open打开一个文件用于读取。如果操作成功,返回的文件对象的方法可用于读取数据;对应的文件描述符具有O_RDONLY模式。如果出错,错误底层类型是*PathError。
func OpenFile(name string, flag int, perm FileMode) (*File, error) //OpenFile是一个更一般性的文件打开函数,大多数调用者都应用Open或Create代替本函数。它会使用指定的选项(如O_RDONLY等)、指定的模式(如0666等)打开指定名称的文件。如果操作成功,返回的文件对象可用于I/O。如果出错,错误底层类型是*PathError。
func Pipe() (r *File, w *File, err error) //Pipe返回一对关联的文件对象。从r的读取将返回写入w的数据。本函数会返回两个文件对象和可能的错误。
func (f *File) Chdir() error //Chdir将当前工作目录修改为f,f必须是一个目录。如果出错,错误底层类型是*PathError。
func (f *File) Chmod(mode FileMode) error //Chmod修改文件权限。如果出错,错误底层类型是*PathError。
func (f *File) Chown(uid, gid int) error //修改文件文件用户id和组id
func (f *File) Close() error //Close关闭文件f,使文件不能用于读写。它返回可能出现的错误。
func (f *File) Fd() uintptr //Fd返回与文件f对应的整数类型的Unix文件描述符。
func (f *File) Name() string //Name方法返回(提供给Open/Create等方法的)文件名称。
func (f *File) Read(b []byte) (n int, err error) //Read方法从f中读取最多len(b)字节数据并写入b。它返回读取的字节数和可能遇到的任何错误。文件终止标志是读取0个字节且返回值err为io.EOF。
func (f *File) ReadAt(b []byte, off int64) (n int, err error) //ReadAt从指定的位置(相对于文件开始位置)读取len(b)字节数据并写入b。它返回读取的字节数和可能遇到的任何错误。当n<len(b)时,本方法总是会返回错误;如果是因为到达文件结尾,返回值err会是io.EOF。
func (f *File) Readdir(n int) ([]FileInfo, error) //Readdir读取目录f的内容,返回一个有n个成员的[]FileInfo,这些FileInfo是被Lstat返回的,采用目录顺序。对本函数的下一次调用会返回上一次调用剩余未读取的内容的信息。
如果n>,Readdir函数会返回一个最多n个成员的切片。这时,如果Readdir返回一个空切片,它会返回一个非nil的错误说明原因。如果到达了目录f的结尾,返回值err会是io.EOF。
如果n<=,Readdir函数返回目录中剩余所有文件对象的FileInfo构成的切片。此时,如果Readdir调用成功(读取所有内容直到结尾),它会返回该切片和nil的错误值。如果在到达结尾前遇到错误,会返回之前成功读取的FileInfo构成的切片和该错误。
func (f *File) Readdirnames(n int) (names []string, err error) //Readdir读取目录f的内容,返回一个有n个成员的[]string,切片成员为目录中文件对象的名字,采用目录顺序。对本函数的下一次调用会返回上一次调用剩余未读取的内容的信息。
如果n>,Readdir函数会返回一个最多n个成员的切片。这时,如果Readdir返回一个空切片,它会返回一个非nil的错误说明原因。如果到达了目录f的结尾,返回值err会是io.EOF。
如果n<=,Readdir函数返回目录中剩余所有文件对象的名字构成的切片。此时,如果Readdir调用成功(读取所有内容直到结尾),它会返回该切片和nil的错误值。如果在到达结尾前遇到错误,会返回之前成功读取的名字构成的切片和该错误。
func (f *File) Seek(offset int64, whence int) (ret int64, err error) //Seek设置下一次读/写的位置。offset为相对偏移量,而whence决定相对位置:0为相对文件开头,1为相对当前位置,2为相对文件结尾。它返回新的偏移量(相对开头)和可能的错误。
func (f *File) SetDeadline(t time.Time) error // 设置文件读取和写入时间,超时返回错误
func (f *File) SetReadDeadline(t time.Time) error //设置文件读取时间
func (f *File) SetWriteDeadline(t time.Time) error // 设置文件写入时间
func (f *File) Stat() (FileInfo, error) //Stat返回描述文件f的FileInfo类型值。如果出错,错误底层类型是*PathError。
func (f *File) Sync() error //Sync递交文件的当前内容进行稳定的存储。一般来说,这表示将文件系统的最近写入的数据在内存中的拷贝刷新到硬盘中稳定保存。
func (f *File) Truncate(size int64) error //Truncate改变文件的大小,它不会改变I/O的当前位置。 如果截断文件,多出的部分就会被丢弃。如果出错,错误底层类型是*PathError。
func (f *File) Write(b []byte) (n int, err error) //Write向文件中写入len(b)字节数据。它返回写入的字节数和可能遇到的任何错误。如果返回值n!=len(b),本方法会返回一个非nil的错误。
func (f *File) WriteAt(b []byte, off int64) (n int, err error) //将len(b)字节写入文件,从字节偏移开始。它返回写入的字节数和错误,写的时候返回一个错误,当n != len(b)
func (f *File) WriteString(s string) (n int, err error) //WriteString类似Write,参数为字符串。
读写参数
文件打开模式:
const (
O_RDONLY int = syscall.O_RDONLY // 只读模式打开文件
O_WRONLY int = syscall.O_WRONLY // 只写模式打开文件
O_RDWR int = syscall.O_RDWR // 读写模式打开文件
O_APPEND int = syscall.O_APPEND // 写操作时将数据附加到文件尾部
O_CREATE int = syscall.O_CREAT // 如果不存在将创建一个新文件
O_EXCL int = syscall.O_EXCL // 和O_CREATE配合使用,文件必须不存在
O_SYNC int = syscall.O_SYNC // 打开文件用于同步I/O
O_TRUNC int = syscall.O_TRUNC // 如果可能,打开时清空文件
)
文件权限:
r :可读,对应的004
w:可写,对应002
x:可执行,对应001
文件读取
Read
package main import (
"fmt"
"os"
"io"
) func main() {
file, err := os.Open("/home/test.txt") //只读打开
if err != nil {
fmt.Println("open file error: ", err)
return
}
defer file.Close() //关闭文件
context := make([]byte ,)
for {
readNum, err := file.Read(context)
if err != nil && err != io.EOF {
//panic(err) //有错误抛出异常
}
if == readNum {
break //当读取完毕时候退出循环
}
}
for k,v := range context{
println(k,v)
} }
Seek
package main
import (
"io"
"fmt"
"os"
)
func main(){
testio()
}
func testio(){
//若文件不存在则创建文件,以append方式打开
file, err := os.OpenFile("/home/test.txt", os.O_CREATE|os.O_APPEND, )
if err != nil{
fmt.Println(err)
return
}
defer file.Close() //关闭文件
file.WriteString("i am chain ") //写入文件
buf := make([]byte, )
var str string
file.Seek(, os.SEEK_SET) //重置文件指针
//读取文件
for {
n, ferr := file.Read(buf)
if ferr != nil && ferr != io.EOF{
fmt.Println(ferr.Error())
break
}
if n == {
break
}
str += string(buf[:n])
}
fmt.Println("file content: ", str)
}
按行读取ReadLine
package main import (
"bufio"
"fmt"
"io"
"os"
) func main() {
file, err := os.Open("/home/test.txt")
if err != nil {
fmt.Println(err)
return
}
defer file.Close()
reader := bufio.NewReader(file)
var line []byte
for {
data, prefix, err := reader.ReadLine()
if err == io.EOF {
break
} line = append(line, data...)
if !prefix {
fmt.Printf("data:%s\n", string(line))
line = line[:]
} }
}
读取整个文件ReadAll
package main import (
"fmt"
"os"
"io/ioutil"
) func main() {
fileName := "/home/test.txt" file, err := os.OpenFile(fileName, os.O_CREATE|os.O_RDWR, )
if err != nil {
fmt.Println("Open file error: ", err)
return
}
defer file.Close() buf, err := ioutil.ReadAll(file)
//buf, err := ioutil.ReadFile(fileName)
if err != nil {
fmt.Fprintf(os.Stderr, "File Error: %s\n", err)
return
}
fmt.Printf("%s\n", string(buf))
}
四、带缓冲区的读写(bufio)
带缓冲的读写操作作用是为了减少磁盘io次数,通过包bufio实现,这里做简单示例说明,bufio包后续再介绍.
标准输入读示例:
package main import (
"bufio"
"os"
"fmt"
) func main() {
reader := bufio.NewReader(os.Stdin) // 创建从标准输入中读取数据对象
str,err := reader.ReadString('\n') //读数据,bytes类型是单引号
if err != nil {
fmt.Println("read fail")
return
}
fmt.Println("input string: ",str) }
//adad
//input string: adad
从文件读取示例
package main import (
"bufio"
"os"
"fmt"
"io"
) func main() {
file,err := os.Open("test.txt") //以只读方式打开文件
if err != nil {
fmt.Println("open file fail err:",err)
return
}
reader := bufio.NewReader(file) // 创建读取数据对象
defer file.Close()
for{
str,err := reader.ReadString('\n') //读数据,bytes类型是单引号,回车结束。
if err == io.EOF {
fmt.Println("read over")
break
}
if err != nil{
fmt.Println("error :",err)
break
}
fmt.Println("STRING: ",str) } }
写文件示例:
注意事项:写入文件需要 Flush缓冲区的内容到文件中。
package main import (
"bufio"
"os"
"fmt"
) func main() {
file,err := os.OpenFile("test.txt",os.O_WRONLY,) //以写方式打开文件
if err != nil {
fmt.Println("open file fail err:",err)
return
}
writer := bufio.NewWriter(file) // 创建写对象
defer file.Close()
var str string
fmt.Println("请输入内容:")
fmt.Scanf("%s",&str)
writer.WriteString(str)
writer.Flush() // 将缓冲区内容写入文件,默认写入到文件开头 }
五、命令行参数
命令行参数:程序启动或者停止时候,在命令行中给定的参数就是命令行参数。例如start.sh -p 8080
go语言中提供了两种处理命令行参数的包os.Agrs和flag包。
优缺点:
- os.Agrs提供了简单的命令行参数,以命令行参数个数作为标识,参数列表是一个切片,索引0代表程序本身,1代表第一个参数,以此类推,没有更细粒度的参数区分,使用起来简单
- flag提供了更为科学的命令行参数处理办法,提供更细粒度的和更全的参数解析,推荐使用
os.Agrs
os.Args 提供原始命令行参数访问功能。注意,切片中的第一个参数是该程序的路径,并且 os.Args[1:]保存所有程序的的参数。
示例:
package main import (
"os"
"fmt"
)
func main() {
if len(os.Args) < {
fmt.Println("no args")
return
}
println("script name: ",os.Args[])
for i := range os.Args {
fmt.Printf("this is %d arg : %s\n" ,i,os.Args[i]) }
}
// 执行./eg1 name age body
//结果:
//script name: ./eg1
//this is 0 arg : ./eg1
//this is 1 arg : name
//this is 2 arg : age
//this is 3 arg : body
flag包
Flag类型是一个结构体,其定义如下:
type Flag struct {
Name string // name as it appears on command line
Usage string // help message
Value Value // value as set
DefValue string // default value (as text); for usage message
}
flag包提供了一系列解析命令行参数的功能接口,其定义的命令行参数方式有以下几种:
-flag //只支持bool类型
-flag=x
-flag x //只支持非bool类型 特别说明一个-和 -- 效果是一样的
定义flag参数
方式一:通过flag.String(), Bool(), Int()
等flag.Xxx()
方法,该种方式返回一个相应的指针
示例:
package main import (
"fmt"
"flag"
)
func main() {
ip := flag.String("ip","10.0.0.230","server listen ip") //参数一为命令行接受的参数名称,参数二为默认值,参数三为描述信息
port := flag.Int("port",,"server port")
flag.Parse()
fmt.Println("ip",*ip)
fmt.Println("port",*port)
}
//使用go build 编译 执行./eg1 --port 8080 -ip 10.0.0.241
//结果
//ip 10.0.0.241
//port 8080
方式二:
通过flag.XxxVar()
方法将flag绑定到一个变量,该种方式返回值类型,我们将上述示例改为flag.xxxVar()
package main import (
"fmt"
"flag"
)
func main() {
var ip string
var port int
flag.StringVar(&ip,"ip","10.0.0.230","server listen ip") //参数一是变量,后面与flag.String一样
flag.IntVar(&port,"port",,"server port")
flag.Parse()
fmt.Println("ip",ip)
fmt.Println("port",port)
}
// 同样编译完成运行./eg1 --port 8080 -ip 10.0.0.241
//结果
//ip 10.0.0.241
//port 8080
六、序列化、反序列化
应用程序交互,即数据的交互,数据交互永远离不开序列化,常见的数据库交互格式如json、xml,在go语言中提供了诸多的序列化格式:
方式 | 优点 | 缺点 |
binary | 性能高 | 不支持不确定大小类型 int、slice、string |
json | 支持多种类型 | 性能低于 binary 和 protobuf |
protobuf | 支持多种类型,性能高 | 需要单独存放结构,如果结构变动需要重新生成 .pb.go 文件 |
gob | 支持多种类型 | 性能低 |
json
json格式数据是现在数据交互用的最多的数据格式,go一般通过json.Marshal()进行序列化,通过json.Marshal()反序列化。
示例一:序列化struct
package main import (
"encoding/json"
"fmt"
) type Student struct {
Name string `json:"name"` //序列化时将字段变为小写
Age int `json:"age"`
Score int `json:"score"`
} func main() {
stu1 :=&Student{Name:"wd",Age:,Score:}
res,err := json.Marshal(stu1)
if err != nil {
fmt.Println("json encode error")
return
}
fmt.Printf("json string: %s",res)
}// 结果
//json string :{"name":"wd","age":22,"score":100}
示例二:序列化map
package main import (
"encoding/json"
"fmt"
) type Dictmap map[int]string func main() { map1 := &Dictmap{:"wd",:"name"}
res,err := json.Marshal(map1)
if err != nil {
fmt.Println("json encode error")
return
}
fmt.Printf("json string: %s",res)
}
// 结果:json string: {"1":"wd","2":"name"}
反序列化
反序列化过程中需要注意,数据格式是byte切片
func Unmarshal(data []byte, v interface{}) error
反序列化struct示例:
package main import (
"encoding/json"
"fmt"
) type Student struct {
Name string `json:"name"`
Age int `json:"age"`
Score int `json:"score"`
} func main() {
data := `{"name":"wd","age":,"score":}`
var stu1 Student
err := json.Unmarshal([]byte(data),&stu1)
if err != nil {
fmt.Println("json decode error: ",err)
return
}
fmt.Printf("struct obj is : %s",stu1.Name)
}
//结果
//struct obj is : wd
gob
Gob(Go binary 的缩写) 是 Go 自己的以二进制形式序列化和反序列化程序数据的格式,其方法在encoding中,类似于 Python 的 "pickle" ,这样的数据格式只能在go程序之间进行数据交互。
序列化和反序列化示例:
package main import (
"bytes"
"encoding/gob"
"fmt"
) type Student struct {
Name string `json:"name"`
Age int `json:"age"`
Score int `json:"score"`
} func main() {
stu1 := Student{"wd", , }
var buf bytes.Buffer enc := gob.NewEncoder(&buf)
dec := gob.NewDecoder(&buf) if err := enc.Encode(stu1); err != nil {
fmt.Println("encode error:", err)
}
fmt.Printf("gob res %s: \n",enc)
var stu2 Student
if err := dec.Decode(&stu2); err != nil {
fmt.Println("decode error:", err)
}
fmt.Println("decode res:",stu2)
} //decode res: wd
Binary
endoding包中的binnary主要用于二进制数据序列化,但是局限性较高。
注意: 如果字段中有不确定大小的类型,如 int,slice,string 等,则会报错。使用binary.Write进行序列化时候,数据类型必须是固定大小如:int只能使用int64、int32,切片需要有固定长度。
package main import (
"bytes"
"encoding/binary"
"fmt"
) type Message struct {
Id uint64
Size uint64
} func main() {
m1 := Message{, }
buf := new(bytes.Buffer)
err := binary.Write(buf, binary.LittleEndian, m1) // 序列化
if err != nil {
fmt.Println("binary write error:", err)
}
fmt.Printf("binary res: %s \n ",m1) //binary res: {%!s(uint64=1) %!s(uint64=22)}
var m2 Message
err1 := binary.Read(buf, binary.LittleEndian, &m2); //反序列化
if err1 != nil {
fmt.Println("binary read error:", err)
}
fmt.Printf("decode res: %s",m2) //decode res: {%!s(uint64=1) %!s(uint64=22)}
}
ProtoBuf
对于ProtoBuf并不是go语言中包自带的,需要自行安装你需要安装protoc编译器,以及protoc库以及生成相关的类
安装方法(linux或者mac):
go get -u github.com/golang/protobuf/proto
go get -u github.com/golang/protobuf/proto-gen-go
go install github.com/golang/protobuf/proto
go install github.com/golang/protobuf/protoc-gen-go
使用:
创建一个test.proto文件
//指定版本
//注意proto3与proto2的写法有些不同
syntax = "proto3"; //包名,通过protoc生成时go文件时
package test; //手机类型
//枚举类型第一个字段必须为0
enum PhoneType {
HOME = ;
WORK = ;
} //手机
message Phone {
PhoneType type = ;
string number = ;
} //人
message Person {
//后面的数字表示标识号
int32 id = ;
string name = ;
//repeated表示可重复
//可以有多个手机
repeated Phone phones = ;
} //联系簿
message ContactBook {
repeated Person persons = ;
}
运行命令:protoc --go_out=. *.proto,生成test.pb.go文件
使用protobuf
package main; import (
"github.com/golang/protobuf/proto"
"protobuf/test"
"io/ioutil"
"os"
"fmt"
) func write() {
p1 := &test.Person{
Id: ,
Name: "小张",
Phones: []*test.Phone{
{test.PhoneType_HOME, ""},
{test.PhoneType_WORK, ""},
},
};
p2 := &test.Person{
Id: ,
Name: "小王",
Phones: []*test.Phone{
{test.PhoneType_HOME, ""},
{test.PhoneType_WORK, ""},
},
}; //创建地址簿
book := &test.ContactBook{};
book.Persons = append(book.Persons, p1);
book.Persons = append(book.Persons, p2); //编码数据
data, _ := proto.Marshal(book);
//把数据写入文件
ioutil.WriteFile("./test.txt", data, os.ModePerm);
} func read() {
//读取文件数据
data, _ := ioutil.ReadFile("./test.txt");
book := &test.ContactBook{};
//解码数据
proto.Unmarshal(data, book);
for _, v := range book.Persons {
fmt.Println(v.Id, v.Name);
for _, vv := range v.Phones {
fmt.Println(vv.Type, vv.Number);
}
}
} func main() {
write();
read();
}
protobuf使用
go语言之行--文件操作、命令行参数、序列化与反序列化详解的更多相关文章
- Linux命令:修改文件权限命令chmod、chgrp、chown详解
Linux系统中的每个文件和目录都有访问许可权限,用它来确定谁可以通过何种方式对文件和目录进行访问和操作. 文件或目录的访问权 限分为只读,只写和可执行三种.以文件为例,只读权限表示只允许读其内容,而 ...
- HDFS文件操作(命令行)
HDFS是一种分布式文件系统,为MapReduce这种框架下的海量数据分布式处理而设计. Hadoop之HDFS文件操作常有两种方式,一种是命令行方式,即Hadoop提供了一套与Linux文件命令类似 ...
- Linux文件搜索命令locate、which、grep详解
命令locate详解 命令locate,其基本功能是在文件资料库中可以快速的搜索系统文件,占用系统资源很少,例如:locate my.cnf 还可以使用locate -i [文件名],不区分大小写进行 ...
- Linux查找并删除重复文件的命令行fdupes工具,dupeGuru图形工具
查了几十个网页,找到这个接近满意的解决方案http://unix.stackexchange.com/questions/146197/fdupes-delete-files-aft... 不过正则里 ...
- 实战Git命令(界面操作+命令行)
先说明下公司的发版步骤,当需要开发一个新的功能,先从master分支中拉出一个自己的分支a(假设分支为a),在a分支开发功能完后,需要切换到dev分支,然后把自己的分支a合到dev分支,部署测试环境让 ...
- gplaycli—— 用于从 GooglePlayStore 中下载和管理 Apk 文件的命令行工具
gplaycli-- 用于从 GooglePlayStore 中下载和管理 Apk 文件的命令行工具 这个 GooglePlay市场 中 https://play.google.com/store/a ...
- shell脚本命令 运行python文件&python命令行运行python代码
单独的python文件运行的时候 报错: 在shell脚本中,运行shell脚本命令:在Python命令行中,运行Python代码.然而,“python hello.py”是一个脚本命令,不是pyth ...
- Unix/Linux环境C编程入门教程(41) C语言库函数的文件操作详解
上一篇博客我们讲解了如何使用Linux提供的文件操作函数,本文主要讲解使用C语言提供的文件操作的库函数. 1.函数介绍 fopen(打开文件) 相关函数 open,fclose 表头文件 #in ...
- Unix/Linux环境C编程新手教程(41) C语言库函数的文件操作具体解释
上一篇博客我们解说了怎样使用Linux提供的文件操作函数,本文主要解说使用C语言提供的文件操作的库函数. 1.函数介绍 fopen(打开文件) 相关函数 open,fclose 表头文件 #in ...
随机推荐
- <Android 应用 之路> JuheNews For aNdroid (改进版)
简介 最新版应用已经上线,欢迎下载使用,提出宝贵意见: http://shouji.baidu.com/software/10720907.html 上一篇介绍的是最开始自己制作的一个采用聚合数据免费 ...
- python实现分页插件
class Pages: def __init__(self, current_page, data_count, per_page_count=10, pager_num=7):#pager_num ...
- WOSA/XFS PTR Form解析库—FormRule.h
#ifndef _FORMRULE_H_#define _FORMRULE_H_ #include <XFSPTR.H>#include <string>#include &l ...
- Unity Profiler连接Android真机调试
Profiler在Editor模式就可以观看性能消耗,但是毕竟电脑配置高,跟手机真机环境还是有区别.实际开发中的优化还是推荐用真机测试. 因为IOS一般比Android手机的配置高,在Android平 ...
- bootstrap selectpicker 通过代码指定选中值 BootStrap selectpicker后台动态绑定数据 selectpicker 获取选中option的属性或者值
bootstrap-select使用 bootstrap selectpicker 通过代码指定选中值 $('#subjectno').selectpicker('val',(row.subjectn ...
- LeetCode题解之Linked List Cycle
1.题目描述 2.问题分析 使用快慢指针方法,一个快指针,一个慢指针,如果到某个时候,快指针追上了慢指针,则说明有环存在. 3.代码 bool hasCycle(ListNode *head) { i ...
- 通过递增快照备份 Azure 非托管 VM 磁盘
概述 Azure 存储提供创建 Blob 快照的功能. 快照将捕获该时间点的 Blob 状态. 本文介绍有关如何使用快照维护虚拟机磁盘备份的方案. 如果选择不使用 Azure 备份和恢复服务,但想要为 ...
- sqlserver 一键备份,异机还原脚本
REM +---------------------------------------------------------------------------------+ REM |desc AU ...
- 如何避免SHRINKDATABASE & SHRINKFILE 产生索引碎片(转载)
1. TRUNCATEONLY参数的使用我们在建立的Job中通常使用如下的语法DBCC SHRINKDATABASE (N'DB', 10,TruncateOnly)其中TruncateOnly的用处 ...
- Cisco ASA 使用ASDM 配置管理口 方法
CISCO ASA防火墙ASDM安装和配置 准备一条串口线一边接台式机或笔记本一边接防火墙的CONSOLE 接口,通过CRT或者超级终端连接ASA在用ASDM图形管理界面之前须在串口下输入一些命令开启 ...