go提高升阶(四) I/O流学习

news2024/10/3 8:17:28

I/O

官网课程
购买课程找博主推荐

文章目录

  • I/O
      • 文件信息
      • 创建文件、目录
      • IO读
      • IO写(权限)
      • 文件复制
      • Seeker接口
      • 断点续传
      • 遍历文件夹
      • bufio

电脑中一切,都是以 二进制流的形式存在的。

jpg:010100000010010101001010101010010101010 编码格式,还原为一个图片展示到计算机显示器

mp4:010100000010010101001010101010010101010

i:input 输入

o:output 输出

文件信息

文本文件
二进制文件
file 类是封装 os 包中的。

封装了文件的信息:FileInfo 、 Read、Write

1、读取文件信息 FileInfo
2、向文件中写入内容 Write
3、读取文件内容 Read

package main

import (
   "fmt"
   "os"
)

// file
// fileInfo
/*
type FileInfo interface {
   Name() string       // base name of the file
   Size() int64        // length in bytes for regular files; system-dependent for others
   Mode() FileMode     // file mode bits : 权限
   ModTime() time.Time // modification time
   IsDir() bool        // abbreviation for Mode().IsDir()

   // 获取更加详细的文件信息, *syscall.Stat_t  反射来获取
   Sys() any           // underlying data source (can return nil)
*/
func main() {
   // 获取某个文件的状态
   fileinfo, err := os.Stat("D:\\Environment\\GoWorks\\src\\xuego\\lesson11\\test")
   if err != nil {
      return
   }
   fmt.Println(fileinfo.Name())    // demo01.go
   fmt.Println(fileinfo.IsDir())   // false
   fmt.Println(fileinfo.ModTime()) // 2023-02-23 20:25:43.1772351 +0800 CST
   fmt.Println(fileinfo.Size())    // 1186 字节数
   fmt.Println(fileinfo.Mode())    // -rw-rw-rw-
}

创建文件、目录

通过代码创建文件

路径:

  • 相对路径
    • 相对当前目录的路径
    • ./ 当前目录
    • …/ 上一级目录
  • 绝对路径
    • 从盘符开始的路径

创建目录

mkdir / 权限
mkdirAll 创建层级目录
remove 删除目录
removeAll 强制删除目录

package main

import (
   "fmt"
   "os"
)

// 创建目录
// 项目开源框架,一运行,就会自动生成脚手架目录
func main() {

   // 打开一个文件夹(1、存在我就打开  2、不存在,创建这个文件夹)
   // func Mkdir(name string, perm FileMode) error
   // ModePerm : 0777
   err := os.Mkdir("D:\\Environment\\GoWorks\\src\\xuego\\lesson11\\file1", os.ModePerm)
   if err != nil {
      //  存在就无法创建了 Cannot create a file when that file already exists.
      fmt.Println(err)
   }
   fmt.Println("文件夹创建完毕")

   // 创建层级文件夹
   err2 := os.MkdirAll("D:\\Environment\\GoWorks\\src\\xuego\\lesson11\\file2\\aa\\bb\\cc\\dd", os.ModePerm)
   if err2 != nil {
      fmt.Println(err2)
   }
   fmt.Println("层级文件夹创建完毕")

   // 删除 remove
   // func Remove(name string) error
   // 通过remove方法只能删除单个空文件夹:
   // remove D:\Environment\GoWorks\src\xuego\lesson11\file2: The directory is not empty.
   err3 := os.Remove("D:\\Environment\\GoWorks\\src\\xuego\\lesson11\\file2")
   if err3 != nil {
      fmt.Println(err3)
      //return
   }
   fmt.Println("file delete success!!")
   // 如果存在多层文件,removeAll,相对来说比较危险,删除这个目录下的所有东西, 强制删除
   err4 := os.RemoveAll("D:\\Environment\\GoWorks\\src\\xuego\\lesson11\\file2")
   if err4 != nil {
      fmt.Println(err4)
      return
   }
   fmt.Println("err4 delete success!!")
}

创建文件

os.create(),若存在就是的打开-就是返回的这个file对象. 如果不存在,创建在打开

package main

import (
   "fmt"
   "os"
)

func main() {
   // 创建文件  Create
   // func Create(name string) (*File, error) {
   // 返回的file对象就是我们的文件
   file1, err := os.Create("a.go") // 相对路径
   if err != nil {
      fmt.Println(err)
   }
   fmt.Println(file1)
   // 删除
   os.Remove("D:\\Environment\\GoWorks\\src\\xuego\\lesson11\\a.go")

}

