ファイルをECDICからASCII形式に変換しようとしていますが、興味深い問題が発生しました。ファイルには、固定長のレコードが含まれ、一部のフィールドは符号付き2進整数(レコードレイアウトではB4と記述)、および長精度の数値(レコードレイアウトではL8と記述)です。文字データは問題なく変換できましたが、どうすれば変換できるのかわかりません。元のシステム( IBM 5110 )のリファレンス・マニュアルから、フィールドを以下に説明します。
Bは、BASIC内部データ形式に変換される固定小数点符号付き2進整数形式の数値データ項目の長さ(2、4、または8バイト)を示します。レコードI/Oファイル入力の場合、レコードの次の2、4、または8バイトには、システムによって内部データ形式に変換され、READFILEまたはREREADで指定された変数に割り当てられる符号付きバイナリ値が含まれます。 FORMステートメントを使用したFILEステートメント。
と
Lは、数値の長精度(8文字)を示します。入力の場合、このエントリは、レコード内の8桁の長精度値が、READFILEまたはREREADFILEステートメントで指定された対応する数値変数に変換されずに割り当てられることを示します。
編集:これが私が変換に使用しているコードです
private void ConvertFile(EbcdicFile file)
{
if (file == null) return;
var filePath = Path.Combine(file.Path, file.FileName);
if (!File.Exists(filePath))
{
this.Logger.Info(string.Format("Cannot convert file {0}. It does not exist.", filePath));
return;
}
var ebcdic = Encoding.GetEncoding(37);
string convertedFilepath = Path.Combine(file.Path, file.ConvertedFileName);
byte[] fileData = File.ReadAllBytes(filePath);
if (!file.HasNumericFields)
File.WriteAllBytes(convertedFilepath, Encoding.Convert(ebcdic, Encoding.ASCII, fileData));
else
{
var convertedFileData = new List<byte>();
for (int position = 0; position < fileData.Length; position += file.RecordLength)
{
var segment = new ArraySegment<byte>(fileData, position, file.RecordLength);
file.Fields.ForEach(field =>
{
var fieldSegment = segment.Array.Skip(segment.Offset + field.Start - 1).Take(field.Length);
if (field.Type.Equals("string", StringComparison.OrdinalIgnoreCase))
{
convertedFileData.AddRange(
Encoding.Convert(ebcdic, Encoding.ASCII, fieldSegment.ToArray())
);
}
else if (field.Type.Equals("B4", StringComparison.OrdinalIgnoreCase))
{
// Not sure how to convert this field
}
else if (field.Type.Equals("L8", StringComparison.OrdinalIgnoreCase))
{
// Not sure how to convert this field
}
});
}
File.WriteAllBytes(convertedFilepath, convertedFileData.ToArray());
}
}