时值我小病在家休养生息,喜欢跳广场舞的外公来寻求我的帮助,他们跳广场舞是将存有歌曲的U盘插到音响上面,而音响大部分都是只能显示歌曲的索引index,不能直接显示歌曲名,所以为了方便他们会在U盘里面对歌曲进行排序。由于音响是寻址按顺序播放,意思就是在U盘里面的歌曲需要一首一首的按顺序复制过去,而且当对U盘歌曲进行增添的时候又需要按照顺序重新复制一遍,可以说相当麻烦。为了将我从这重复的劳动中解放出来,我用go语言写了一个小工具,本来想着分分钟写完,却没想到踩到了坑。

os包中有一个Rename()函数具有重命名和移动的功能,其函数如下:

func Rename(oldpath, newpath string) error

Rename修改一个文件的名字,移动一个文件。可能会有一些个操作系统特定的限制。

在windows系统下面使用该函数,oldpathnewpath在同一个磁盘/卷下面能正常使用,可我需要将音乐移动到U盘上,当使用这个函数的时候出现了:

The system cannot move the file to a different disk drive.

搜索Githubissues,发现Rename在windows中不能进行跨磁盘/卷操作。

为了实现跨磁盘/卷操作,一种方法是直接调用windows API,于是在windows api docs中搜索到movefileex()函数能够实现该功能,但是在go语言的syscall包中只有movefile()函数,其函数如下:

func MoveFile(from *uint16, to *uint16) (err error)

实现文件移动的函数可以写成:

