Go实现http同步文件操作 - 增删改查

news2025/1/10 21:27:10

http同步文件操作 - 增删改查

  • http同步文件操作 - 增删改查
  • 1. 前置要求
    • 1.1. 构建结构体 文件名 + 文件内容
      • 1.1.1. 页面结构体
      • 1.1.2. 为`Page`结构体绑定方法:`Save`
      • 1.1.3. 对`Page`结构体支持页面内容查看方法,同时提供页面文件是否存在的方法
    • 1.2. 简单验证上面的结构体是否可以直接改变值
  • 使用HTTP来完成对页面的增删改查
    • 1. 增加对页面文件保存的操作
      • 增加mian方法,进行测试
    • 2. 增加对页面文件进行查看内容的操作
      • 增加mian方法,进行测试
    • 3. 增加对页面文件删除操作
      • 增加mian方法,进行测试
    • 4. 增加对页面文件内容更新的操作
      • 增加mian方法,进行测试
      • 增删改查的操作保存在一个文件里,内容如下
  • other

http同步文件操作 - 增删改查

1. 前置要求

1.1. 构建结构体 文件名 + 文件内容

1.1.1. 页面结构体

type Page struct {
	Title string `json:"title"`
	Body  string `json:"body"`
}
// ``符号为结构体的标准,可忽略

1.1.2. 为Page结构体绑定方法:Save

// SavePage 页面文件保存方法,保存到数据库,这里保存到页面文件中
// 使用bufio操作文件
// notice: 延时关闭 flush
// 绑定Page指针变量
func (page *Page) SavePage(title string, body string) (err error) {
	title += ".txt"
	// todo 1. 拿到页面文件句柄
	file, err := os.OpenFile(title, os.O_CREATE|os.O_RDWR, fs.ModePerm)
	// todo final step
	defer func() { _ = file.Close() }()
	if err != nil {
		fmt.Println("无法获取到页面文件,error:", err)
		return err
	}
	// todo 2. 打开页面文件
	writer := bufio.NewWriter(file)
	// todo 3. 往页面文件写入内容
	nByteNum, err := writer.Write([]byte(body))
	if err != nil {
		fmt.Println("页面文件保存失败,error:", err)
		return err
	}
	// todo 4. 刷写数据出去
	_ = writer.Flush()
	fmt.Println("写入的内容大小为:", nByteNum, "字节")
	return nil
}
  1. 内容添加文件后缀,固定为.txt

  2. 使用bufio操作文件,可以更换其它方式

  3. *指针变量

  4. 注意事项:

    1. 延时关闭

      defer func() { _ = file.Close() }()

    2. 数据刷写

      _ = writer.Flush()

1.1.3. 对Page结构体支持页面内容查看方法,同时提供页面文件是否存在的方法


// 判断是否存在该页面文件名,不需要加后缀!已经手动添加;也可以优化,多加入参数表示后缀即可
func ExistFile(fileName string) bool {
	if _, err := os.Stat(fileName + ".txt"); err != nil {
		if os.IsNotExist(err) {
			return false
		}
	}
	return true
}

// 查看指定的页面文件内容
// 使用os操作文件
func ViewPage(title string) (page *Page) {
	page = &Page{}
	page.Title = title
	if ExistFile(title) {
		fileContent, err := os.ReadFile(title + ".txt")
		if err != nil {
			fmt.Println("读取页面文件出错, error is :", err)
		} else {
			page.Body = string(fileContent)
		}
	}
	return page
}
  • 上面内容为一个文件,该entity/entity.go文件的全部代码为:
package entity

import (
	"bufio"
	"fmt"
	"io/fs"
	"os"
)

type Page struct {
	Title string `json:"title"`
	Body  string `json:"body"`
}

