C # Ошибка чтения двух дат из двоичного файла - PullRequest
2 голосов
/ 18 мая 2010

При чтении двух дат из двоичного файла я вижу ошибку ниже:

"Выходной буфер символов слишком мал для размещения декодированных символов, кодирующих 'Unicode (UTF-8)' fallback 'System.Text.DecoderReplacementFallback'. Имя параметра: chars"

Мой код указан ниже:

static DateTime[] ReadDates()
{
    System.IO.FileStream appData = new System.IO.FileStream(
       appDataFile, System.IO.FileMode.Open, System.IO.FileAccess.Read);

    List<DateTime> result = new List<DateTime>();
    using (System.IO.BinaryReader br = new System.IO.BinaryReader(appData))
    {
        while (br.PeekChar() > 0)
        {
            result.Add(new DateTime(br.ReadInt64()));
        }
        br.Close();
    }
    return result.ToArray();
}

static void WriteDates(IEnumerable<DateTime> dates)
{
    System.IO.FileStream appData = new System.IO.FileStream(
       appDataFile, System.IO.FileMode.Create, System.IO.FileAccess.Write);

    List<DateTime> result = new List<DateTime>();
    using (System.IO.BinaryWriter bw = new System.IO.BinaryWriter(appData))
    {
        foreach (DateTime date in dates)
            bw.Write(date.Ticks);
        bw.Close();
    }
}

В чем может быть причина? Спасибо

Ответы [ 4 ]

4 голосов
/ 18 мая 2010

Проблема в том, что вы используете PeekChar - он пытается декодировать двоичные данные, как если бы это был символ UTF-8. К сожалению, в BinaryReader я не вижу ничего, что позволяло бы определить конец потока.

Вы могли бы просто продолжать звонить ReadInt64, пока не наберется EndOfStreamException, но это довольно ужасно. Хм. Вы можете вызвать ReadBytes(8), а затем BitConverter.ToInt64 - это позволит вам остановиться, когда ReadBytes возвращает байтовый массив с чем-то меньшим, чем 8 байтов ... хотя это не здорово.

Кстати, вам не нужно явно вызывать Close, поскольку вы уже используете оператор using. (Это касается и читателя, и писателя.)

1 голос
/ 18 мая 2010

Я думаю, что Джон прав, что PeekChar душит двоичные данные.

Вместо потоковой передачи данных вы можете получить все это в виде массива и получить значения из этого:

static DateTime[] ReadDates() {
  List<DateTime> result = new List<DateTime>();
  byte[] data = File.ReadAllBytes(appDataFile);
  for (int i = 0; i < data.Length; i += 8) {
    result.Add(new DateTime(BitConverter.ToInt64(data, i)));
  }
  return result;
}
0 голосов
/ 26 сентября 2014

Простым решением вашей проблемы было бы явное указание кодировки ASCII для BinaryReader, таким образом PeekChar() использует только один байт, и такого рода исключения (на самом деле, ошибка .NET) не происходит:

using (System.IO.BinaryReader br = new System.IO.BinaryReader(appData, Encoding.ASCII))
0 голосов
/ 05 августа 2010
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...