func movefile(oldpath, newpath string) error { //跨卷移动
from, err := syscall.UTF16PtrFromString(oldpath)
if err != nil {
return err
}
to, err := syscall.UTF16PtrFromString(newpath)
if err != nil {
return err
}
return syscall.MoveFile(from, to)//windows API }

当我们读取oldpath目录里面的文件时调用io/ioutil包的ReadDir()函数可按照文件夹内的排序方式批量读入文件名,其函数实现如下:

func filenamelist(filepath string) []string {
var list []string
rd, err := ioutil.ReadDir(filepath) //遍历目录
if err != nil {
log.Fatal(err)
}
for _, fi := range rd {
if fi.IsDir() {
fmt.Printf("[%s]is dir\n", fi.Name()) } else {
list = append(list, fi.Name())
fmt.Println(filepath + fi.Name())
}
}
return list//返回一个string数组 }

当然也可以普通方式读入文件名然后用sort包进行排序。

下面是完整代码:

package main

import (
"fmt"
"io/ioutil"
"log"
"os"
"syscall"
) func movefile(oldpath, newpath string) error { //跨卷移动
from, err := syscall.UTF16PtrFromString(oldpath)
if err != nil {
return err
}
to, err := syscall.UTF16PtrFromString(newpath)
if err != nil {
return err
}
return syscall.MoveFile(from, to)//windows API }
func filenamelist(filepath string) []string {
var list []string
rd, err := ioutil.ReadDir(filepath) //遍历目录
if err != nil {
log.Fatal(err)
}
for _, fi := range rd {
if fi.IsDir() {
fmt.Printf("[%s]is dir\n", fi.Name()) } else {
list = append(list, fi.Name())
fmt.Println(filepath + fi.Name())
}
}
return list }
func movefilelist(oldpath, newpath string) {
for _, fi := range filenamelist(oldpath) { //移动目录的所有文件
err := movefile(oldpath+fi, newpath+fi)
if err != nil {
log.Fatal(err)
}
fmt.Println(fi + "--Move To -->" + newpath + "--OK!") }
}
func main() {
movefilelist(os.Args[1], os.Args[2])
}

最后在终端中:

Ryan@DESKTO MINGW64 /Go/test (master)
$ go run main.go ~/Desktop/music/ /d/
C:/Users/Ryan/Desktop/music/新建文本文档 (2).txt
C:/Users/Ryan/Desktop/music/新建文本文档.txt
新建文本文档 (2).txt--Move To -->D:/--OK!
新建文本文档.txt--Move To -->D:/--OK!

有了这个脚本,我今后终于可以愉快的帮助我外公了。

转载请注明

go语言 os.Rename() cannot move the file to a different disk drive 怎么办的更多相关文章

  1. python shutil 模块 的剪切文件函数 shutil.movemove(src, dst),换用 os.rename(sourceFile, targetFile)

    Google 一搜python 剪切文件,出来shutil 这模块,网上很多人也跟疯说shutil.move(src, dst)就是用来剪切文件的,结果一试,剪切毛线,文件都复制到另一个文件夹了,源文 ...

  2. 合并静态库出现 can't move temporary file错误

    静态库的制作就不说了很简单,网上也很多例子,这里主要讲下我合并通用静态库时候遇见的坑,在合并前注意.a文件一定要正确,我有一次scheme选了release但是device忘了换,结果怼着两个模拟器静 ...

  3. shutil.copy()、os.walk()、os.rename()实例

    #!/usr/bin/python # -*- coding: UTF-8 -*- import os import shutil Path = "panel/" PNPath = ...

  4. CentOS VSCode调试go语言出现:exec: "gcc": executable file not found in PATH

    CentOS VSCode调试go语言出现:exec: "gcc": executable file not found in PATH 解决方案: 执行如下命令安装GCC,然后重 ...

  5. 【翻译自mos文章】 在错误的从os级别remove掉 trace file 之后,怎么找到该trace file的内容?

    在错误的从os级别remove掉 trace file 之后,怎么找到该trace file的内容? 參考原文: How to Find the Content of Trace File Gener ...

  6. Python os.rename() 方法

    概述 os.rename() 方法用于命名文件或目录,从 src 到 dst,如果dst是一个存在的目录, 将抛出OSError.高佣联盟 www.cgewang.com 语法 rename()方法语 ...

  7. VSCode调试go语言出现:exec: "gcc": executable file not found in %PATH%

    1.问题描述 由于安装VS15 Preview 5,搞的系统由重新安装一次:在用vscdoe编译go语言时,出现以下问题: # odbcexec: "gcc": executabl ...

  8. os.rename 和os.replace

    f1 = open("hello.txt","w") f1.write("hello,my name is bobo.") f1.close ...

  9. C语言基础 (12) 文件的操作 FILE

    课程回顾 结构体基本操作: 结构体类型的定义 // struct为关键字 Stu为自定义标识符 // struct Stu才是结构体类型 // 结构体成员不能在定义类型时赋值 struct Stu { ...

随机推荐

  1. Eclipse导出可运行的jar包并运行

    https://blog.csdn.net/kpchen_0508/article/details/49275407 程序运行的第二种方式:

  2. ORA-12514

    ORA-12514: TNS:listener does not currently know of service requested in connect descriptor 监听器目前不知道在 ...

  3. iOS测试基础(命令篇)-iPhone型号及其他信息

    首先安装libimobiledevice和ideviceinstaller brew uninstall ideviceinstaller brew uninstall libimobiledevic ...

  4. 安装visual studio2017后 首次启动出现ActivityLog.xml异常解决方法

    安装visual studio2017后 首次启动出现ActivityLog.xml异常解决方法 ps:操作系统是win10 在官网下载了vs2017社区版按照教程(教程链接在文末)安装完成之后,首次 ...

  5. Salesforce平台支持多租户Multi tenant的核心设计思路

    Multitenancy is the fundamental technology that clouds use to share IT resources cost-efficiently an ...

  6. python下操作redis

    python安装这里我只介绍如何在Windows上安装redis,以及接下来的实践都是在Windows上进行的.在Windows上安装python的依赖库,常用的方法有两种,第一种是直接通过pip i ...

  7. Hadoop学习之路(二十一)MapReduce实现Reduce Join(多个文件联合查询)

    MapReduce Join 对两份数据data1和data2进行关键词连接是一个很通用的问题,如果数据量比较小,可以在内存中完成连接. 如果数据量比较大,在内存进行连接操会发生OOM.mapredu ...

  8. 2019.3.26 为什么说HTTP是无状态协议/无连接

    无状态 1.协议对于事务处理没有记忆能力 2.对同一个url请求没有上下文关系 3.每次的请求都是独立的,它的执行情况和结果与前面的请求和之后的请求时无直接关系的,它不会受前面的请求应答情况直接影响, ...

  9. CentOS7图文安装教程

    CentOS 7下载: CentOS 7只提供64位版本,虽然有不少国内镜像节点,不过还是觉得通过BT下载是不错的选择.镜像大小6.7G,联通20M光纤下载,不到小时.以下是中国大陆的下载地址列表: ...

  10. windows环境安装docker,并下载lamp镜像

    1.PC系统:windows10专业版 2.开启Hyper-V 此电脑->右击->属性->控制面板主页->(查看方式为小图标)程序和功能->右上方启动或关闭windows ...