IO读

1、与文件建立连接

package main

import (
   "fmt"
   "os"
)

// IO读
func main() {

   // 找到这个文件的对象 create 创建、 打开Open
   // func Open(name string) (*File, error)
   file1, err := os.Open("D:\\Environment\\GoWorks\\src\\xuego\\lesson11\\123.txt")
   if err != nil {
      fmt.Println(err)
   }
   fmt.Println(file1)
   // file 类-- 指定的对象
   // 打开文件的时候,选定权限: 可读可写的方式打开
   // OpenFile(文件名,打开方式:可读、可写...,FileMode , 权限)
   file2, err2 := os.OpenFile("D:\\Environment\\GoWorks\\src\\xuego\\lesson11\\123.txt",
      os.O_RDONLY|os.O_WRONLY, os.ModePerm)
   if err2 != nil {
      fmt.Println(err2)
   }
   fmt.Println(file2)

   // 可以操作这个对象了
   
   

}

2、读取 file.Read([]byte) ,将file中的数据读取到 []byte 中, n,err n读取到的行数,err 错误,EOF错误,就代表文件读取完毕了

一直调用read,就代表光标往后移动…

package main

import (
   "fmt"
   "os"
)

// 读取文件数据
func main() {
   // 我们习惯于在建立连接时候通过defer来关闭连接,保证程序不会出任何问题,或者忘记关闭
   // 建立连接
   file, _ := os.Open("123.txt")
   // 关闭连接
   defer file.Close()

   // 读代码 ,Go 的错误机制,让我们专心可以写业务代码。

   // 1、创建一个容器 (二进制文本文件--0100101010 => 读取流到一个容器 => 读取容器的数据)
   bs := make([]byte, 2, 1024) // 缓冲区,可以接受我们读取的数据
   // 2、读取到缓冲区中。 // 汉字一个汉字占 3个位置
   n, err := file.Read(bs)
   fmt.Println(n)
   fmt.Println(err)
   fmt.Println(string(bs)) // 读取到的字符串  ab
   // 光标不停的向下去指向,读取出来的内容就存到我们的容器中。
   file.Read(bs)
   fmt.Println(string(bs)) // 读取到的字符串  cd
   file.Read(bs)
   fmt.Println(string(bs)) // 读取到的字符串  e
   n, err = file.Read(bs)
   fmt.Println(n)
   fmt.Println(err)        // EOF ,读取到了文件末尾。就会返回EOF。
   fmt.Println(string(bs)) // 读取到的字符串
   n, err = file.Read(bs)
   fmt.Println(n)
   fmt.Println(err)
   fmt.Println(string(bs)) // 读取到的字符串

}

IO写(权限)

建立连接 (设置权限:可读可写,扩充这个文件的append) os.OpenFile

关闭连接

写入 file.write

  • file.Write
  • file.WriteString
package main

import (
   "fmt"
   "os"
)

func main() {

   fileName := "123.txt"
   // 权限:如果我们要向一个文件中追加内容, O_APPEND, 如果没有,就是从头开始写
   file, _ := os.OpenFile(fileName, os.O_WRONLY|os.O_RDONLY|os.O_APPEND, os.ModePerm)
   defer file.Close()

   // 操作
   bs := []byte{65, 66, 67, 68, 69} // A B C D E
   n, err := file.Write(bs)
   if err != nil {
      fmt.Println(err)
   }
   fmt.Println(n)

   // string类型的写入
   n, err = file.WriteString("hhahahahah哈哈哈哈哈哈哈")
   if err != nil {
      fmt.Println(err)
   }
   fmt.Println(n)
}

文件复制

package utils

import (
   "fmt"
   "io"
   "os"
)

// Copy 方法需要参数为:source 源文件 ,destination 目标文件
func Copy(source, destination string, bufferSize int) {

   // 读取文件
   sourceFile, err := os.Open(source)
   if err != nil {
      fmt.Println("Open错误:", err)
   }
   // 输出文件 O_WRONLY , O_CREATE 如果不不存在,则会创建
   destinationFile, err := os.OpenFile(destination, os.O_WRONLY|os.O_CREATE, os.ModePerm)
   if err != nil {
      fmt.Println("OpenFile错误:", err)
   }
   // 关闭
   defer sourceFile.Close()
   defer destinationFile.Close()

   // 专注业务代码,拷贝
   buf := make([]byte, bufferSize)
   // 读取
   for {
      n, err := sourceFile.Read(buf)
      if n == 0 || err == io.EOF {
         fmt.Println("读取完毕源文件,复制完毕")
         break
      } else if err != nil {
         fmt.Println("读取错误:", err)
         return // 错误之后,必须要return终止函数执行。
      }
      // 将缓冲区的东西写出到目标文件
      _, err = destinationFile.Write(buf[:n])
      if err != nil {
         fmt.Println("写出错误:", err)
      }
   }

}

