mirror of
https://github.com/nsnail/dot.git
synced 2025-06-18 05:23:21 +08:00
90 lines
2.9 KiB
C#
90 lines
2.9 KiB
C#
using System.Diagnostics.CodeAnalysis;
|
||
|
||
namespace Dot.TrimUtf8Bom;
|
||
|
||
public sealed class Main : Tool<Option>, IDisposable
|
||
{
|
||
private int _breakCnt;
|
||
private bool _disposed;
|
||
private static readonly object _lockObj = new();
|
||
private int _procedCnt;
|
||
private ChildProgressBar _step2Bar;
|
||
private int _totalCnt;
|
||
private int _trimCnt;
|
||
public Main(Option opt) : base(opt) { }
|
||
|
||
|
||
~Main()
|
||
{
|
||
Dispose(false);
|
||
}
|
||
|
||
private void Dispose(bool disposing)
|
||
{
|
||
if (_disposed) return;
|
||
if (disposing) _step2Bar?.Dispose();
|
||
_disposed = true;
|
||
}
|
||
|
||
|
||
private void ShowMessage(int procedCnt, int replaceCnt, int breakCnt)
|
||
{
|
||
lock (_lockObj) {
|
||
_procedCnt += procedCnt;
|
||
_trimCnt += replaceCnt;
|
||
_breakCnt += breakCnt;
|
||
_step2Bar.Message = $"已处理:{_procedCnt}/{_totalCnt},移除BOM:{_trimCnt},跳过:{_breakCnt}";
|
||
}
|
||
}
|
||
|
||
public void Dispose()
|
||
{
|
||
Dispose(true);
|
||
GC.SuppressFinalize(this);
|
||
}
|
||
|
||
[SuppressMessage("ReSharper", "PossibleMultipleEnumeration")]
|
||
public override void Run()
|
||
{
|
||
if (!Directory.Exists(Opt.Path)) throw new ArgumentException(nameof(Opt.Path), $"指定的路径“{Opt.Path}”不存在");
|
||
|
||
|
||
var utf8Bom = new byte[] { 0xef, 0xbb, 0xbf };
|
||
using var step1Bar = new IndeterminateProgressBar("查找文件...", DefaultProgressBarOptions);
|
||
|
||
|
||
var fileList = EnumerateFiles(Opt.Path, Opt.Filter);
|
||
_totalCnt = fileList.Count();
|
||
|
||
step1Bar.Message = "查找文件...OK";
|
||
step1Bar.Finished();
|
||
|
||
_step2Bar = step1Bar.Spawn(_totalCnt, string.Empty, DefaultProgressBarOptions);
|
||
|
||
Parallel.ForEach(fileList, file => {
|
||
_step2Bar.Tick();
|
||
ShowMessage(1, 0, 0);
|
||
|
||
var tmpFile = $"{file}.tmp";
|
||
var isReplaced = false;
|
||
using (var fsr = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) {
|
||
Span<byte> buffer = stackalloc byte[utf8Bom.Length];
|
||
var readLen = fsr.Read(buffer);
|
||
if (readLen == utf8Bom.Length && buffer.SequenceEqual(utf8Bom)) {
|
||
using var fsw = new FileStream(tmpFile, FileMode.OpenOrCreate, FileAccess.Write);
|
||
int data;
|
||
while ((data = fsr.ReadByte()) != -1) fsw.WriteByte((byte)data);
|
||
isReplaced = true;
|
||
}
|
||
}
|
||
|
||
if (isReplaced) {
|
||
MoveFile(tmpFile, file);
|
||
ShowMessage(0, 1, 0);
|
||
}
|
||
else {
|
||
ShowMessage(0, 0, 1);
|
||
}
|
||
});
|
||
}
|
||
} |