Китайские кодировки имеют переменную длину, будь то Big5 или GB18030.Это означает, что X
хранится как один байт, а 高
хранится как два байта.Кажется, этот файл имеет фиксированную длину байт на поле, а не фиксированную длину символа.
Это означает, что код, который ожидает фиксированную длину символа , не сможет легко прочитать этот файл.Это включает в себя Excel и, вероятно, каждую библиотеку или код обработки CSV.
В худшем случае вы можете читать байты непосредственно из файлового потока.Каждый набор байтов можно преобразовать в строку, используя Encoding.ToString
.Вы можете получить кодировку Big5 с помощью Encoding.GetEncoding(950)
.
Encoding _big5=Encoding.GetEncoding(950);
byte[] _buffer=new byte[90];
public string GetField(FileStream stream,int offset, int length)
{
var read=stream.ReadBytes(_buffer,offset,length);
if(read>0)
{
return _big5.GetString(buffer,0,read);
}
else
{
return "";
}
}
//Quick & dirty way to skip to end
public void SkipToLineEnd(FileStream stream)
{
int c;
while((in=stream.ReadByte()>-1)
{
if (c==(int)'\n')
{
return;
}
}
}
. Вы можете построить запись из строки следующим образом:
public MyRecord GetNextRecord(FileStream stream)
{
var record = new MyRecord
{
Id=GetField(stream,0,9),
...
//6 bytes, not just 4
Comp = GetField(stream,28,6),
..
//Start from 50, 16 bytes
Format = GetField(stream,50,16)
};
SkipToLineEnd(stream);
return myRecord;
}
Вы можете написать метод итератора, который читает записи этогопуть, пока он не достигнет конца файла.Быстрый и грязный способ сделать это - проверить, находится ли Position
потока настолько близко к концу, что не может быть получена полная запись, например:
public IEnumerable<MyRecord> GetRecords(FileStream stream,int recordLength)
{
while(stream.Position < stream.Length - recordLength)
{
yield return GetRecordNextRecord(stream);
}
}
И используйте его следующим образом:
var records=GetRecords(myStream,96);
foreach(var record in records)
{
....
}
Это позаботится о том, чтобы завершать новые строки и, возможно, прерывать последние строки.
Чтобы пропустить строки заголовка, просто позвоните SkipToLineEnd()
столько раз, сколько необходимо.
Вы можете использовать такую библиотеку, как EPPlus , чтобы сгенерировать файл Excel непосредственно из этогонапример,
using (var p = new ExcelPackage())
{
var ws=p.Workbook.Worksheets.Add("MySheet");
ws.Cells.LoadFromCollection(records);
p.SaveAs(new FileInfo(@"c:\workbooks\myworkbook.xlsx"));
}