go语言 os.Rename() cannot move the file to a different disk drive 怎么办
时值我小病在家休养生息,喜欢跳广场舞的外公来寻求我的帮助,他们跳广场舞是将存有歌曲的U盘插到音响上面,而音响大部分都是只能显示歌曲的索引index,不能直接显示歌曲名,所以为了方便他们会在U盘里面对歌曲进行排序。由于音响是寻址按顺序播放,意思就是在U盘里面的歌曲需要一首一首的按顺序复制过去,而且当对U盘歌曲进行增添的时候又需要按照顺序重新复制一遍,可以说相当麻烦。为了将我从这重复的劳动中解放出来,我用go语言写了一个小工具,本来想着分分钟写完,却没想到踩到了坑。
在os包中有一个Rename()函数具有重命名和移动的功能,其函数如下:
func Rename(oldpath, newpath string) error
Rename修改一个文件的名字,移动一个文件。可能会有一些个操作系统特定的限制。
在windows系统下面使用该函数,oldpath和newpath在同一个磁盘/卷下面能正常使用,可我需要将音乐移动到U盘上,当使用这个函数的时候出现了:
The system cannot move the file to a different disk drive.
搜索Github的issues,发现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 怎么办的更多相关文章
- python shutil 模块 的剪切文件函数 shutil.movemove(src, dst),换用 os.rename(sourceFile, targetFile)
Google 一搜python 剪切文件,出来shutil 这模块,网上很多人也跟疯说shutil.move(src, dst)就是用来剪切文件的,结果一试,剪切毛线,文件都复制到另一个文件夹了,源文 ...
- 合并静态库出现 can't move temporary file错误
静态库的制作就不说了很简单,网上也很多例子,这里主要讲下我合并通用静态库时候遇见的坑,在合并前注意.a文件一定要正确,我有一次scheme选了release但是device忘了换,结果怼着两个模拟器静 ...
- shutil.copy()、os.walk()、os.rename()实例
#!/usr/bin/python # -*- coding: UTF-8 -*- import os import shutil Path = "panel/" PNPath = ...
- CentOS VSCode调试go语言出现:exec: "gcc": executable file not found in PATH
CentOS VSCode调试go语言出现:exec: "gcc": executable file not found in PATH 解决方案: 执行如下命令安装GCC,然后重 ...
- 【翻译自mos文章】 在错误的从os级别remove掉 trace file 之后,怎么找到该trace file的内容?
在错误的从os级别remove掉 trace file 之后,怎么找到该trace file的内容? 參考原文: How to Find the Content of Trace File Gener ...
- Python os.rename() 方法
概述 os.rename() 方法用于命名文件或目录,从 src 到 dst,如果dst是一个存在的目录, 将抛出OSError.高佣联盟 www.cgewang.com 语法 rename()方法语 ...
- VSCode调试go语言出现:exec: "gcc": executable file not found in %PATH%
1.问题描述 由于安装VS15 Preview 5,搞的系统由重新安装一次:在用vscdoe编译go语言时,出现以下问题: # odbcexec: "gcc": executabl ...
- os.rename 和os.replace
f1 = open("hello.txt","w") f1.write("hello,my name is bobo.") f1.close ...
- C语言基础 (12) 文件的操作 FILE
课程回顾 结构体基本操作: 结构体类型的定义 // struct为关键字 Stu为自定义标识符 // struct Stu才是结构体类型 // 结构体成员不能在定义类型时赋值 struct Stu { ...
随机推荐
- Centos7下面安装eclipse
下载Eclipse压缩包 下载路径 http://mirrors.neusoft.edu.cn/eclipse/technology/epp/downloads/release/luna/SR2/ec ...
- C#互操作
一.引言 “为什么我们需要掌握互操作技术的呢?” 对于这个问题的解释就是——掌握了.NET平台下的互操作性技术可以帮助我们在.NET中调用非托管的dll和COM组件. ..NET 平台下提供了3种互操 ...
- BZOJ 1588 营业额统计 set
题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1588 题目大意: 营业额统计 Tiger最近被公司升任为营业部经理,他上任后接受公司交 ...
- springMVC <mvc:interceptors>拦截器的使用
首先在springMVC.xml配置如下代码 <!-- 拦截器 --> <mvc:interceptors> <bean class="com.base.Acc ...
- Java虚拟机13:Java类加载机制
前言 我们知道我们写的程序经过编译后成为了.class文件,.class文件中描述了类的各种信息,最终都需要加载到虚拟机之后才能运行和使用.而虚拟机如何加载这些.class文件?.class文件的信息 ...
- 关于Mysql查询varchar类型错误问题
因为后台所有表ID都是按照雪花算法生成的18位数字,需要对接到Android,Ios和H5,此时H5会出现字符超长溢出,所以直接把ID改为varchar类型. 如我的一张表ID为varchar(18) ...
- 浅谈Fluent Ribbon 中的SplitButton
Fluent Ribbon Control Suite 就不做介绍了,网上的例子比较多,类似Office2007及以后版本的图形界面(菜单栏).官网地址:https://github.com/flue ...
- SQL SERVER或oracl如何判断删除列
ORACLE: BEGIN EXECUTE IMMEDIATE 'DROP TABLE CUX_PO_VENDORS';EXCEPTION WHEN OTHERS THEN NULL;END ...
- 当面试官问你sql优化的时候。。。
当面试官问你有关sql优化的问题时,直接拿笔写给他: 8-select 9-distinct<column_list> 1-from left_table 3-<join_type& ...
- Gradle Goodness: Parse Files with SimpleTemplateEngine in Copy Task
With the copy task of Gradle we can copy files that are parsed by Groovy's SimpleTemplateEngine. Thi ...