调用

package main

import "xuego/lesson11/utils"

func main() {
   source := "C:\\xq.png"
   dest := "D:\\Environment\\GoWorks\\src\\xuego\\lesson11\\xq.png"

   utils.Copy(source, dest, 1024)

}

系统给我们提供了copy方法

// 调用系统的方法
func Copy2(source, destination string) {
   // 读取文件
   sourceFile, err := os.Open(source)
   if err != nil {
      fmt.Println("Open错误:", err)
   }
   // 输出文件 O_WRONLY , O_CREATE 如果不不存在,则会创建
   destinationFile, err := os.OpenFile(destination, os.O_WRONLY|os.O_CREATE, os.ModePerm)
   if err != nil {
      fmt.Println("OpenFile错误:", err)
   }
   // 关闭
   defer sourceFile.Close()
   defer destinationFile.Close()

   // 具体的实现
   written, err := io.Copy(destinationFile, sourceFile)
   fmt.Println("文件的字节大小:", written)
}

第三方包,也提供了这些方法。

Seeker接口

设置光标的位置,读写文件

type Seeker interface {
    // 1、offset 偏移量 3
    // 2、whence 如何设置,当前光标的位置。
   Seek(offset int64, whence int) (int64, error)
}
// 如何让光标在第三个位置?
// 1、找到当前光标在哪里
//  a) 文件的头部, 0
//  b) 文件的尾部  end
//  c) 在任意地方,相对位置。

const (
	SeekStart   = 0 // 表示相对于文件的开头
	SeekCurrent = 1 // 表示相对于当前光标所在的位置
	SeekEnd     = 2 // 相对于文件的末尾
)

关于seek的使用

package main

import (
   "fmt"
   "io"
   "os"
)

func main() {
   // 读取文件
   file, _ := os.OpenFile("D:\\Environment\\GoWorks\\src\\xuego\\lesson11\\a.txt",
      os.O_RDWR, os.ModePerm)
   // defer close
   defer file.Close()

   // 测试seek
   // 相对开始位置。io.SeekStart
   // 相对于文件末尾, io.SeekEnd
   file.Seek(2, io.SeekStart)
   buf := []byte{0}
   file.Read(buf)

   fmt.Println(string(buf))

   // 相对于当前位置
   file.Seek(3, io.SeekCurrent)
   file.Read(buf)

   fmt.Println(string(buf))

   // 在结尾追加内容
   file.Seek(0, io.SeekEnd)
   file.WriteString("hahahaha")
}

断点续传

思考几个问题:

1、如果你要传的文件很大,70G,是否有方法可以缩短耗时?

  • 将文件拆分
  • 同时多线程进行下载

2、如果在文件传递过程中,程序被迫中断(断电、断网、内存满了…),下次重启之后,文件是否还需要重头再传?

  • 希望能够继续上传或者下载

3、传递文件的时候,支持暂停和恢复上传?假设这个两个操作分布在重启前后?

  • 支持!

file、read、write、seek

思路:

1、需要记住上一次传递了多少数据、temp.txt => 记录

2、如果被暂停或者中断了,我们就可以读取这个temp.txt的记录,恢复上传

3、删除temp.txt
在这里插入图片描述

理解

package main

import (
   "fmt"
   "io"
   "os"
   "strconv"
)

