想象一下我想创建(或覆盖)以下文件: - C:\Temp\Bar\Foo\Test.txt
使用File.Create(..)方法,这可以做到这一点.
但是,如果我没有以下任何一个文件夹(从该示例路径,上面)
然后我得到一个DirectoryNotFoundException抛出.
那么.. 给定一个路径,我们如何递归创建创建文件所需的所有文件夹..对于该路径? 如果存在Temp或Bar文件夹,但Foo不存在......那么也会创建.
为简单起见,我们假设没有安全问题 - 所有权限都很好,等等.
For a long path aware process on Windows 10, I'm trying to understand what the argument restrictions are when using the windows shell method PathRelativePathTo.
In my example below, I'm using C# via pinvoke to call the method.
I've given multiple examples below and their output. Note:
我正在创建一个文件复制程序,它将使用ROBOCOPY命令复制大小约为50 KB的大量文件(~100,000).
对于每个文件,我创建一个新进程并传递ROBOCOPY命令和参数如下:
using (Process p = new Process)
{
p.StartInfo.Arguments = string.Format("/C ROBOCOPY {0} {1} {2}",
sourceDir, destinationDir, fileName);
p.StartInfo.FileName = "CMD.EXE";
p.StartInfo.CreateNoWindow = true;
p.StartInfo.UseShellExecute = false;
p.Start();
p.WaitForExit();
}
Run Code Online (Sandbox Code Playgroud)
我正在寻找一种更好的方法,而不是为每个文件创建一个流程,这在性能和设计方面都很好.有人可以提出更好的方法吗?
背景
我需要编写一个使用.NET 2.0版本的工具(由于政治,商业和机密性/信任原因,使用现成的东西不是这个客户的选项)通过网络将文件从一个服务器迁移到另一个服务器.服务器是本地团队的文件服务器,某些团队文件夹需要迁移到其他服务器以便于重组.基本的想法是我们读取每个文件并在数小时内通过网络流式传输,几天后数据将被迁移.需要保留文件权限.由于这将花费几天时间(我们正在谈论几千兆字节的数据,对于某些团队而言),我们需要每晚迭代文件并比较修改日期并更新已更改的日期.理论上说,最终新服务器将拥有最新的文件副本,用户可以切换到新服务器.它当然不是那么简单,但我们有一个我们认为应该工作的设计:)
问题
所以理论上我们只需打开文件,通过网络流式传输,然后在另一端写入,对吧?:)
不幸的是,在服务器本身,文件共享是在文件夹路径创建的,例如:
D:\ Data\Team Shares\DIVISION\DEPARTMENT\NAME OF TEAM - 可能会长期一直
对于每个用户,此路径将映射到驱动器,例如,它将作为\\ SERVER\TEAMNAME共享并映射到T:驱动器.
这导致了从T:驱动器可见的文件在MAX_PATH限制范围内的情况,但是当在服务器本身上本地查看时,它们会超出它.我们无法使用网络共享来访问文件,因为这个工具需要是通用的,要在数百个这样的服务器上运行,并且没有标准的方法来判断哪些文件共享是我们应该移动的文件共享和那些不是 - 甚至没有命名约定标准.此外,偶尔会有其他股份的子股票,因此我们超过MAX_PATH限额两倍!
我知道使用"\\?\"前缀指定路径的解决方法,该路径将路径视为UNC路径,并允许理论上最多32k个字符.
这种解决方法是在Win32 API级别实现的,System.IO命名空间(大部分)基本上只是本机Win32 API函数的一个薄包装,但是在将调用交给API之前,Microsoft已经"帮助"实现了额外(不正确)的验证. .在这种情况下,.NET Framework拒绝该路径,因为它声称'?' 是一个无效的路径字符.
所以我的问题是......有没有一种方法我没有想到这将允许我解决这个问题,而不必完全重写几乎整个System.IO命名空间,加载P/Invoke调用,只是为了删除这个烦人的验证?
只是一个简单的问题(我希望):当我使用File.Move它给我一个错误:
System.IO.DirectoryNotFoundException was unhandled by user code
Message=Could not find a part of the path.
Source=mscorlib
StackTrace:
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.__Error.WinIOError()
at System.IO.File.Move(String sourceFileName, String destFileName)
at Portal_2_Level_Installer.Form1.WorkMagic(String FileLocation) in C:\Users\Yoshie\Local Settings\Documents\Visual Studio 2010\Projects\Portal 2 Level Installer\Portal 2 Level Installer\Form1.cs:line 265
InnerException:
Run Code Online (Sandbox Code Playgroud)
我的代码:
File.Move(FileLocation, destinationPath);
Run Code Online (Sandbox Code Playgroud)
以及变量的内容:
destinationPath="c:/program files (x86)/steam\\steamapps\\common\\portal 2\\Test\\Test.docx"
FileLocation="C:\\Users\\Yoshie\\Local Settings\\Documents\\Test.docx"
Run Code Online (Sandbox Code Playgroud)
谢谢!编辑:我现在真的觉得自己像个白痴.我没有意识到目标文件夹必须存在!我愚蠢地假设目标文件夹将自动创建,如果它尚不存在.很抱歉浪费你的时间,但谢谢你的答案!(我现在知道我可以用@来停止逃跑,所以这很好知道)无论如何,谢谢,再次,对不起!
我有一个同步软件,它从“传入”文件夹加载 CSV 文件,处理它们,然后将它们移动到“存档”文件夹。
今天,我看到这个同步软件出现以下错误:
[23/06/2014 00:06:04 AM]:无法从
D:\IBI_ORDER_IMPORTER_FTP_SERVER\Template3\Fifty & Dean\Incoming\5A040K___d6f1ca45937b4ceb98d29d0db4601bf4.csv 到
D:\IBI_ORDER_IMPORTER_FTP_SERVER\Template3\Fifty & Dean\Archive\5A040K___d6f1ca45937b4ceb98d29d0db4601bf4.csv -找不到路径的一部分。
这是从同步软件中提取的片段,文件在其中被处理和移动:
public static void ProcessSingleUserFile(Int32 TemplateId, String ImportedBy, String FilePath)
{
// Always Rename File To Avoid Conflict
string FileName = Path.GetFileNameWithoutExtension(FilePath);
String NewFilePath = FilePath.Replace(FileName, Utils.RandomString() + "___" + FileName);
File.Move(FilePath, NewFilePath);
FilePath = NewFilePath;
// Log
SyncUtils.ConsoleLog(String.Format("Processing [ {0} as {1} ] By [ {2} ] On Template [ #{3} ]",
FileName + ".csv",
Path.GetFileName(FilePath),
ImportedBy,
TemplateId));
// Init
List<OrderDraft> myOrderDrafts …Run Code Online (Sandbox Code Playgroud) 我正在处理的应用程序需要处理具有很长文件/路径名的文件.这是一个.Net 4.6应用程序,所以我实现了4.6.2之前的解决方法,以允许此处和此处概述的\\?\语法.
这是我用来启用该功能的代码(我无法修改app.config,因此必须在代码中设置):
var type = Type.GetType("System.AppContext");
if (type != null)
{
AppContext.SetSwitch("Switch.System.IO.UseLegacyPathHandling", false);
AppContext.SetSwitch("Switch.System.IO.BlockLongPaths", false);
var switchType = Type.GetType("System.AppContextSwitches");
if (switchType != null)
{
// We also have to reach into System.AppContextSwitches and manually update the cached private versions of these properties (don't ask me why):
var legacyField = switchType.GetField("_useLegacyPathHandling", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
legacyField?.SetValue(null, (Int32)(-1)); // <- caching uses 0 to indicate no value, -1 for false, 1 for true.
var blockingField = switchType.GetField("_blockLongPaths", System.Reflection.BindingFlags.Static …Run Code Online (Sandbox Code Playgroud) 我创建了一个超出字符限制的目录,并在目录前添加了“\\?\”,但我无法使用 删除它shutil.rmtree或使用 列出它os.walk。
我收到以下错误shutil.rmtree("folder"):
WindowsError: [错误 3] 系统找不到指定的路径:'folder\CAAAAAAAAAB2iMan9VH4-0fxO4JOiT43bz9XVbQUoCcdOJTk1WRcPA++\BwAAAAAAAACXEWzr-_xJujcfpbaeAa-zNMqou1c_EtOH1lGXEMaL8w++\CAAAAAAAAACq0GkU9kGYNVD caXAZ78ut8FSHTvE45Ra69qN495R6Fw++\CgAAAAAAAAAsOJ6oX-y6iRcg2F3KB4HGi6kcWnU2QPO2CEKsJUA4-g++'
我可以使用一个函数来删除该目录吗?
谢谢。
我试图在C#中使用各种文件函数File.GetLastWriteTime,复制命令放在路径上的文件大于Windows 7上的最大允许路径,即260.它给我一个长路径名错误.在MSDN支持上,他们要求使用\\?\前面的路径.我做了同样的但仍然得到了同样的错误,它似乎没有做任何改变.以下是我的代码.如果我正确使用它或者我需要添加任何东西,请告诉我:
这些我正在使用的所有lib作为代码还有其他东西:
以下是各自的代码:
filesToBeCopied = Directory.GetFiles(path,"*",SearchOption.AllDirectories);
for (int j = 0; j < filesToBeCopied.Length; j++)
{
try
{
String filepath = @"\\?\" + filesToBeCopied[j];
File.GetLastWriteTime(filepath);
}
catch (Exception ex)
{
MessageBox.Show("Error Inside the single file iteration for the path:" +
filesToBeCopied[j] + " . The exception is :" + ex.Message);
}
}
Run Code Online (Sandbox Code Playgroud)
其中path是Windows机器上以驱动器号开头的文件夹的路径.例如:d:\abc\bcd\cd\cdc\dc\..........
我已经浏览了很长时间,我找到的唯一可行方法是使用该subst方法.我希望我不必为此而烦恼.我只想将文件或目录复制/移动X到位置Y.
我可以制作一个.bat脚本或其他类型的脚本来实现这一目标.
PS:这被标记为主题,我很好,但它是在编程环境中完成的.