// SavePage 页面文件保存方法,保存到数据库,这里保存到页面文件中
// 使用bufio操作文件
// notice: 延时关闭 flush
func (page *Page) SavePage(title string, body string) (err error) {
	title += ".txt"
	// todo 1. 拿到页面文件句柄
	file, err := os.OpenFile(title, os.O_CREATE|os.O_RDWR, fs.ModePerm)
	// todo final step
	defer func() { _ = file.Close() }()
	if err != nil {
		fmt.Println("无法获取到页面文件,error:", err)
		return err
	}
	// todo 2. 打开页面文件
	writer := bufio.NewWriter(file)
	// todo 3. 往页面文件写入内容
	nByteNum, err := writer.Write([]byte(body))
	if err != nil {
		fmt.Println("页面文件保存失败,error:", err)
		return err
	}
	// todo 4. 刷写数据出去
	_ = writer.Flush()
	fmt.Println("写入的内容大小为:", nByteNum, "字节")
	return nil
}

// 判断是否存在该页面文件名,不需要加后缀!
func ExistFile(fileName string) bool {
	if _, err := os.Stat(fileName + ".txt"); err != nil {
		if os.IsNotExist(err) {
			return false
		}
	}
	return true
}

// 查看指定的页面文件内容
// 使用os操作文件
func ViewPage(title string) (page *Page) {
	page = &Page{}
	page.Title = title
	if ExistFile(title) {
		fileContent, err := os.ReadFile(title + ".txt")
		if err != nil {
			fmt.Println("读取页面文件出错, error is :", err)
		} else {
			page.Body = string(fileContent)
		}
	}
	return page
}

1.2. 简单验证上面的结构体是否可以直接改变值

func main() {
	// 验证你的结构体是否发生改变 - 指针变量
	page := entity.ViewPage("TestPage")
	fmt.Println(page)
	page.Body = "change"
	fmt.Println(page)
}

使用HTTP来完成对页面的增删改查

1. 增加对页面文件保存的操作

// http方式保存page
// 默认从请求体中获取内容作为body传入文件
// 直接调用/savePage的body默认值为:this is a default value
// 更新操作也会调用该方法,body值为 上传的请求体内容
func saveHandler(responseWriter http.ResponseWriter, request *http.Request) {
	// todo 1. 在url中获取 page的title值
	title := request.URL.Path[len("/savePage/"):]
	// todo 2. 填充 body内容
	page := &entity.Page{}
	// important 本人在后面update会遇到坑,默认从请求体中获取body
	// todo 2.1. 优先考虑从请求体获取body
	body := request.FormValue("body")
	// todo 2.2. 请求体为空串,则赋值默认值
	if body == "" {
		body = "this is a default value"
	}
	// todo 3. 将body值写入到页面文件
	err := page.SavePage(title, body)
	// todo 3.1. 展示写入结果
	if err != nil {
		_, _ = responseWriter.Write([]byte("页面文件保存不成功"))
		fmt.Println("页面文件保存不成功,error is :", err)
		return
	} else {
		message := "页面文件保存成功"
		_, _ = responseWriter.Write([]byte(message))
		fmt.Println(message)
	}
}

增加mian方法,进行测试

func main() {
    // url路径要对应,当然你也可以更改;
    // 若修改viewPage,上面的viewHandler方法也要对应改变
	http.HandleFunc("/savePage/", saveHandler)
	err := http.ListenAndServe(":8989", nil)
	if err != nil {
		fmt.Println("端口异常")
	}
}
  • 运行程序,然后到浏览器访问:localhost:8989/viewPage/myFirst2

    • 结果会展示

      • 在这里插入图片描述

      • 页面也会展示成功的提示

    • 项目目录下会生成myFirst2.txt文件,内容为:

      this is a default value
      

2. 增加对页面文件进行查看内容的操作

// http 方式查看特定的page内容
// 使用硬编码页面
func viewHandler(responseWriter http.ResponseWriter, request *http.Request) {
	// todo 1. 在url中获取 page的title值
	title := request.URL.Path[len("/viewPage/"):]
	// todo 2. 判断是否已经存在该页面文件
	if !entity.ExistFile(title) {
		// todo 2.1. 不存在该页面文件就结束
		fmt.Printf("不存在%v页面文件", title)
		_, _ = responseWriter.Write([]byte("不存在该页面文件"))
		return
	}
	// todo 2.2. 获取该页面的内容
	page := entity.ViewPage(title)
	body := []byte(page.Body)
	// todo 3. 页面展示内容
	_, _ = responseWriter.Write(body)
}