// 断点续传
func main() {

   // 传输源文件地址
   srcFile := "C:\\Users\\遇见狂神说\\Desktop\\client\\gp.png"
   // 传输的目标位置
   destFile := "D:\\Environment\\GoWorks\\src\\xuego\\lesson11\\server\\gp-upload.png"
   // 临时记录文件
   tempFile := "D:\\Environment\\GoWorks\\src\\xuego\\lesson11\\temp.txt"

   // 创建对应的file对象,连接起来
   file1, _ := os.Open(srcFile)
   file2, _ := os.OpenFile(destFile, os.O_CREATE|os.O_RDWR, os.ModePerm)
   file3, _ := os.OpenFile(tempFile, os.O_CREATE|os.O_RDWR, os.ModePerm)
   defer file1.Close()
   defer file2.Close()
   fmt.Println("file1/2/3 文件连接建立完毕")

   // 1、读取temp.txt
   file3.Seek(0, io.SeekStart)
   buf := make([]byte, 1024, 1024)
   n, _ := file3.Read(buf)
   // 2、转换成string - 数字。
   countStr := string(buf[:n])
   count, _ := strconv.ParseInt(countStr, 10, 64)
   fmt.Println("temp.txt中记录的值为:", count) // 5120

   // 3、设置读写的偏移量
   file1.Seek(count, io.SeekStart)
   file2.Seek(count, io.SeekStart)
   fmt.Println("file1/2 光标已经移动到了目标位置")

   // 4、开始读写(复制、上传)
   bufData := make([]byte, 1024, 1024)
   // 5、需要记录读取了多少个字节
   total := int(count)

   for {
      // 读取数据
      readNum, err := file1.Read(bufData)
      if err == io.EOF { // file1 读取完毕了
         fmt.Println("文件传输完毕了")
         file3.Close()
         os.Remove(tempFile)
         break
      }
      
      // 向目标文件中写入数据
      writeNum, err := file2.Write(bufData[:readNum])
      
      // 将写入数据放到 total中, 在这里total 就是传输的进度
      total = total + writeNum
      // temp.txt 存放临时记录数据
      file3.Seek(0, io.SeekStart) // 将光标重置到开头
      file3.WriteString(strconv.Itoa(total))

   }

}

遍历文件夹

package main

import (
   "fmt"
   "log"
   "os"
)

// cd /d 文件夹路径
// tree /F , 查看当前文件夹下的所有文件

// 遍历文件夹
// 1、读取当前文件夹下的所有文件
// 2、如果是文件夹,进入文件夹,继续读取里面的所有文件
// 3、设置一些结构化代码
func main() {
   dir := "D:\\Environment\\GoWorks\\src\\xuego"
   tree(dir, 0)
}

// 日常调试测试常用fmt输出 、 工作中or项目中更多是log日志输出
func tree(dir string, level int) {
   // 编写层级
   tabString := "|--"
   for i := 0; i < level; i++ {
      tabString = "|    " + tabString
   }

   // 获取目录 ReadDir, 返回目录信息[]DirEntry,多个文件信息
   fileInfos, err := os.ReadDir(dir)
   if err != nil {
      log.Println(err)
   }

   // 遍历出来所有文件之后,获取里面的单个文件
   for _, file := range fileInfos {
      // 文件夹中文件的全路径展示
      filename := dir + "\\" + file.Name()
      fmt.Println(tabString + file.Name())
      // 如果是文件夹,再次遍历
      if file.IsDir() {
         tree(filename, level+1)
      }
   }

}

bufio

Go语言自带的IO操作包。bufio,使用这个包可以大幅提升文件的读写效率。

buf: 缓冲区.

io操作效率本身是还可以的,频繁访问本地磁盘文件(效率低)

所以说 bufio ,提供了一个缓冲区,读和写都先在缓冲区中,最后再一次性读取或者写入到文件里,降低访问本地磁盘的次数。在这里插入图片描述

bufio写入

package main

import (
   "bufio"
   "fmt"
   "log"
   "os"
)

// bufio 的应用
func main() {
   file, err := os.Open("D:\\Environment\\GoWorks\\src\\xuego\\lesson11\\demo01.go")
   if err != nil {
      log.Println(err)
   }
   defer file.Close()

   // 读取文件
   // 创建一个bufio包下的 reader对象。
   //bufioReader := bufio.NewReader(file)
   //buf := make([]byte, 1024)
   //n, err := bufioReader.Read(buf)
   //fmt.Println("读取到了多少个字节:", n)

   // 读取键盘的输入
   // 键盘的输入,实际上是流 os.Stdin
   inputReader := bufio.NewReader(os.Stdin)
   // delim 到哪里结束读取
   readString, _ := inputReader.ReadString('\n')
   fmt.Println("读取键盘输入的信息:", readString)

}

bufio写出

package main

import (
   "bufio"
   "fmt"
   "os"
)

// 写入
func main() {
   file, _ := os.OpenFile("D:\\Environment\\GoWorks\\src\\xuego\\lesson11\\a.txt",
      os.O_RDWR|os.O_CREATE,
      os.ModePerm)
   defer file.Close()

   // bufio
   fileWrite := bufio.NewWriter(file)
   writeNum, _ := fileWrite.WriteString("kuangshen")
   fmt.Println("writeNum:", writeNum)
   // 发现并没有写出到文件,是留在了缓冲区,所以我们需要调用 flush 刷新缓冲区
   // 手动刷新进文件
   fileWrite.Flush()
}

