如何编写跨平台的.Net程序-秋风

起因

  开发中大多数都是Windows系统,部署有可能是Windows,也有可能是Linux系统.这个问题是发生我同事身上的,他是做Java,本以为他们写东西,跨平台的意识比较强些,后来发现不是这么回事.

  事情这样的,他在项目进行拼接图片URL的时候有换行符,所以在JavaScript使用带换行的URL是直接报错.

  最简单的方式,就是replace("\r\n",""),在Wndows系统没有问题,发布到Linux系统的时候一样报错.我突然想起Linux系统的换行符是"\n",所以让他改成这样replace("\r\n","").replace("\n","")
  
  由于Windows和Linux(及Unix)系统是有差异性,想要跨平台,就要屏蔽系统间的差异性,不管.Net还是Java都在运行虚拟机中(CLR和JVM),虚拟机屏蔽了系统的差异性,只需要在项目开发中,注意路径拼接等注意事项,尽量不调用系统函数.

进入正体,说说.Net跨平台的注意事项

  1. Linux/Unix,是区分大小写的,读取和写入文件的时候要注意的文件名的大小写.
  2. 在拼接文件路径的时候,应该用Path.DirectorySeparatorChar(提供特定平台的路径目录符).
  3. 要注意换行符,不要自己写"\r\n"或者"\n",要使用Environment.NewLine.
  4. 使用条件编译.
  5. 引入第三方dll文件,看是否对依赖特定的系统的api(wpf对Windows系统有依赖,不能跨平台)
  6. 在配置文件中的路径目录符,也是要注意的地方.最好统一使用"/",Windows系统兼容这个"/"

看代码示例

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

class Program
{
    static void Main(string[] args)
    {
        //.netcore早期需要指定编码为utf-8,不然输出的中文会乱码(新版本的.netcore不需要指定编码)
        //Console.OutputEncoding = Encoding.UTF8;

        //显示特定平台的目录符
        Console.WriteLine(@"Path.DirectorySeparatorChar={0}", Path.DirectorySeparatorChar);

        //显示换行符的ascii码值
        Console.Write(@"换行符( windows换行符\r\n(13 10) linux换行符\n(10) )ascii码=");
        byte[] array = Encoding.ASCII.GetBytes(Environment.NewLine);
        foreach (var item in array)
        {
            Console.Write(item + " ");
        }
        Console.Write(Environment.NewLine);

        //合并文件路径
        string filePath = string.Format("{0}{1}log", Directory.GetCurrentDirectory(), Path.DirectorySeparatorChar);
        Console.WriteLine("filePath={0}", filePath);

        //测试写文件(文件名为小写,统一方便跨平台使用,要避免大小写组合使用)
        Log("测试写入");
        Console.ReadKey();
    }
    static void Log(string msg)
    {
        string filePath = string.Format("{0}{1}log", Directory.GetCurrentDirectory(), Path.DirectorySeparatorChar);
        if (!Directory.Exists(filePath))
        {
            Directory.CreateDirectory(filePath);
        }
        string fileName = string.Format("{0}{1}log-{2}.txt", filePath, Path.DirectorySeparatorChar, DateTime.Now.ToString("yyyyMMdd"));
        File.AppendAllText(fileName, string.Format("{0} {1}", msg, Environment.NewLine));
    }
}

运行结果(windows mono应该是文件编码的问题)

windows系统mono运行

windows系统.netcore运行

linux系统 mono运行

总结

   前期注意跨平台的细节,虽然有些痛苦,但为了能够跨平台,这些都是值得,还有如要在Linux运行.Net程序,还需继续对Linux学习.
秋风 2016-12-28