增加mian方法,进行测试

func main() {
    // url路径要对应,当然你也可以更改;
    // 若修改viewPage,上面的viewHandler方法也要对应改变
    http.HandleFunc("/savePage/", saveHandler)
	http.HandleFunc("/viewPage/", viewHandler)
	err := http.ListenAndServe(":8989", nil)
	if err != nil {
		fmt.Println("端口异常")
	}
}
  • 运行程序,到浏览器输入 localhost:8989/viewPage/myFirst2

    • 会查看当前项目下是否存在myFirst2.txt文件,如果存在,则会返回页面文件内容。反之会展示不存在该页面文件内容

      • 我们前面生成了myFirst2.txt文件,效果为:

        • 在这里插入图片描述

        • 页面展示的内容为文件的内容

      • 我们访问没有对应的文件url:localhost:8989/viewPage/myFirst3

        • 效果为:

          在这里插入图片描述

        • 即页面展示不存在该文件。你也可以再利用savePage来生成一个myFirst3.txt文件

3. 增加对页面文件删除操作

// http方式删除页面文件
func deleteHandler(responseWriter http.ResponseWriter, request *http.Request) {
	// todo 1. 在url中获取 page的title值
	title := request.URL.Path[len("/deletePage/"):]
	// todo 2. 判断是否存在该页面文件
	if !entity.ExistFile(title) {
		_, _ = responseWriter.Write([]byte("页面文件不存在,无法删除"))
		return
	} else {
		// todo 3. 移除页面文件
		err := os.Remove(title + ".txt")
		if err != nil {
			_, _ = responseWriter.Write([]byte("页面文件删除异常,请检查你的权限,或者联系管理员"))
			return
		}
		_, _ = responseWriter.Write([]byte("页面文件删除成功"))
	}
}

增加mian方法,进行测试

func main() {
    // url路径要对应,当然你也可以更改;
    // 若修改viewPage,上面的viewHandler方法也要对应改变
    http.HandleFunc("/savePage/", saveHandler)
	http.HandleFunc("/viewPage/", viewHandler)
    http.HandleFunc("/deletePage/", deleteHandler)
	err := http.ListenAndServe(":8989", nil)
	if err != nil {
		fmt.Println("端口异常")
	}
}
  • 运行程序,到浏览器输入 localhost:8989/deletePage/myFirst2

    • 程序会删除myFirst2文件,效果为:

      在这里插入图片描述

      • 项目下的文件已经被删除,若此时再次执行则会提示无法删除

        在这里插入图片描述

4. 增加对页面文件内容更新的操作

// http方式更新页面文件
func updateHandler(responseWriter http.ResponseWriter, request *http.Request) {
	// todo 1. 在url中获取 page的title值
	title := request.URL.Path[len("/updatePage/"):]
	// todo 2. 查看该页面文件
	page := entity.ViewPage(title)
	// todo 3. 填充html页面,硬编码
	fmt.Fprintf(responseWriter, "<h1>Editing %s</h1>"+
		// 直接调用了 saveHandler
		// todo 4. 再次保存该页面文件
		"<form action=\"/savePage/%s\" method=\"POST\">"+
		"<textarea name=\"body\">%s</textarea><br>"+
		"<input type=\"submit\" value=\"Save\">"+
		"</form>",
		page.Title, page.Title, page.Body)
}
  • notice :todo的第四步,保存后会出发/savePage的访问动作

增加mian方法,进行测试

func main() {
    // url路径要对应,当然你也可以更改;
    // 若修改viewPage,上面的viewHandler方法也要对应改变
    http.HandleFunc("/savePage/", saveHandler)
    http.HandleFunc("/viewPage/", viewHandler)
    http.HandleFunc("/deletePage/", deleteHandler)
    http.HandleFunc("/updatePage/", updateHandler)
	err := http.ListenAndServe(":8989", nil)
	if err != nil {
		fmt.Println("端口异常")
	}
}
  • 运行程序,到浏览器输入 localhost:8989/updatePage/myFirst2

    • 页面会返回一个html页面,效果为:

      在这里插入图片描述

      • 尝试在文本框输入内容,这里输入hello,java页 可乐 唱跳rap,然后点击Save进行保存。

        • 然后页面会进行跳转到保存页面,效果图为:

          在这里插入图片描述