i/o差不多就这些,整理狂神笔记,可以到官网购买课程
官网连接

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

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

相关文章

(02)Unity HDRP Volume 详解

1.概述这篇文章主要针对HDRP中的Volume和Volume Post-processing进行解释&#xff0c;针对于各个组件只能进行部分参数的解释&#xff0c;具体的信息可参考官方资料&#xff0c;这里只是对官方文档的图片效果补充以及笔者自己的理解。看到这里进入正文&#xff0c;请确保你的Un…

企业IT信息化,BI 能做什么?

随着数字化相关技术、应用的发展&#xff0c;社会总体的数字化发展进入了加速阶段&#xff0c;各行各业都开始有了数字化的身影&#xff0c;在这种情况下&#xff0c;数据已经成为了越来越多企业的重要资产&#xff0c;所以如何处理数据&#xff0c;让数据从资产转化为实际的价…

【Linux】理解文件系统

文章目录理解文件系统了解磁盘结构inode理解文件系统 了解磁盘结构 磁盘是计算机中的一个 机械设备 这个磁盘的盘片就像光盘一样,数据就在盘片上放着, 但是光盘是只读的,磁盘是可读可写的 机械硬盘的寻址的工作方式: 盘片不断旋转,磁头不断摆动,定位到特定的位置 我们可以把…

代码随想录算法训练营day46 | 动态规划之背包问题 139.单词拆分

day46139.单词拆分1.确定dp数组以及下标的含义2.确定递推公式3.dp数组如何初始化4.确定遍历顺序5.举例推导dp[i]139.单词拆分 题目链接 解题思路&#xff1a;单词就是物品&#xff0c;字符串s就是背包&#xff0c;单词能否组成字符串s&#xff0c;就是问物品能不能把背包装满。…

NJ+SCU42做Modbus RTU从站

NJSCU42做Modbus RTU从站实验时间&#xff1a;2023.2.28 硬件设备&#xff1a;NJ501-1300&#xff0c;CJ1W-SCU42 软件&#xff1a;Sysmac Studio&#xff0c;Commix串口调试助手 案例简介&#xff1a;发送Modbus RTU命令读取NJ里的数据 1. 系统概述 264 ​ 本次实验使用C…

「TCG 规范解读」PC 平台相关规范(4)

可信计算组织&#xff08;Ttrusted Computing Group,TCG&#xff09;是一个非盈利的工业标准组织&#xff0c;它的宗旨是加强在相异计算机平台上的计算环境的安全性。TCG于2003年春成立&#xff0c;并采纳了由可信计算平台联盟&#xff08;the Trusted Computing Platform Alli…

3种方法找回命令提示符删除的文件

“电脑D盘有个文件没有权限删除&#xff0c;后面我使用cmd命令去强制删除&#xff0c;结果确认删除后盘中的其他文件没了&#xff0c;其中有我重要word文档&#xff0c;有什么办法恢复吗&#xff1f;求助大神&#xff01;”——来自某某小伙伴的咨询文件丢失是一个不可预测但又…

RK3288-android8-es7210-阵列麦克风

ES7210驱动包 应需求调试一个ES7210的阵列麦克风 首先移植 From 234647c69a57c32198c65836e7fc521dc22e444b Mon Sep 17 00:00:00 2001 From: LuoXiaoTan <lxt@rock-chips.com> Date: Tue, 10 Jul 2018 18:08:50 -0700 Subject: [PATCH] ASoC: codecs: add es7210 adc …

linux下多线程调试,以及一些常用工具总结(pstack/pstree/stress/perf)

一、多线程调试使用gdb查看线程信息。&#xff08;1&#xff09;获取主线程id&#xff1a;ps -aux | grep 进程名称&#xff0c;例如&#xff1a;&#xff08;2&#xff09;查看线程信息&#xff1a;gdb attach 线程id&#xff0c;例如1和3表示进程启动运行依赖的库的信息&…

2023王道考研数据结构笔记第二章线性表

第二章 线性表 2.1 线性表的定义 2.1.1 线性表的基本概念 线性表是具有相同数据类型的n(n>0)个数据元素的有限序列&#xff0c;其中n为表长&#xff0c;当n0时线性表是一个空表。若用L命名线性表&#xff0c;则其一般表示为&#xff1a; L(a1,a2,...,ai,ai1,...,an)L(a_1…

