Атрибуты файла C# xattr
Я создаю кроссплатформенное программное обеспечение и хочу знать, есть ли какой-либо (простой) способ чтения / записи расширенных атрибутов файлов Unix (Mac OSX/Linux) в C#. Я только что прочитал о xattr
пространства имен, но я не нашел никакой информации о реализации C# или привязках этой функции.
PS Единственное, что я нашел до сих пор, это библиотека python-xattr, но я не хочу использовать ее, потому что:
- Я не хочу обязывать пользователей устанавливать Python (уже существует зависимость от Mono/.NET)
- При использовании Python у меня будет снижение производительности (C# компилируется, а Python интерпретируется)
- Я не хочу полагаться / зависеть от внешних инструментов (если это возможно), потому что это небезопасно
2 ответа
Вы должны использовать системные вызовы в Mono.Unix.Native.Syscall.*attr*
.
Сборка nuget называется https://www.nuget.org/packages/Mono.Posix.NETStandard.
Обратите внимание, что имя пары имя-значение имеет префикс пространства имен.
По словам человека 7 xattr
В настоящее время классы атрибутов безопасности, системные, доверенные и расширенные пользователем определены, как описано ниже. Дополнительные классы могут быть добавлены в будущем.
public static void Test()
{
string path = "/root/Desktop/CppSharp.txt";
// Mono.Unix.Native.Syscall.getxattr()
// Mono.Unix.Native.Syscall.fgetxattr()
// Mono.Unix.Native.Syscall.lgetxattr()
// Mono.Unix.Native.Syscall.setxattr()
// Mono.Unix.Native.Syscall.fsetxattr()
// Mono.Unix.Native.Syscall.lsetxattr
// Mono.Unix.Native.Syscall.llistxattr()
// Mono.Unix.Native.Syscall.flistxattr()
// Mono.Unix.Native.Syscall.llistxattr()
// Mono.Unix.Native.Syscall.removexattr()
// Mono.Unix.Native.Syscall.fremovexattr()
// Mono.Unix.Native.Syscall.lremovexattr()
if (System.IO.File.Exists(path))
System.Console.WriteLine("path exists");
else
System.Console.WriteLine("path doesn't exists");
System.Text.Encoding enc = new System.Text.UTF8Encoding(false);
string[] values = null;
int setXattrSucceeded = Mono.Unix.Native.Syscall.setxattr(path, "user.foobar",
enc.GetBytes("Hello World äöüÄÖÜ"), Mono.Unix.Native.XattrFlags.XATTR_CREATE);
if (setXattrSucceeded == -1)
{
Mono.Unix.Native.Errno er = Mono.Unix.Native.Stdlib.GetLastError();
string message = Mono.Unix.Native.Stdlib.strerror(er);
// https://stackru.com/questions/12662765/how-can-i-get-error-message-for-errno-value-c-language
System.Console.WriteLine(message);
} // End if (setXattrSucceeded == -1)
byte[] data = null;
long szLen = Mono.Unix.Native.Syscall.getxattr(path, "user.foobar", out data);
string value = enc.GetString(data);
System.Console.WriteLine(value);
Mono.Unix.Native.Syscall.listxattr(path, System.Text.Encoding.UTF8, out values);
System.Console.WriteLine(values);
// https://man7.org/linux/man-pages/man2/getxattr.2.html
} // End Sub TestExtendedAttributes
Я думаю, что Mono.Unix.Native.Syscall.setxattr будет лучшим решением, которое находится в модуле Mono.Posix.
Окончательное решение может быть следующим, скажите мне, что вы думаете?
FileAttrsManager - абстрактный класс, используемый для создания 2 производных классов:
- FileAttrsManagerDos: управляет расширенными атрибутами с помощью DSOFile.dll *
- FileAttrsManagerUnix: управляет расширенными атрибутами, используя IronPython* и python-xattr **
[*] http: \\ www.microsoft.com/download/en/details.aspx?displaylang=en&id=8422
[**] http: \\ ironpython.codeplex.com
[** *] http: \\ pypi.python.org/pypi/xatt
Операция с расширенными атрибутами (например, SetPropery(string key, object value)
а также GetProperty(string key)
и т.д.) будет управляться в статическом классе (FileAttrsProvider), который инициализирует объект FileAttrsManager одним из двух производных типов, а именно:
public static class FileAttrProvider
{
private static FileAttrReader _reader = null;
public static void Initialize()
{
switch (Environment.OSVersion.Platform)
{
case PlatformID.MacOSX:
goto case PlatformID.Unix;
case PlatformID.Unix:
_reader = new FileAttrReaderUnix();
break;
case PlatformID.Win32NT:
_reader = new FileAttrReaderDos();
break;
}
}
}
Хотя производный тип зависит от среды, исходный тип используется для обеспечения автоматической отправки всех вызовов методов объекта _reader).