增删改查的操作保存在一个文件里,内容如下

package main

import (
	"fmt"
	"goland-setting/test/webapp/entity"
	"net/http"
	"os"
)

// http 方式查看特定的page
// 使用硬编码页面
func viewHandler(responseWriter http.ResponseWriter, request *http.Request) {
	// todo 1. 在url中获取 page的title值
	title := request.URL.Path[len("/viewPage/"):]
	// todo 2. 判断是否已经存在该页面文件
	if !entity.ExistFile(title) {
		// todo 2.1. 不存在该页面文件就结束
		fmt.Printf("不存在%v页面文件", title)
		_, _ = responseWriter.Write([]byte("不存在该页面文件"))
		return
	}
	// todo 2.2. 获取该页面的内容
	page := entity.ViewPage(title)
	body := []byte(page.Body)
	// todo 3. 页面展示内容
	_, _ = responseWriter.Write(body)
}

// http方式保存page
// 默认从请求体中获取body
// 直接调用/savePage的body默认值为:this is a default value
// 更新操作也会调用该方法,body值为 上传的请求体内容
func saveHandler(responseWriter http.ResponseWriter, request *http.Request) {
	// todo 1. 在url中获取 page的title值
	title := request.URL.Path[len("/savePage/"):]
	// todo 2. 填充 body内容
	page := &entity.Page{}
	// important 本人在后面update会遇到坑,默认从请求体中获取body
	// todo 2.1. 优先考虑从请求体获取body
	body := request.FormValue("body")
	// todo 2.2. 请求体为空串,则赋值默认值
	if body == "" {
		body = "this is a default value"
	}
	// todo 3. 将body值写入到页面文件
	err := page.SavePage(title, body)
	// todo 3.1. 展示写入结果
	if err != nil {
		_, _ = responseWriter.Write([]byte("页面文件保存不成功"))
		fmt.Println("页面文件保存不成功,error is :", err)
		return
	} else {
		message := "页面文件保存成功"
		_, _ = responseWriter.Write([]byte(message))
		fmt.Println(message)
	}
}

// http方式删除页面文件
func deleteHandler(responseWriter http.ResponseWriter, request *http.Request) {
	// todo 1. 在url中获取 page的title值
	title := request.URL.Path[len("/deletePage/"):]
	// todo 2. 判断是否存在该页面文件
	if !entity.ExistFile(title) {
		_, _ = responseWriter.Write([]byte("页面文件不存在,无法删除"))
		return
	} else {
		// todo 3. 移除页面文件
		err := os.Remove(title + ".txt")
		if err != nil {
			_, _ = responseWriter.Write([]byte("页面文件删除异常,请检查你的权限,或者联系管理员"))
			return
		}
		_, _ = responseWriter.Write([]byte("页面文件删除成功"))
	}
}

// http方式更新页面文件
func updateHandler(responseWriter http.ResponseWriter, request *http.Request) {
	// todo 1. 在url中获取 page的title值
	title := request.URL.Path[len("/updatePage/"):]
	// todo 2. 查看该页面文件
	page := entity.ViewPage(title)
	// todo 3. 填充html页面
	fmt.Fprintf(responseWriter, "<h1>Editing %s</h1>"+
		// 直接调用了 saveHandler
		// todo 4. 再次保存该页面文件
		"<form action=\"/savePage/%s\" method=\"POST\">"+
		"<textarea name=\"body\">%s</textarea><br>"+
		"<input type=\"submit\" value=\"Save\">"+
		"</form>",
		page.Title, page.Title, page.Body)
}

func main() {
	http.HandleFunc("/savePage/", saveHandler)
	http.HandleFunc("/deletePage/", deleteHandler)
	http.HandleFunc("/updatePage/", updateHandler)
	http.HandleFunc("/viewPage/", viewHandler)
	err := http.ListenAndServe(":8989", nil)
	if err != nil {
		fmt.Println("端口异常")
	}
}

一个简单的webApp就完成了。