泛微e-cology9 <0.56 存在sql注入漏洞

漏洞描述 泛微e-cology9 是一个 OA 系统。 泛微e-cology9 10.56 之前版本存在 sql 注入漏洞&#xff0c;攻击者可利用该漏洞读取或修改数据库中的敏感信息&#xff0c;进而操控管理系统。 漏洞名称泛微e-cology9 <0.56 存在sql注入漏洞漏洞类型SQL注入发现时间2023/2/23漏…

论文阅读-DISTILLING KNOWLEDGE FROM READER TORETRIEVER FOR QUESTION ANSWERING

论文链接&#xff1a;https://arxiv.org/pdf/2012.04584.pdf 目录 方法 交叉注意机制 交叉注意力得分作为段落检索的相关性度量 用于段落检索的密集双编码器 将交叉注意力分数提取到双编码器 数据集 方法 我们的系统由两个模块组成&#xff0c;即检索器和阅读器&#xf…

文献阅读 Image-to-Image Translation with Conditional Adversarial Networks

前言 本文中所使用的cGAN模型为上篇论文的main idea&#xff0c;这里再进行一下相关介绍。 题目 Image-to-Image Translation with Conditional Adversarial Networks 使用条件对抗网络实现图片到图片的翻译 摘要 我们研究了条件对抗网络作为图像到图像翻译问题的通用方案。…

【C++】inline 内联函数

文章目录&#x1f4d5; 概念&#x1f4d5; 使用前的准备&#x1f4d5; 使用&#x1f4d5; 特性&#x1f4d5; 概念 在 C 中&#xff0c;为了解决一些频繁调用的小函数大量消耗栈空间&#xff08;栈内存&#xff09;的问题&#xff0c;特别的引入了 inline 修饰符&#xff0c;表…

你需要同款“Unreal项目自动化编译、打包和部署”方案吗?

在过往几期的UWA Pipeline最佳实践案例中&#xff0c;我们分享了如何通过Pipeline实现性能优化、性能管理、游戏内容验收和云真机系统的应用&#xff08;实现批量真机设备的自动化测试&#xff0c;以及针对特效性能优化的方式&#xff09;&#xff0c;其实这些高效的方法并不局…

改进 YOLO V5 的密集行人检测算法研究(论文研读)——目标检测

改进 YOLO V5 的密集行人检测算法研究&#xff08;2021.08&#xff09;摘 要&#xff1a;1 YOLO V52 SENet 通道注意力机制3 改进的 YOLO V5 模型3.1 训练数据处理改进3.2 YOLO V5 网络改进3.3 损失函数改进3.3.1 使用 CIoU3.3.2 非极大值抑制改进4 研究方案与结果分析4.1 实验…

碰撞高校智慧,凝聚青春力量 | 因“AI”而“深”-高校开源专场顺利举办!

为聚焦AI新发展&#xff0c;探寻开源新环境&#xff0c;聆听高校声音&#xff0c;2月25日上午&#xff0c;第四届OpenI/O启智开发者大会以“因AI而深”为主题在深圳人才研修院举办高校开源专场&#xff0c;共同交流高校优质开源项目的发展经验、社区优秀开发者的心路历程及高校…

ROS2功能包Hello world(python)

文章目录环境准备Python创建工作空间、功能包及节点方法编译使用环境准备 为了便于日后复现&#xff0c;相关环境已经打包到docker中。 拉取docker镜像 docker pull 1224425503/ros2_foxy_full:latest新建容器 docker run -dit --rm --privilegedtrue --network host -e NV…

cnpm adduser 报错 409 Conflict

今天遇到一个问题&#xff0c;cnpm adduser 一直失败&#xff0c;返回 409 Conflict。 我们先来看下报错信息 409 Conflict - PUT http://registry.cnpm.xxxx.com.cn/-/user/org.couchdb.user:mingyu6 - conflict第一步 分析 http 错误码 409 Conflict&#xff1a;请求与服务…

Java函数式编程

从JDK8开始java支持函数式编程&#xff0c;函数式编程是面向数学的抽象&#xff0c;将计算描述为一种表达式求值&#xff0c;函数式程序就是一个表达式。JDK也提供了几个常用的函数式接口。 java的函数式编程还没有例如js那样的规范和深奥&#xff0c; 在函数式编程中&#xf…