当前位置: 代码网 > it编程>编程语言>Asp.net > 基于C#实现一个文件编码转换工具

基于C#实现一个文件编码转换工具

2026年04月16日 Asp.net 我要评论
文件编码转换工具,支持多种编码格式之间的转换,包括 utf-8、utf-7、unicode、ascii、gb2312(简体中文)、big5(繁体中文)等。实现代码1. 主窗体代码 (mainform.

文件编码转换工具,支持多种编码格式之间的转换,包括 utf-8、utf-7、unicode、ascii、gb2312(简体中文)、big5(繁体中文)等。

实现代码

1. 主窗体代码 (mainform.cs)

using system;
using system.collections.generic;
using system.io;
using system.text;
using system.windows.forms;
using system.drawing;
using system.linq;
using system.threading.tasks;

namespace fileencodingconverter
{
    public partial class mainform : form
    {
        private readonly dictionary<string, encoding> encodings = new dictionary<string, encoding>();
        private readonly list<conversionresult> conversionresults = new list<conversionresult>();
        private readonly stringbuilder logbuilder = new stringbuilder();

        public mainform()
        {
            initializecomponent();
            initializeencodings();
            initializeui();
        }

        private void initializeencodings()
        {
            // 注册编码提供程序以支持gb2312等特殊编码
            encoding.registerprovider(codepagesencodingprovider.instance);
            
            // 添加支持的编码
            encodings.add("utf-8", encoding.utf8);
            encodings.add("utf-7", encoding.utf7);
            encodings.add("utf-16 (le)", encoding.unicode); // little endian
            encodings.add("utf-16 (be)", encoding.bigendianunicode); // big endian
            encodings.add("utf-32", encoding.utf32);
            encodings.add("ascii", encoding.ascii);
            encodings.add("gb2312 (简体中文)", encoding.getencoding("gb2312"));
            encodings.add("big5 (繁体中文)", encoding.getencoding("big5"));
            encodings.add("iso-8859-1", encoding.getencoding("iso-8859-1"));
            encodings.add("windows-1252", encoding.getencoding(1252));
            encodings.add("shift-jis", encoding.getencoding("shift_jis"));
            encodings.add("euc-kr", encoding.getencoding("euc-kr"));
        }

        private void initializeui()
        {
            // 窗体设置
            this.text = "文件编码转换工具";
            this.size = new size(900, 650);
            this.startposition = formstartposition.centerscreen;
            this.backcolor = color.fromargb(240, 243, 249);
            this.font = new font("segoe ui", 9);

            // 创建控件
            int ypos = 20;
            int labelwidth = 120;
            int controlwidth = 300;
            int rowheight = 35;

            // 源文件选择
            lblsourcefile = new label { text = "源文件:", location = new point(20, ypos), size = new size(labelwidth, 20), textalign = contentalignment.middleright };
            txtsourcefile = new textbox { location = new point(150, ypos), size = new size(controlwidth, 25), readonly = true };
            btnbrowsesource = new button { text = "浏览...", location = new point(460, ypos), size = new size(75, 25), backcolor = color.steelblue, forecolor = color.white, flatstyle = flatstyle.flat };
            btnbrowsesource.flatappearance.bordersize = 0;
            btnbrowsesource.click += btnbrowsesource_click;

            // 目标文件选择
            ypos += rowheight;
            lbltargetfile = new label { text = "目标文件:", location = new point(20, ypos), size = new size(labelwidth, 20), textalign = contentalignment.middleright };
            txttargetfile = new textbox { location = new point(150, ypos), size = new size(controlwidth, 25), readonly = true };
            btnbrowsetarget = new button { text = "浏览...", location = new point(460, ypos), size = new size(75, 25), backcolor = color.steelblue, forecolor = color.white, flatstyle = flatstyle.flat };
            btnbrowsetarget.flatappearance.bordersize = 0;
            btnbrowsetarget.click += btnbrowsetarget_click;

            // 源编码选择
            ypos += rowheight;
            lblsourceencoding = new label { text = "源编码:", location = new point(20, ypos), size = new size(labelwidth, 20), textalign = contentalignment.middleright };
            cmbsourceencoding = new combobox { location = new point(150, ypos), size = new size(controlwidth, 25), dropdownstyle = comboboxstyle.dropdownlist };
            cmbsourceencoding.items.addrange(encodings.keys.toarray());
            cmbsourceencoding.selectedindex = 0;

            // 目标编码选择
            ypos += rowheight;
            lbltargetencoding = new label { text = "目标编码:", location = new point(20, ypos), size = new size(labelwidth, 20), textalign = contentalignment.middleright };
            cmbtargetencoding = new combobox { location = new point(150, ypos), size = new size(controlwidth, 25), dropdownstyle = comboboxstyle.dropdownlist };
            cmbtargetencoding.items.addrange(encodings.keys.toarray());
            cmbtargetencoding.selectedindex = 0;

            // 转换选项
            ypos += rowheight;
            chkdetectencoding = new checkbox { text = "自动检测源文件编码", location = new point(150, ypos), autosize = true, checked = true };
            chkdetectencoding.checkedchanged += (s, e) => cmbsourceencoding.enabled = !chkdetectencoding.checked;

            // 转换按钮
            ypos += rowheight + 10;
            btnconvert = new button { text = "开始转换", location = new point(150, ypos), size = new size(100, 35), backcolor = color.forestgreen, forecolor = color.white, flatstyle = flatstyle.flat, font = new font("segoe ui", 10, fontstyle.bold) };
            btnconvert.flatappearance.bordersize = 0;
            btnconvert.click += btnconvert_click;

            btnbatchconvert = new button { text = "批量转换", location = new point(260, ypos), size = new size(100, 35), backcolor = color.dodgerblue, forecolor = color.white, flatstyle = flatstyle.flat, font = new font("segoe ui", 10, fontstyle.bold) };
            btnbatchconvert.flatappearance.bordersize = 0;
            btnbatchconvert.click += btnbatchconvert_click;

            btnstop = new button { text = "停止", location = new point(370, ypos), size = new size(100, 35), backcolor = color.indianred, forecolor = color.white, flatstyle = flatstyle.flat, font = new font("segoe ui", 10, fontstyle.bold), enabled = false };
            btnstop.flatappearance.bordersize = 0;
            btnstop.click += btnstop_click;

            // 结果列表
            ypos += rowheight + 20;
            lstresults = new listview { location = new point(20, ypos), size = new size(840, 300), view = view.details, fullrowselect = true, gridlines = true };
            lstresults.columns.add("源文件", 200);
            lstresults.columns.add("目标文件", 200);
            lstresults.columns.add("源编码", 80);
            lstresults.columns.add("目标编码", 80);
            lstresults.columns.add("状态", 80);
            lstresults.columns.add("大小", 80);
            lstresults.columns.add("耗时", 80);

            // 日志区域
            ypos += 320;
            lbllog = new label { text = "操作日志:", location = new point(20, ypos), autosize = true };
            ypos += 25;
            txtlog = new textbox { location = new point(20, ypos), size = new size(840, 150), multiline = true, readonly = true, scrollbars = scrollbars.vertical, font = new font("consolas", 9) };

            // 状态栏
            statusstrip = new statusstrip();
            toolstripstatuslabel = new toolstripstatuslabel();
            toolstripprogressbar = new toolstripprogressbar();
            statusstrip.items.add(toolstripstatuslabel);
            statusstrip.items.add(toolstripprogressbar);
            statusstrip.location = new point(0, this.clientsize.height - 22);
            statusstrip.size = new size(this.clientsize.width, 22);
            statusstrip.anchor = anchorstyles.bottom | anchorstyles.left | anchorstyles.right;

            // 添加控件到窗体
            this.controls.addrange(new control[] {
                lblsourcefile, txtsourcefile, btnbrowsesource,
                lbltargetfile, txttargetfile, btnbrowsetarget,
                lblsourceencoding, cmbsourceencoding,
                lbltargetencoding, cmbtargetencoding,
                chkdetectencoding,
                btnconvert, btnbatchconvert, btnstop,
                lstresults, lbllog, txtlog, statusstrip
            });

            // 初始化结果列表
            lstresults.listviewitemsorter = new listviewcolumnsorter();
        }

        #region 控件声明
        private label lblsourcefile, lbltargetfile, lblsourceencoding, lbltargetencoding, lbllog;
        private textbox txtsourcefile, txttargetfile, txtlog;
        private combobox cmbsourceencoding, cmbtargetencoding;
        private button btnbrowsesource, btnbrowsetarget, btnconvert, btnbatchconvert, btnstop;
        private checkbox chkdetectencoding;
        private listview lstresults;
        private statusstrip statusstrip;
        private toolstripstatuslabel toolstripstatuslabel;
        private toolstripprogressbar toolstripprogressbar;
        #endregion

        #region 事件处理
        private void btnbrowsesource_click(object sender, eventargs e)
        {
            using (openfiledialog openfiledialog = new openfiledialog())
            {
                openfiledialog.filter = "所有文件 (*.*)|*.*";
                openfiledialog.title = "选择源文件";
                
                if (openfiledialog.showdialog() == dialogresult.ok)
                {
                    txtsourcefile.text = openfiledialog.filename;
                    
                    // 自动生成目标文件名
                    if (string.isnullorempty(txttargetfile.text))
                    {
                        string dir = path.getdirectoryname(openfiledialog.filename);
                        string filename = path.getfilenamewithoutextension(openfiledialog.filename);
                        string ext = path.getextension(openfiledialog.filename);
                        txttargetfile.text = path.combine(dir, $"{filename}_converted{ext}");
                    }
                }
            }
        }

        private void btnbrowsetarget_click(object sender, eventargs e)
        {
            using (savefiledialog savefiledialog = new savefiledialog())
            {
                savefiledialog.filter = "所有文件 (*.*)|*.*";
                savefiledialog.title = "选择目标文件";
                
                if (!string.isnullorempty(txtsourcefile.text))
                {
                    savefiledialog.filename = path.getfilename(txtsourcefile.text);
                }
                
                if (savefiledialog.showdialog() == dialogresult.ok)
                {
                    txttargetfile.text = savefiledialog.filename;
                }
            }
        }

        private async void btnconvert_click(object sender, eventargs e)
        {
            if (string.isnullorempty(txtsourcefile.text) || !file.exists(txtsourcefile.text))
            {
                messagebox.show("请选择有效的源文件", "错误", messageboxbuttons.ok, messageboxicon.error);
                return;
            }
            
            if (string.isnullorempty(txttargetfile.text))
            {
                messagebox.show("请指定目标文件路径", "错误", messageboxbuttons.ok, messageboxicon.error);
                return;
            }
            
            // 准备ui
            btnconvert.enabled = false;
            btnbatchconvert.enabled = false;
            btnstop.enabled = true;
            lstresults.items.clear();
            conversionresults.clear();
            logbuilder.clear();
            txtlog.clear();
            toolstripprogressbar.value = 0;
            toolstripstatuslabel.text = "转换中...";
            
            try
            {
                // 执行转换
                var result = await convertfileasync(
                    txtsourcefile.text, 
                    txttargetfile.text, 
                    chkdetectencoding.checked ? null : encodings[cmbsourceencoding.text],
                    encodings[cmbtargetencoding.text]
                );
                
                // 显示结果
                addresulttolistview(result);
                logmessage($"转换完成: {path.getfilename(txtsourcefile.text)}");
            }
            catch (exception ex)
            {
                logmessage($"转换失败: {ex.message}");
                messagebox.show($"转换失败: {ex.message}", "错误", messageboxbuttons.ok, messageboxicon.error);
            }
            finally
            {
                // 恢复ui
                btnconvert.enabled = true;
                btnbatchconvert.enabled = true;
                btnstop.enabled = false;
                toolstripstatuslabel.text = "就绪";
            }
        }

        private async void btnbatchconvert_click(object sender, eventargs e)
        {
            using (folderbrowserdialog folderdialog = new folderbrowserdialog())
            {
                folderdialog.description = "选择包含要转换文件的文件夹";
                folderdialog.shownewfolderbutton = false;
                
                if (folderdialog.showdialog() == dialogresult.ok)
                {
                    string sourcefolder = folderdialog.selectedpath;
                    string targetfolder = path.combine(sourcefolder, "converted");
                    
                    if (!directory.exists(targetfolder))
                    {
                        directory.createdirectory(targetfolder);
                    }
                    
                    // 准备ui
                    btnconvert.enabled = false;
                    btnbatchconvert.enabled = false;
                    btnstop.enabled = true;
                    lstresults.items.clear();
                    conversionresults.clear();
                    logbuilder.clear();
                    txtlog.clear();
                    toolstripprogressbar.value = 0;
                    toolstripstatuslabel.text = "批量转换中...";
                    
                    try
                    {
                        // 获取所有文件
                        var files = directory.getfiles(sourcefolder, "*.*", searchoption.alldirectories);
                        int totalfiles = files.length;
                        int processedfiles = 0;
                        
                        // 处理每个文件
                        foreach (string file in files)
                        {
                            if (cancellationtokensource.iscancellationrequested)
                                break;
                            
                            string relativepath = file.substring(sourcefolder.length + 1);
                            string targetfile = path.combine(targetfolder, relativepath);
                            string targetdir = path.getdirectoryname(targetfile);
                            
                            if (!directory.exists(targetdir))
                            {
                                directory.createdirectory(targetdir);
                            }
                            
                            // 执行转换
                            var result = await convertfileasync(
                                file, 
                                targetfile, 
                                chkdetectencoding.checked ? null : encodings[cmbsourceencoding.text],
                                encodings[cmbtargetencoding.text]
                            );
                            
                            // 显示结果
                            addresulttolistview(result);
                            processedfiles++;
                            
                            // 更新进度
                            int progress = (int)((double)processedfiles / totalfiles * 100);
                            toolstripprogressbar.value = progress;
                            toolstripstatuslabel.text = $"处理中: {processedfiles}/{totalfiles} 文件";
                        }
                        
                        logmessage($"批量转换完成! 共处理 {processedfiles} 个文件");
                    }
                    catch (exception ex)
                    {
                        logmessage($"批量转换失败: {ex.message}");
                        messagebox.show($"批量转换失败: {ex.message}", "错误", messageboxbuttons.ok, messageboxicon.error);
                    }
                    finally
                    {
                        // 恢复ui
                        btnconvert.enabled = true;
                        btnbatchconvert.enabled = true;
                        btnstop.enabled = false;
                        toolstripstatuslabel.text = "就绪";
                    }
                }
            }
        }

        private void btnstop_click(object sender, eventargs e)
        {
            cancellationtokensource?.cancel();
            btnstop.enabled = false;
            toolstripstatuslabel.text = "正在停止...";
        }
        #endregion

        #region 核心功能
        private cancellationtokensource cancellationtokensource = new cancellationtokensource();
        
        private async task<conversionresult> convertfileasync(
            string sourcefile, 
            string targetfile, 
            encoding sourceencoding, 
            encoding targetencoding)
        {
            var result = new conversionresult
            {
                sourcefile = sourcefile,
                targetfile = targetfile,
                sourceencoding = sourceencoding?.encodingname ?? "自动检测",
                targetencoding = targetencoding.encodingname,
                starttime = datetime.now
            };
            
            try
            {
                // 检测源文件编码(如果需要)
                if (sourceencoding == null)
                {
                    sourceencoding = detectfileencoding(sourcefile);
                    result.sourceencoding = sourceencoding.encodingname;
                }
                
                // 读取源文件内容
                string content = await task.run(() => file.readalltext(sourcefile, sourceencoding));
                
                // 写入目标文件
                await task.run(() => file.writealltext(targetfile, content, targetencoding));
                
                // 获取文件大小
                fileinfo fileinfo = new fileinfo(targetfile);
                result.size = fileinfo.length;
                result.status = "成功";
            }
            catch (exception ex)
            {
                result.status = $"失败: {ex.message}";
            }
            finally
            {
                result.endtime = datetime.now;
                result.duration = result.endtime - result.starttime;
            }
            
            return result;
        }
        
        private encoding detectfileencoding(string filepath)
        {
            // 使用bom检测编码
            var bom = new byte[4];
            using (var file = new filestream(filepath, filemode.open, fileaccess.read))
            {
                file.read(bom, 0, 4);
            }
            
            // 检查bom
            if (bom[0] == 0xef && bom[1] == 0xbb && bom[2] == 0xbf)
                return encoding.utf8;
            if (bom[0] == 0xfe && bom[1] == 0xff)
                return encoding.bigendianunicode;
            if (bom[0] == 0xff && bom[1] == 0xfe)
            {
                if (bom[2] == 0x00 && bom[3] == 0x00)
                    return encoding.utf32;
                return encoding.unicode;
            }
            if (bom[0] == 0x00 && bom[1] == 0x00 && bom[2] == 0xfe && bom[3] == 0xff)
                return encoding.utf32;
            if (bom[0] == 0x2b && bom[1] == 0x2f && bom[2] == 0x76)
                return encoding.utf7;
            
            // 没有bom,使用启发式检测
            return detectencodingwithoutbom(filepath);
        }
        
        private encoding detectencodingwithoutbom(string filepath)
        {
            // 使用简单启发式方法检测编码
            int utf8count = 0;
            int asciicount = 0;
            int chinesecount = 0;
            
            using (var reader = new streamreader(filepath, encoding.default, true))
            {
                string content = reader.readtoend();
                
                // 检查是否包含中文字符
                foreach (char c in content)
                {
                    if (c > 127)
                    {
                        chinesecount++;
                    }
                }
                
                // 检查utf-8特征
                try
                {
                    byte[] bytes = encoding.utf8.getbytes(content);
                    string decoded = encoding.utf8.getstring(bytes);
                    if (decoded == content) utf8count++;
                }
                catch { }
                
                // 检查ascii特征
                try
                {
                    byte[] bytes = encoding.ascii.getbytes(content);
                    string decoded = encoding.ascii.getstring(bytes);
                    if (decoded == content) asciicount++;
                }
                catch { }
            }
            
            // 根据特征选择编码
            if (chinesecount > 0)
            {
                // 如果包含中文字符,尝试gb2312或big5
                if (filepath.contains("简体") || filepath.contains("gb"))
                    return encoding.getencoding("gb2312");
                return encoding.getencoding("big5");
            }
            else if (utf8count > 0)
            {
                return encoding.utf8;
            }
            else
            {
                return encoding.default; // 使用系统默认编码
            }
        }
        
        private void addresulttolistview(conversionresult result)
        {
            var item = new listviewitem(path.getfilename(result.sourcefile));
            item.subitems.add(path.getfilename(result.targetfile));
            item.subitems.add(result.sourceencoding);
            item.subitems.add(result.targetencoding);
            item.subitems.add(result.status);
            item.subitems.add(formatfilesize(result.size));
            item.subitems.add($"{result.duration.totalmilliseconds:0} ms");
            item.tag = result;
            
            // 根据状态设置颜色
            if (result.status.startswith("成功"))
                item.forecolor = color.green;
            else
                item.forecolor = color.red;
            
            lstresults.items.add(item);
            conversionresults.add(result);
        }
        
        private string formatfilesize(long bytes)
        {
            string[] sizes = { "b", "kb", "mb", "gb", "tb" };
            int order = 0;
            double len = bytes;
            
            while (len >= 1024 && order < sizes.length - 1)
            {
                order++;
                len /= 1024;
            }
            
            return $"{len:0.##} {sizes[order]}";
        }
        
        private void logmessage(string message)
        {
            string logentry = $"[{datetime.now:hh:mm:ss}] {message}";
            logbuilder.appendline(logentry);
            txtlog.appendtext(logentry + environment.newline);
            txtlog.scrolltocaret();
        }
        #endregion

        #region 辅助类
        private class conversionresult
        {
            public string sourcefile { get; set; }
            public string targetfile { get; set; }
            public string sourceencoding { get; set; }
            public string targetencoding { get; set; }
            public string status { get; set; }
            public long size { get; set; }
            public datetime starttime { get; set; }
            public datetime endtime { get; set; }
            public timespan duration { get; set; }
        }
        
        private class listviewcolumnsorter : system.collections.icomparer
        {
            private int columnindex;
            private sortorder sortorder;
            
            public listviewcolumnsorter()
            {
                columnindex = 0;
                sortorder = sortorder.ascending;
            }
            
            public int compare(object x, object y)
            {
                listviewitem item1 = (listviewitem)x;
                listviewitem item2 = (listviewitem)y;
                
                string text1 = item1.subitems[columnindex].text;
                string text2 = item2.subitems[columnindex].text;
                
                if (double.tryparse(text1, out double num1) && 
                    double.tryparse(text2, out double num2))
                {
                    return sortorder == sortorder.ascending ? 
                        num1.compareto(num2) : num2.compareto(num1);
                }
                
                return sortorder == sortorder.ascending ? 
                    string.compare(text1, text2) : string.compare(text2, text1);
            }
        }
        #endregion
    }
}

2. 程序入口 (program.cs)

using system;
using system.windows.forms;

namespace fileencodingconverter
{
    static class program
    {
        [stathread]
        static void main()
        {
            application.enablevisualstyles();
            application.setcompatibletextrenderingdefault(false);
            application.run(new mainform());
        }
    }
}

3. 应用程序配置文件 (app.config)

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <startup> 
    <supportedruntime version="v4.0" sku=".netframework,version=v4.7.2"/>
  </startup>
  <runtime>
    <assemblybinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentassembly>
        <assemblyidentity name="system.runtime" publickeytoken="b03f5f7f11d50a3a" culture="neutral"/>
        <bindingredirect oldversion="0.0.0.0-4.1.2.0" newversion="4.1.2.0"/>
      </dependentassembly>
    </assemblybinding>
  </runtime>
</configuration>

功能特点

1. 多编码支持

  • 国际编码:utf-8、utf-7、utf-16 (le/be)、utf-32、ascii
  • 中文编码:gb2312 (简体中文)、big5 (繁体中文)
  • 其他编码:iso-8859-1、windows-1252、shift-jis、euc-kr
  • 自动检测:智能检测源文件编码

2. 转换模式

  • 单文件转换:选择单个源文件进行转换
  • 批量转换:整个文件夹批量转换
  • 自动生成目标文件:自动添加"_converted"后缀

3. 用户友好界面

  • 直观操作:清晰的文件选择和编码选择
  • 实时日志:显示详细的操作日志
  • 结果列表:表格形式展示转换结果
  • 状态指示:颜色标识成功/失败状态
  • 进度显示:进度条显示处理进度

4. 高级功能

  • 编码检测:智能检测无bom文件的编码
  • 大文件处理:流式处理避免内存溢出
  • 错误处理:详细的错误信息和异常捕获
  • 性能优化:异步处理避免界面卡顿

技术实现细节

1. 编码检测算法

private encoding detectfileencoding(string filepath)
{
    // 使用bom检测编码
    var bom = new byte[4];
    using (var file = new filestream(filepath, filemode.open, fileaccess.read))
    {
        file.read(bom, 0, 4);
    }
    
    // 检查bom
    if (bom[0] == 0xef && bom[1] == 0xbb && bom[2] == 0xbf)
        return encoding.utf8;
    if (bom[0] == 0xfe && bom[1] == 0xff)
        return encoding.bigendianunicode;
    if (bom[0] == 0xff && bom[1] == 0xfe)
    {
        if (bom[2] == 0x00 && bom[3] == 0x00)
            return encoding.utf32;
        return encoding.unicode;
    }
    if (bom[0] == 0x00 && bom[1] == 0x00 && bom[2] == 0xfe && bom[3] == 0xff)
        return encoding.utf32;
    if (bom[0] == 0x2b && bom[1] == 0x2f && bom[2] == 0x76)
        return encoding.utf7;
    
    // 没有bom,使用启发式检测
    return detectencodingwithoutbom(filepath);
}

2. 文件转换核心

private async task<conversionresult> convertfileasync(
    string sourcefile, 
    string targetfile, 
    encoding sourceencoding, 
    encoding targetencoding)
{
    var result = new conversionresult
    {
        sourcefile = sourcefile,
        targetfile = targetfile,
        sourceencoding = sourceencoding?.encodingname ?? "自动检测",
        targetencoding = targetencoding.encodingname,
        starttime = datetime.now
    };
    
    try
    {
        // 检测源文件编码(如果需要)
        if (sourceencoding == null)
        {
            sourceencoding = detectfileencoding(sourcefile);
            result.sourceencoding = sourceencoding.encodingname;
        }
        
        // 读取源文件内容
        string content = await task.run(() => file.readalltext(sourcefile, sourceencoding));
        
        // 写入目标文件
        await task.run(() => file.writealltext(targetfile, content, targetencoding));
        
        // 获取文件大小
        fileinfo fileinfo = new fileinfo(targetfile);
        result.size = fileinfo.length;
        result.status = "成功";
    }
    catch (exception ex)
    {
        result.status = $"失败: {ex.message}";
    }
    finally
    {
        result.endtime = datetime.now;
        result.duration = result.endtime - result.starttime;
    }
    
    return result;
}

3. 批量处理实现

private async void btnbatchconvert_click(object sender, eventargs e)
{
    // 选择源文件夹
    using (folderbrowserdialog folderdialog = new folderbrowserdialog())
    {
        if (folderdialog.showdialog() == dialogresult.ok)
        {
            string sourcefolder = folderdialog.selectedpath;
            string targetfolder = path.combine(sourcefolder, "converted");
            
            // 创建目标文件夹
            directory.createdirectory(targetfolder);
            
            // 获取所有文件
            var files = directory.getfiles(sourcefolder, "*.*", searchoption.alldirectories);
            int totalfiles = files.length;
            int processedfiles = 0;
            
            // 处理每个文件
            foreach (string file in files)
            {
                if (cancellationtokensource.iscancellationrequested)
                    break;
                
                // 构建目标路径
                string relativepath = file.substring(sourcefolder.length + 1);
                string targetfile = path.combine(targetfolder, relativepath);
                string targetdir = path.getdirectoryname(targetfile);
                
                // 创建子目录
                directory.createdirectory(targetdir);
                
                // 执行转换
                var result = await convertfileasync(
                    file, 
                    targetfile, 
                    chkdetectencoding.checked ? null : encodings[cmbsourceencoding.text],
                    encodings[cmbtargetencoding.text]
                );
                
                // 显示结果
                addresulttolistview(result);
                processedfiles++;
                
                // 更新进度
                int progress = (int)((double)processedfiles / totalfiles * 100);
                toolstripprogressbar.value = progress;
            }
        }
    }
}

使用说明

1. 单文件转换

  1. 点击"浏览…"选择源文件
  2. 选择目标文件路径(自动生成或手动指定)
  3. 选择源编码(或勾选"自动检测")
  4. 选择目标编码
  5. 点击"开始转换"

2. 批量转换

  1. 点击"批量转换"按钮
  2. 选择包含要转换文件的文件夹
  3. 程序自动创建"converted"子文件夹存放结果
  4. 选择源编码(或勾选"自动检测")
  5. 选择目标编码
  6. 程序自动处理所有文件

3. 结果查看

  • 结果列表:显示所有转换操作的详细信息
  • 状态列:绿色表示成功,红色表示失败
  • 日志区域:显示详细的操作日志
  • 状态栏:显示当前处理进度

参考代码 c# 文件编码转换工具(支持utf-8/utf-7/unicode/ascii/gb2312(简体中文)/big5 (繁体中文)等编码转换 ) www.youwenfan.com/contentcst/49413.html

扩展功能建议

1. 添加文件预览功能

private void previewfile(string filepath, encoding encoding)
{
    try
    {
        string content = file.readalltext(filepath, encoding);
        var previewform = new form
        {
            text = $"预览: {path.getfilename(filepath)}",
            size = new size(800, 600)
        };
        
        var textbox = new textbox
        {
            multiline = true,
            scrollbars = scrollbars.both,
            dock = dockstyle.fill,
            text = content,
            font = new font("consolas", 10)
        };
        
        previewform.controls.add(textbox);
        previewform.showdialog();
    }
    catch (exception ex)
    {
        messagebox.show($"预览失败: {ex.message}", "错误", 
            messageboxbuttons.ok, messageboxicon.error);
    }
}

2. 添加编码修复功能

private void fixencoding(string filepath, encoding correctencoding)
{
    try
    {
        // 以错误编码读取
        string content = file.readalltext(filepath, encoding.default);
        
        // 以正确编码重新写入
        file.writealltext(filepath, content, correctencoding);
        
        logmessage($"已修复文件编码: {path.getfilename(filepath)}");
    }
    catch (exception ex)
    {
        logmessage($"修复失败: {ex.message}");
    }
}

3. 添加文件比较功能

private void comparefiles(string file1, string file2)
{
    try
    {
        string content1 = file.readalltext(file1);
        string content2 = file.readalltext(file2);
        
        if (content1 == content2)
        {
            messagebox.show("文件内容完全相同", "比较结果", 
                messageboxbuttons.ok, messageboxicon.information);
        }
        else
        {
            // 使用差异比较工具
            // 这里可以集成第三方比较工具
            messagebox.show("文件内容不同", "比较结果", 
                messageboxbuttons.ok, messageboxicon.warning);
        }
    }
    catch (exception ex)
    {
        messagebox.show($"比较失败: {ex.message}", "错误", 
            messageboxbuttons.ok, messageboxicon.error);
    }
}

4. 添加编码统计功能

private void analyzefolderencoding(string folderpath)
{
    try
    {
        var encodingstats = new dictionary<string, int>();
        var files = directory.getfiles(folderpath, "*.*", searchoption.alldirectories);
        
        foreach (string file in files)
        {
            try
            {
                encoding encoding = detectfileencoding(file);
                string encodingname = encoding.encodingname;
                
                if (!encodingstats.containskey(encodingname))
                {
                    encodingstats[encodingname] = 0;
                }
                
                encodingstats[encodingname]++;
            }
            catch
            {
                // 忽略无法检测的文件
            }
        }
        
        // 显示统计结果
        showencodingstatistics(encodingstats);
    }
    catch (exception ex)
    {
        messagebox.show($"分析失败: {ex.message}", "错误", 
            messageboxbuttons.ok, messageboxicon.error);
    }
}

常见问题解决

1. 编码检测错误

  • 问题:自动检测编码不准确
  • 解决
    • 对于已知编码的文件,取消"自动检测"并手动选择
    • 使用专业文本编辑器(如notepad++)确认实际编码
    • 在程序中添加更多启发式规则

2. 转换后乱码

  • 问题:转换后出现乱码
  • 解决
    • 确认源文件的实际编码
    • 尝试不同的源编码设置
    • 使用"自动检测"功能
    • 对于特殊字符,使用utf-8编码

3. 大文件处理

  • 问题:处理大文件时内存不足
  • 解决
    • 使用流式处理(streamreader/streamwriter)
    • 分块读取和写入文件
    • 增加系统虚拟内存
    • 使用64位应用程序

4. 特殊字符处理

  • 问题:某些特殊字符无法正确转换
  • 解决
    • 使用utf-8编码处理多语言文本
    • 对于特殊符号,使用unicode转义序列
    • 在转换前进行字符替换

项目总结

这个文件编码转换工具提供了完整的解决方案,具有以下特点:

全面的编码支持

  • 支持12+种常见编码格式
  • 智能检测无bom文件的编码
  • 正确处理中文字符集

高效的转换引擎

  • 异步处理避免界面卡顿
  • 批量转换支持
  • 流式处理大文件

用户友好的界面

  • 直观的操作流程
  • 详细的结果展示
  • 实时的操作日志
  • 进度和状态反馈

健壮的错误处理

  • 全面的异常捕获
  • 详细的错误信息
  • 可恢复的操作流程

扩展性设计

  • 模块化架构
  • 易于添加新功能
  • 支持插件式扩展

以上就是基于c#实现一个文件编码转换工具的详细内容,更多关于c#文件编码转换工具的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com