在UNIX环境中创建文本文件时使用编码转换(使用没有BOM编码的UTF-8)

时间:2017-05-23 08:10:38

标签: c# file encoding character-encoding filestream

我有一个方法可以将任何文件编码转换为Windows(1252)。

但是在UNIX环境中创建文件时没有转换(使用没有BOM编码的UTF-8),显然文件没有任何BOM。只有在出现这种情况时才会发生。

这是我的代码。

public static void ConvertFileEncoding(string srcFile, Encoding srcEncoding, string tempFile)
    {

          using (var reader = new StreamReader(srcFile,srcEncoding,false))
          using (var writer = new StreamWriter(System.IO.File.Open(tempFile, FileMode.Create), Encoding.GetEncoding(1252)))
            {
                char[] buf = new char[1024];

                while (true)
                {
                    int count = reader.Read(buf, 0, buf.Length);
                    if (count == 0)
                    {
                        break;
                    }
                    writer.Write(buf, 0, count);
                }
            }

            System.IO.File.Copy(tempFile, srcFile, true); // Source file is replaced with Temp file 
            DeleteTempFile(tempFile);

            // TO DO  -- Log Sucess Details
    }

任何人都可以提出更好的方法。

1 个答案:

答案 0 :(得分:1)

我认为在你的情况下你可以简单地改变......

using (var reader = new StreamReader(srcFile,srcEncoding,false))
{
    ...
}

要...

using (var reader = new StreamReader(srcFile))
{
    ...
}

不需要在StreamReader上定义编码,没有它就能很好地工作。

另一点是你的代码中存在未处理的异常;在某些情况下无用的覆盖。

前段时间我创建了一个类似的功能。我修改了一下,在这里分享它作为例子:

namespace Example
{
    using System;
    using System.IO;
    using System.Text;
    using System.Security.Cryptography;

    public static class TextEx
    {
        public static void ChangeEncoding(string srcFile, Encoding encoding)
        {
            if (srcFile == null)
                throw new ArgumentNullException(nameof(srcFile));
            if (encoding == null)
                throw new ArgumentNullException(nameof(encoding));
            if (!File.Exists(srcFile))
                throw new FileNotFoundException();

            // get the current encoding of the source file and cancel if it equals
            // with the specified encoding
            if (encoding.Equals(GetEncoding(srcFile)))
                return;

            // creates the destination file on the same location to be sure we
            // have rights to write there
            var newFile = string.Concat(srcFile, ".new");
            File.Create(newFile).Close();

            // read the source file and write to the destination file
            using (var sr = new StreamReader(srcFile))
            {
                var ca = new char[4096];
                using (var sw = new StreamWriter(newFile, true, encoding))
                {
                    int i;
                    while ((i = sr.Read(ca, 0, ca.Length)) > 0)
                        sw.Write(ca, 0, i);
                }
            }

            // generate the hashcode of the source file for comparison
            var srcHash = GetFileHash(srcFile);
            // generate the hashcode of the finished destination file and compare
            // it with the hashcode of the source file
            var newHash = GetFileHash(newFile);
            if (srcHash.Equals(newHash))
            {
                // delete the destination file if there are no changes inside
                File.Delete(newFile);
                return;
            }

            // overwrite the file if it is different
            File.Delete(srcFile);
            File.Move(newFile, srcFile);
        }

        public static Encoding GetEncoding(string file)
        {
            if (string.IsNullOrEmpty(file))
                throw new ArgumentNullException(nameof(file));
            if (!File.Exists(file))
                throw new FileNotFoundException();
            Encoding encoding;
            using (var sr = new StreamReader(file, true))
            {
                sr.Peek();
                encoding = sr.CurrentEncoding;
            }
            return encoding;
        }

        public static string GetFileHash(string file)
        {
            if (string.IsNullOrEmpty(file))
                throw new ArgumentNullException(nameof(file));
            if (!File.Exists(file))
                throw new FileNotFoundException();
            string hash;
            using (var md5 = MD5.Create())
                using (var fs = File.OpenRead(file))
                {
                    var bytes = md5.ComputeHash(fs);
                    hash = BitConverter.ToString(bytes);
                }
            return hash;
        }
    }
}

请注意,如果源文件被其他进程锁定,则会出现未处理的异常。但我认为我创建的解决方案太过分了,无法在此分享。

用法:

Example.TextEx.ChangeEncoding("C:\\example.txt", Encoding.GetEncoding(1252));