other

  • 对于更新操作,服务器硬编码html太难了,可以使用html/template来渲染,这样会好很多。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1312717.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【树莓派】高级开发概述、开发环境搭建(内核镜像拷贝至树莓派并启动新内核)

一、树莓派开发环境搭建 二、Linux文件系统的目录结构 三、树莓派Linux源码目录树分析 四、树莓派Linux源码配置 五、如何配置树莓派的Linux内核 六、树莓派Linux内核编译 七、配置启动参数的cmdline.txt 一、树莓派开发环境搭建 树莓派官网 raspberrypi raspberrypi/tools…

FM30H12G N通道沟槽电源MOS管 封装形式PDFN5*6

FM30H12G 是一款 N通道沟槽电源的场效应管&#xff08;MOS管&#xff09;&#xff0c;封装形式&#xff1a;PDFN5*6。 来百度APP畅享高清图片 FM30H12G应用&#xff1a; 1、液晶电视 2、笔记本 3、电梯 4、感应加热 5、电动工具

低碳未来,智慧共赢!SIA上海工业自动化展2024焕新出发!

近年来&#xff0c;全球积极推进智能化数字化赋能工程&#xff0c;国内制造业也全面向数字化智能化转型。重点企业、龙头企业充分发挥综合优势&#xff0c;着力推动智能工厂、数字化车间的建设&#xff0c;深入实施“机器换人”战略&#xff0c;以促进产品、企业、产业全面升级…

使用 PAI-Blade 加速 StableDiffusion Fine-Tuning

01 背景 Stable Diffusion 模型自从发布以来在互联网上发展迅猛&#xff0c;它可以根据用户输入的文本描述信息生成相关图片&#xff0c;用户也可以提供自己喜爱的风格的照片&#xff0c;来对模型进行微调。例如当我们输入 "A photo of sks dog in a bucket" &…

城市数字化管理、智慧城市、数字孪生城市间的关系和演变

基于《基于数字孪生的智慧城市》和《2023版数字孪生世界白皮书》&#xff0c;我们可以全面了解从数字城市管理到智慧城市&#xff0c;再到数字孪生城市的关系和发展历程。 以下是这一顺序和继承关系的要点总结&#xff1a; 城市数字化管理 这是城市地区向智慧城市演进的初始…

蓝桥杯专题-真题版含答案-【信用卡号校验】【数量周期】【取球博弈】【Playfair密码】

Unity3D特效百例案例项目实战源码Android-Unity实战问题汇总游戏脚本-辅助自动化Android控件全解手册再战Android系列Scratch编程案例软考全系列Unity3D学习专栏蓝桥系列ChatGPT和AIGC &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff0c;以及各种资源分…

节气丨大雪过后,阳气归根的十五天,这些事再不做就晚了!

亲爱的家人们大家好&#xff0c;大雪&#xff0c;是24节气中的第21个节气&#xff0c;也是冬季的第3个节气。 这一节气的到来&#xff0c;标志着仲冬时节正式开始&#xff0c;特点是气温显著下降、降水量增多。 古人认为“秋冬养阴”&#xff0c;所谓养阴&#xff0c;即是养阳…

浏览器输入URL再按下回车会经历哪些过程

目录 前言 一、解析URL 二、解析域名(DNS) 三、TCP三次握手建立连接 1.seq、syn、ack含义 2.三次握手 四、发送http/https请求 五、服务器响应请求 六、浏览器解析渲染页面 七、TCP四次挥手断开连接 总结 前言 看各种面经发现这个问题是一个高频出现的面试问题&#xff0c;但…

LLM之RAG实战(四):Self-RAG如何革命工业LLM

论文地址&#xff1a;https://arxiv.org/pdf/2310.11511.pdf Github地址&#xff1a;https://github.com/AkariAsai/self-rag 尽管LLM&#xff08;大型语言模型&#xff09;的模型和数据规模不断增加&#xff0c;但它们仍然面临事实错误的问题。现有的Retrieval-Augmented Gen…

详解—C++右值引用

目录 一、右值引用概念 二、 左值与右值 三、引用与右值引用比较 四、值的形式返回对象的缺陷 五、移动语义 六、右值引用引用左值 七、完美转发 八、右值引用作用 一、右值引用概念 C98中提出了引用的概念&#xff0c;引用即别名&#xff0c;引用变量与其引用实体公共…

