服务计算课程——开发简单的CLI程序

服务计算——开发简单的CLI程序

代码请看github
根据Linux命令行上的Selpg指令,结合Flag和PFlag利用go语言开发简单的CLI程序

  • 论述

    • 按照上述链接的说明,Linux命令行通过默认或指定参数调用指令,其中指定参数中使用Flag中方法,通过类似-a10的方式a对应参数赋值为10,而PFlag方法则为相应的变形,变为诸如--a=10的方式为参数赋值。通过类似的方法,利用PFlag构建简单的读取文件命令指令。
  • 代码

    • 构建参数的Help指令,指导用户如何传入参数调用指令。其中,根据PFlag中的IntVar、StringVar函数,构建相应的命令,其后调用Parse函数解析上述Help指令即如下代码:

      func set_flag(){
      	pflag.IntVar(&(start_page), "s", -1, "Define start page, defaults to -1")
      	pflag.IntVar(&(end_page), "e", -1, "Define end page, defaults to -1")
      	pflag.IntVar(&(page_len), "l", 1, "Define page length, defaults to 1")
      	pflag.StringVar(&(in_file), "i", "in_file.txt", "Define input file's name, defaults to in_file.txt")
      	pflag.StringVar(&(print_des), "d", "", "Define input file's name, defaults to NULL")
      	//pflag.StringVar(&(err_des), "e", "../errpr_file.txt", "Define input file's name, defaults to errpr_file.txt")
      	pflag.Parse()
      }
      	```	
      
    • 由于按照需求,需要进一步对参数进行处理,即根据传入的参数指令配置相关变量信息,根据os.Args参数处理。

       	func check_args_1(args []string) {
         for _, para := range args[1:] {
         	switch{
         	case para[0:2] == "--s", para[0:2] == "--e":
         		if val, err := strconv.Atoi(para[4:]); err != nil || val < 0{
         			if err != nil{
         				fmt.Fprintf(os.Stderr, fmt.Sprintf("%s",err))
         			}else{
         				fmt.Fprintf(os.Stderr, "\n[Error] The start/end page can not less then zero or be empty\n")
         			}
         			os.Exit(2)
         		}
         	case para[0:2] == "--l":
         		if val, err := strconv.Atoi(para[4:]); err != nil || val < 0{
         			if err != nil{
         				fmt.Fprintf(os.Stderr, fmt.Sprintf("%s",err))
         			}else{
         				fmt.Fprintf(os.Stderr, "\n[Error] The page lenth can not less then zero\n")
         			}
         			os.Exit(3)
         		}
         	case para[0:2] == "--i":
         		if file, err := os.Open(para[4:]); err != nil {
         			fmt.Fprintf(os.Stderr, fmt.Sprintf("%s",err))
         			os.Exit(4)
         		}else{
         			file.Close()
         		}
         	case para[0] == '<', para[0] == '>':
         		if file, err := os.Open(para[1:]); err != nil {
         			fmt.Fprintf(os.Stderr, fmt.Sprintf("%s",err))
         			os.Exit(4)
         		}else{
         			if para[0] == '<'{
         				in_file = para[1:]
         			}else{
         				print_des = para[1:]
         			}
         			file.Close()
         		}
      
         	}
         }
         }
      
    • 初步处理完参数后,还需要进一步检查参数即判断start_page、end_page的关系。

          func check_args_2(){
         	if selpg.start_page > selpg.end_page {
         		fmt.Fprintf(os.Stderr, "\n[Error] The start page should larger than the end page\n")
         		os.Exit(5)
         	}
         }
      
    • 配置相关 selpg类,保存上述获取的参数信息。

      	type Selpg struct{
      		start_page int
      		end_page int
      		page_len int
      		in_file string
      		print_des string
      		err_des string
      	}
      
    • 根据上述获得的参数信息,进行命令的处理,即为是否从指定路径读取文件,是否向指定路径写文件以及读取的行数以及起始终止位置等。

      func process(){
      	var outfile *os.File
      	
      	if selpg.print_des != ""{
      		if _,err_exit := os.Stat(selpg.print_des); err_exit != nil {
      			outfile,_= os.Create(selpg.print_des)
      		}else{
      			outfile, _ = os.OpenFile(selpg.print_des,os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0666)
      		}
      	}
      	defer outfile.Close()
      	if selpg.in_file != ""{
      		var infile *os.File
      		
      		infile, _ = os.OpenFile(selpg.in_file, os.O_RDWR, 0666)
      		defer infile.Close()
      		buf := bufio.NewReader(infile)
      		page_count := 1
      		line_count := 0
      		for page_count <= selpg.end_page {
      			line, in_err := buf.ReadString('\n')
      			if in_err != nil {
      				fmt.Fprintf(os.Stderr, fmt.Sprintf("%s",in_err))
      				os.Exit(7)
      			}
      			if in_err == io.EOF{
      				break
      			}
      			if page_count >= selpg.start_page{
      				if selpg.print_des != ""{
      					outfile.Write([]byte(line))
      				}else{
      					fmt.Println(line)
      				}
      			}
      			line_count++
      			if line_count == selpg.page_len {
      				line_count = 0
      				page_count++
      			}
      		}
      	}
      }
      
    • 传入指令,在未指定输出文件下输出不同的s、e参数值,其输出内容如下:

    在这里插入图片描述
    在这里插入图片描述

    • 当使用d参数指定输出文件时,终端输出以及相应文件输出内容分别如下:
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述
    • 当命令行输入错误或未输入必要的参数时,输出相应的Help信息。
      在这里插入图片描述
    • 通过>指定输出文件后,终端和文件输出内容分别如下。
      在这里插入图片描述
      在这里插入图片描述
    • 通过比较可以看出,当>传入参数时,Ubuntu终端也会解析指令,从而将原有的关于PFlag参数信息输出到相应位置。
从1990年代开始,IT的快速发展为传统服务业带来了的巨大的革新并逐步形成了知识经济为主体的现代服务业。同第一产业的农业和第二产业的工业一样,服务业的快速发展也需要相应的理论体系和工程技术加以支持。IBM公司于2004年提出的"服务科学、管理与工程(Service Sciences, Management and Engineering, SSME)",试图将传统的服务相关学科的知识整合起来形成一个称为"服务科学"的独立学科,吸引学术界、教育界和工业界共同关注"服务"的研究与实践, 进而提高服务产业的水平。"服务计算"正是关注服务科学中基础理论、技术体系和工程实践的学科门类,高等学校培养的面向现代服务业的科技型人才必须具备该学科的相关知识及应用能力。作为现代服务科学的奠基石,服务计算已成为一项桥接商业服务与信息技术服务的跨学科的科学技术。IEEE认为服务计算已成为面向现代服务业的一门新的基础学科。服务计算已经成为新兴的系统构造和 企业管理模型,产业界迫切需要掌握服务计算相关理论和技术的软件工程师和管理人员。本课程面对这一需求,涵盖了服务计算方向的主要知识点,主要内容包括服务计算概要、面向服务的体系结构(方法学)、服务计算技术(技术观)、Web服务基础(实现式)、实时服务计算(航空航天特色)和服务计算的基础理论(理论点)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值