زمانی که در سی شارپ با فایل‌ها کار می‌کنیم، معمولا به این فکر هستیم که در تمامی سیستم‌عامل ها به درستی کار کنند. زیرا مسیرها در ویندوز، لینوکس و مک باهم تفاوت دارند. برای مثال در ویندوز برای جداسازی پوشه ها از "\" استفاده می‌شود، اما در لینوکس از "/" استفاده می‌شود. اگر در کدهایی که نوشته‌ایم مسیرهایی را مشخص کرده‌ایم، باید به این نکته توجه داشته باشیم که در تمامی سیستم‌عامل ها کد ما باید بدون خطا و به درستی کار کند. در این قسمت به پیاده سازی یک FileHelper میپردازیم که با توجه به سیستم عاملی که کد بر روی آن اجرا شده است؛ مسیر فایلها را درست می‌کنیم.
برای مثال اگر در ویندوز اجرا شود خروجی زیر را دریافت می‌کنیم:

.\Data\uploads\fileName.txt

و در صورتی که کد بر روی لینوکس اجرا شود خروجی زیر را دریافت کنیم:

./Data/uploads/fileName.txt

در مرحله اول شاید به این فکر کنیم که از یک متد برای دریافت جدا کننده فایل‌ها استفاده کنیم. اما راه حل بهتری که خود مایکروسافت [PathInternal.Unix.cs, PathInternal.Windows.cs و PathInternal.cs] از آن استفاده کرده است به این صورت می‌باشد.
یک پروژه از نوع Shared ایجاد کنیم و یک پوشه به اسم Helpers ایجاد میکنیم. سپس دو فایل دیگر به اسم FileHelper.Windows.cs و FileHelper.Unix.cs ایجاد میکنیم.
فایل FileHelper.Windows.cs:

public static partial class FileHelper
{
    public const char DirectorySeparator = '\\';
}

فایل FileHelper.Unix.cs:

public static partial class FileHelper
{
    public const char DirectorySeparator = '/';
}

سپس باید در فایل MultipleOsPlatform.Shared.projitems کدهای مربوط به Include کردن فایل‌های Windows و Unix را وارد نمایید. فایل MultipleOsPlatform.Shared.projitems باید به صورت زیر باشد:

<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <MSBuildAllProjects Condition="'$(MSBuildVersion)' == '' Or '$(MSBuildVersion)' &lt; '16.0'">$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
    <HasSharedItems>true</HasSharedItems>
    <SharedGUID>f42755fb-0a29-4d81-bb93-4db1e4b32d4f</SharedGUID>
  </PropertyGroup>
  <PropertyGroup Label="Configuration">
    <Import_RootNamespace>MultipleOsPlatform.Shared</Import_RootNamespace>
  </PropertyGroup>
  <ItemGroup Condition="'$(OS)' == 'Unix'">
    <Compile Include="$(MSBuildThisFileDirectory)Helpers\FileHelper.Unix.cs" />
  </ItemGroup>
  <ItemGroup Condition="'$(OS)' == 'Windows_NT'">
    <Compile Include="$(MSBuildThisFileDirectory)Helpers\FileHelper.Windows.cs">
    </Compile>
  </ItemGroup>
</Project>

در فایل MultipleOsPlatform.Shared.projitems مشخص کرده‌ایم که زمانی سیستم‌عامل Unix باشد باید فایل FileHelper.Unix.cs کامپایل شود و درصورتی که سیستم‌عامل Windows باشد فایل FileHelper.Windows.cs کامپایل شود. به این ترتیب در پراپرتی  DirectorySeparator زمانی که سیستم عامل لینوکس باشد کاراکتر "/" برگشت داده می‌شود و زمانی که سیستم‌عامل ویندوز باشد کاراکتر "\" برگشت داده می‌شود.

سپس یک برنامه از نوع ConsoleApplication ایجاد کنید و در قسمت Shared Reference پروژه‌ی Shared را به آن اضافه کنید. در ادامه اگر در پروژه ConsoleApplication کد زیر را فراخوانی کنید،

var directorySeparator = FileHelper.DirectorySeparator;

Console.WriteLine(".{0}Data{0}uploads{0}fileName", directorySeparator);

در سیستم عامل ویندوز خروجی زیر را مشاهده می‌کنید:

.\Data\uploads\fileName

و زمانی که بر روی سیستم‌عامل لینوکس اجرا شود خروجی زیر را مشاهده می‌کنید:

./Data/uploads/fileName

کدهای این مطلب را میتوانید از گیتلب دریافت نمایید.
:)

Powered by Froala Editor

نظرات

سایر نظرات
  • میثم

    این عبارت،Path.DirectorySeparatorCharجوابگو نبود؟

    ارسال شده در تاریخ دوشنبه، ۰۵ تیر ۱۴۰۲
    • admin

      با استفاده از Path.Combine و Path.DirectorySeparatorChar اصلا نیازی به پیاده سازی این کلاس ها نداریم. هدف از نوشتن این مطلب نحوه کار کردن با فایل ها در سیستم عامل های مختلف در دات نت بود.

      ارسال شده در تاریخ دوشنبه، ۰۵ تیر ۱۴۰۲