uniapp实现检查版本检测,更新

1.首先需要获取当前app的版本 const systemInfo uni.getSystemInfoSync();// 应用程序版本号// #ifdef APPme.version systemInfo.appWgtVersion;// #endif// #ifdef H5me.version systemInfo.appVersion;// #endif2.在获取到服务器保存的app版本 3.点击按钮验证版本号 //…

【源码】车牌检测+QT界面+附带数据库

目录 1、基本介绍2、基本环境3、核心代码3.1、车牌识别3.2、车牌定位3.3、车牌坐标矫正 4、界面展示4.1、主界面4.2、车牌检测4.3、查询功能 5、演示6、链接 1、基本介绍 本项目采用tensorflow&#xff0c;opencv&#xff0c;pyside6和pymql编写&#xff0c;pyside6用来编写UI界…

2023年【上海市安全员B证】考试题库及上海市安全员B证考试资料

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 上海市安全员B证考试题库是安全生产模拟考试一点通总题库中生成的一套上海市安全员B证考试资料&#xff0c;安全生产模拟考试一点通上上海市安全员B证作业手机同步练习。2023年【上海市安全员B证】考试题库及上海市安…

支出管理如何帮助企业抵御经营成本压力?

近日&#xff0c;国内中小企业协会发布最新中小企业发展指数情况&#xff0c;虽然经济持续恢复向好&#xff0c;但依然面临困难和挑战。企业经营成本压力不减&#xff0c;效益状况总体仍不乐观。 许多中小企业采取被动措施&#xff0c;想方设法削减成本。然而&#xff0c;如果…

怎样培养孩子的好习惯

好习惯是孩子成长道路上不可或缺的伴侣。那么&#xff0c;如何在孩子成长的关键时期培养他们良好的习惯呢&#xff1f;以下是几点建议&#xff1a; 一、以身作则&#xff0c;成为孩子的榜样 父母是孩子的第一任老师和榜样。要求孩子做到的事情&#xff0c;自己首先要做到。只有…

常用的系统存储过程

exec sp_databases ---列出服务器上所有的数据库信息 exec sp_help student ---查看学生表中的所有信息 exec sp_renamedb Myschool,MySchools ---更改数据库的名称 需要两个参数 一个是原来数据库的名称 一个是要改为的数据库名称 消息框显示&#xff1a;数据库 名称 MyS…

Docker——2. Docker基础

1. 常见命令 不用重复使用docker run命令&#xff0c;这是创建容器命令&#xff0c;启动容器应该是docker start&#xff1b; docker ps 查看进程运行状态&#xff1b; docker rmi 删除镜像、rm 删除容器&#xff1b; docker logs 查看日志、docker exec 执行命令进入容器内部&…

c#读取XML文件实现晶圆wafermapping显示demo计算电机坐标以便控制电机移动

c#读取XML文件实现晶圆wafermapping显示 功能&#xff1a; 1.读取XML文件&#xff0c;显示mapping图 2.在mapping视图图标移动&#xff0c;实时查看bincode,x,y索引与计算的电机坐标 3.通过设置wafer放在平台的位置x,y轴电机编码值&#xff0c;相机在wafer的中心位置&#…

jstree组件的使用详细教程,部分案例( PHP / fastAdmin )

jstree 组件的使用。 简介&#xff1a;JsTree是一个jquery的插件&#xff0c;它提交一个非常友好并且强大的交互性的树&#xff0c;并且是完全免费或开源的&#xff08;MIT 许可&#xff09;。Jstree技持Html 或 json格式的的数据&#xff0c; 或者是ajax方式的动态请求加载数…

基于ssm的汽车服务商城系统设计与实现论文

摘 要 本课题是根据用户的需要以及网络的优势建立的一个基于Vue的汽车服务商城系统&#xff0c;来更好的为用户提供服务。 本基于Vue的汽车服务商城系统应用Java技术&#xff0c;MYSQL数据库存储数据&#xff0c;基于SSMVue框架开发。在网站的整个开发过程中&#xff0c;首先对…