我将一个Unix C应用程序移植到Windows。 这个应用程序在打开的时候重命名文件,这在Unix上是非常好的,但显然它在Windows上不起作用。 跟踪所有的重命名,以确保我closures文件,然后重新打开,再次寻求将是痛苦的。
鉴于Windows资源pipe理器允许在使用时重命名文件,我不知道为什么我不能得到这个工作。 我已经尝试在C中重命名和MoveFile ,并在C#中System.IO.File.Move。 在所有情况下,都会出现“Permission denied”错误(具体来说,GetLastError()返回的错误是“进程无法访问文件,因为正在被另一个进程使用”)
提示?
我也尝试打开文件与_sopen共享。 它也没有工作(同样的错误)。
感谢Stefan对C#代码的工作:
string orig_filename = "testrenamesharp-123456"; string dest_filename = "fancynewname.txt"; Byte[] info = new UTF8Encoding(true).GetBytes("This is to test the OpenWrite method."); var fs = new FileStream(orig_filename, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite | FileShare.Delete); fs.Write(info, 0, info.Length); File.Move(orig_filename, dest_filename); fs.Close();
工作C样本:
const char* filename = "testrename-XXXXXX"; const char* dest_filename = "fancynewname.txt"; /* The normal POSIX C functions lock the file */ /* int fd = open(filename, O_RDWR | O_CREAT, _S_IREAD | _S_IWRITE); */ /* Fails */ /* int fd = _sopen(filename, O_RDWR | O_CREAT, _SH_DENYNO, _S_IREAD | _S_IWRITE); */ /* Also fails */ /* We need to use WINAPI + _open_osfhandle to be able to use file descriptors (instead of WINAPI handles) */ HANDLE hFile = CreateFile(filename, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY, NULL ); if( INVALID_HANDLE_VALUE == hFile) { ErrorExit(TEXT("CreateFile")); } int fd = _open_osfhandle((long int)hFile, _O_CREAT | _O_RDWR | _O_TEMPORARY); if( -1 == fd ) { perror("open"); } int resw = write(fd, buf, strlen(buf)); if(-1 == resw) { perror("write"); } if( 0 == access(dest_filename, F_OK)) { perror("access"); } /* Now try to rename it - On Windows, this fails */ int resr = rename(filename, dest_filename); if( -1 == resr) { perror("rename"); } int resc = close(fd); if( -1 == resc ) { perror("close"); }
重命名要求使用FileShare.Delete共享打开有问题的文件。 如果共享标志丢失,则在打开文件时不能重命名/移动该文件。
这取决于如何打开文件。 如果文件是用锁打开的,你不能写或重命名它。 像Notepad ++这样的工具打开文件而不锁定它。 如果你是打开和编辑它的人,你也可以这样做:
http://balajiramesh.wordpress.com/2008/07/16/using-streamreader-without-locking-the-file-in-c/
文章中的代码显示了如何使用带有FileShare选项的FileStream:
using(FileStream fs = new FileStream(@”c:\test.txt”, FileMode.Open, FileAccess.Read,FileShare.ReadWrite)) { StreamReader sr = new StreamReader(fs); txtContents.Text = sr.ReadToEnd(); sr.Close(); }