在.net中传输数据的Windows与unix路径



问题是:在Windows上取一个相对文件夹结构,把它打包成一个JSON文件,然后在linux发行版上复制它,比如Ubuntu 20.04,使用。net 5。

这是我的(非常简化的)方法:

using System.IO;
using System.Collections.Generic;
using Newtonsoft.Json;
using Internal;
public class FileData
{
public string Path { get; set; }
public string FileName { get; set; }
}
public static void Main(string[] args)
{
var rootPath = Path.GetFullPath(@"C:/tempFolder");
var files = Directory.GetFiles(rootPath, "*.*", SearchOption.AllDirectories);
List<FileData> fileData = new List<FileData>();
foreach (var file in files)
{
fileData.Add(new FileData
{
FileName = Path.GetFileName(file),
Path = Path.GetRelativePath(rootPath, Path.GetDirectoryName(file))
});
}

Console.WriteLine(JsonConvert.SerializeObject(fileData));
}

现在输出类似

的内容
[
{
"Path":"InnerFolder\Subfolder",
"FileName":"TestFile.txt"
}
]

将JSON写入文件并将其传输到linux,并沿着以下行执行:

var rootPath = Path.GetFullPath("/home/user/tempFolder2/");
var fileData = JsonConvert.DeserializeObject<List<FileData>>(dataReadFromFile);
foreach(var file in fileData)
{
var path = Path.Combine(rootPath, file.Path, file.FileName);
//...proceed to create file and path
}

问题是,这里的路径返回/home/user/tempFolder2/InnerFolderSubfolder/TestFile,因为反斜杠在linux中是一个有效的路径字符,并且它不会被path . combine .

解析。我想这里有两个选项:

  1. 以某种方式强制窗口使用AltPathSeparatorChar ('/')
  2. 走穷人的路,把所有的"\"如果系统不是WinNT32,则在相对路径中出现''。

现在我非常不喜欢第二个选项,以防路径是使用linux生成的,并且反斜杠确实是反斜杠。我更希望所有的输出文件都有一个标准的"路径"格式。变量,但我不能为我的生活弄清楚,如何强制路径命名空间使用正斜杠路径,而不是反斜杠在Windows。

是否有一种方法可以使用Path api来实现这一点,或者我必须去if(OS)…路吗?

编辑:在与@Olivier Rogier进行了简短的讨论后,我决定更新这个问题,以防有人知道一个集成的解决方案。

归根结底:

var relativePath = Path.GetRelativePath("./folder", "./folder/sf1/sf2");

返回"sf1 sf2"在Windows "sf1/sf2"在Linux中。因此,如果程序员没有额外的代码,如果代码在两个不同的系统上运行,那么这行代码是不确定的。

运行像这里这样的简单示例

//WRITER
var relativePath = Path.GetRelativePath("./folder", "./folder/sf1/sf2");
File.WriteAllText("transferFile", relativePath);
//READER, on another OS
var relativePath = File.ReadAllText("transferFile");
var combinedPath = Path.Combine("./folder", relativePath);

在两个环境中不会产生相同的结果。

1: Writer: WIN, Reader: WIN写入器输出:sf1\sf2阅读器中的合并路径:文件夹\sf1\sf2Dir创建结果:文件夹-sf1-sf2
2: Writer: LNX, Reader: WIN写入输出:sf1/sf2阅读器中的合并路径:文件夹\sf1\sf2Dir创建结果:文件夹-sf1-sf2
3: Writer: WIN, Reader: LNX写入器输出:sf1\sf2阅读器中的合并路径:文件夹/sf1\sf2/Dir创建结果:文件夹-sf1\sf2

另一个例子是使用Linux目录路径

<>之前的文件夹-sf1stillavalidfoldername
Writer: LNX, Reader: WIN写入输出:sf1stillavalidfoldername阅读器中的合并路径:文件夹\sf1\stillavalidfolde\rnameDir创建结果:文件夹-sf1-stillavalidfolde-rname

到目前为止,唯一可行的解决方案是类似于

//WRITER
var relativePath = Path.GetRelativePath("./folder", "./folder/sf1/sf2");
File.WriteAllLines("transferFile", relativePath.Split(Path.DirectorySeparatorChar));
//READER, on another OS
var relativePaths = File.ReadAllLines("transferFile");
var combinedPath = Path.Combine("./folder", relativePaths);

这当然意味着要更新所有的序列化器、序列化代码等等,所以他们在任何路径被序列化的地方使用分割/连接方法,并且降低了人类的可读性。

可以期望至少对Path命名空间方法进行重载,其中可以指定目录分隔字符(强制使用Path。GetFullPath和Path。组合方法以始终使用相同的格式),一个RelativePath类,其中这是在内部处理的,或者可能是另一种我没有想到的方法。

重申一下,是否有一种方法可以提取、存储和读取字符串中的相对路径名,而不是在Windows和Linux上读取和写入,而无需将字符串路径转换为目录数组?

要独立于操作系统,我会使用路径将相对路径保存为JSON中的数组。DirectorySeparatorChar属性:

// Example: notepad.exe relative to C:
var pathParts = Path.GetRelativePath(@"C:", Path.GetDirectoryName(@"C:WindowsSystem32notepad.exe"))
.Split(Path.DirectorySeparatorChar);

与路径。组合你可以恢复你的操作系统依赖部分:

var restoredPath = Path.Combine(pathParts);

相关内容

  • 没有找到相关文章

最新更新