Исходники.Ру - Программирование
Исходники
Статьи
Книги и учебники
Скрипты
Новости RSS
Магазин программиста

Главная » Статьи по программированию » .NET - Все статьи »

Обсудить на форуме Обсудить на форуме

Работа с кодировкой DOS
В практике программирования при использовании нескольких операционных систем рано или поздно возникает задача перекодирования информации из одного формата в другой. Простейший пример - чтение/запись текстовых файлов в формате DOS из Windows-программ (частный случай - запись информации из программы FoxPro в виде текста и последующая загрузка записанного файла для его обработки).

В практике программирования при использовании нескольких операционных систем рано или поздно возникает задача перекодирования информации из одного формата в другой. Простейший пример - чтение/запись текстовых файлов в формате DOS из Windows-программ (частный случай - запись информации из программы FoxPro в виде текста и последующая загрузка записанного файла для его обработки).

Хотя в .Net и предусмотрена работа с текстовыми файлами, но перечень поддерживаемых кодировок не включает кодировку DOS (точнее говоря, как один из вариантов можно использовать кодировку операционной системы по умолчанию, но в Windows, под управлением которой работает .Net, кодировка DOS по умолчанию не устанавливается).

Поэтому возникает проблема перекодировки при чтении текстовых файлов DOS в программы .Net и, соответственно, при записи в кодировке DOS.

Принцип перекодирования известен, безусловно, любому программисту - взять символ во входном потоке (массиве) и преобразовать его либо с помощью внутренней таблицы соответствия кодов, либо с помощью расчетного алгоритма. Поэтому сама задача перекодирования даже неинтересна - в лучшем случае можно обсуждать способы оптимизации с точки зрения быстродействия или используемой памяти.

Архитектурное же решение, используемое в .Net для подключения произвольных алгоритмов перекодирования, достойно более детального рассмотрения (тем более что в Delphi ничего подобного не просматривается, а в Java, ближайшем конкуренте .Net, подобная архитектура появилась только в начале 2002 года с выходом JDK 1.4).

Итак, в .Net для доступа к текстовым файлам (в общем случае - к любому потоку) используются два специализированных класса - StreamReader для чтения и StreamWriter для записи. У обоих классов имеется ряд конструкторов, которые позволяют подключать внешние перекодировщики (взято из документации на C#):

public StreamReader(Stream, Encoding); Initializes a new instance of the StreamReader class for the specified stream with the specified character encoding.
public StreamReader(string, Encoding); Initializes a new instance of the StreamReader class for the specified file name and with the specified character encoding.
public StreamReader(Stream, Encoding, bool); Initializes a new instance of the StreamReader class for the specified stream, with the specified character encoding and byte order mark detection option.
public StreamReader(string, Encoding, bool); Initializes a new instance of the StreamReader class for the specified file name, with the specified character encoding and byte order mark detection option.
public StreamReader(Stream, Encoding, bool, int); Initializes a new instance of the StreamReader class for the specified stream, with the specified character encoding, byte order mark detection option, and buffer size.
public StreamReader(string, Encoding, bool, int); Initializes a new instance of the StreamReader class for the specified file name, with the specified character encoding, byte order mark detection option, and buffer size.
public StreamWriter(Stream, Encoding); Initializes a new instance of the StreamWriter class for the specified stream, using the specified encoding and the default buffer size.
public StreamWriter(Stream, Encoding, int); Initializes a new instance of the StreamWriter class for the specified stream, using the specified encoding and buffer size.
public StreamWriter(string, bool, Encoding); Initializes a new instance of the StreamWriter class for the specified file on the specified path, using the specified encoding and default buffer size. If the file exists, it can be either overwritten or appended to. If the file does not exist, this constructor creates a new file.
public StreamWriter(string, bool, Encoding, int); Initializes a new instance of the StreamWriter class for the specified file on the specified path, using the specified encoding and buffer size. If the file exists, it can be either overwritten or appended to. If the file does not exist, this constructor creates a new file.

Из приведенного списка видно, что везде участвует <волшебный> параметр типа Encoding, который на самом деле представляет собой специальный класс для перекодирования. И, поскольку мы можем легко написать своего наследника от этого класса, вопрос перекодировки становится и на архитектурном уровне очень простой задачей. Более того, однажды написанный класс специализированной перекодировки может использоваться во многих местах, например, при перекодировании информации, записанной в memo-полях базы данных, или XML-файлов.

Если же рассмотреть класс более подробно, то становится понятно, что он в свою очередь тоже не является монолитной сущностью, а состоит из 2-х относительно независимых вещей - кодировщика и декодировщика (см. методы GetDecoder и GetEncoder класса Encoding). Такое архитектурное решение позволяет реализовывать достаточно простой и эффективный код (см. исходный текст перекодировщика DOS). В завершение для примера отобразим диаграмму классов, используемых при чтении текстового файла DOS:



Пример использования перекодировщика:
using System;
using System.IO;
using System.Text;
using DrgEncoding;

namespace Test1
{
  class Class1 {
    [STAThread]
    static void Main() {
      // имя файла DOS
      string fileName = @"c:\test1.txt";
      // создание перекодировщика
      Encoding encoding = new Encoding866();
      // вывод параметров перекодировщика
      Console.WriteLine("Encoding Properties:");
      Console.WriteLine("BodyName: {0}", encoding.BodyName);
      Console.WriteLine("CodePage: {0}", encoding.CodePage);
      Console.WriteLine("EncodingName: {0}", encoding.EncodingName);
      Console.WriteLine("HeaderName: {0}", encoding.HeaderName);
      Console.WriteLine("IsBrowserDisplay: {0}", encoding.IsBrowserDisplay);
      Console.WriteLine("IsBrowserSave: {0}", encoding.IsBrowserSave);
      Console.WriteLine("IsMailNewsDisplay: {0}", encoding.IsMailNewsDisplay);
      Console.WriteLine("IsMailNewsSave: {0}", encoding.IsMailNewsSave);
      Console.WriteLine("WebName: {0}", encoding.WebName);
      Console.WriteLine("WindowsCodePage: {0}", encoding.WindowsCodePage);
      Console.WriteLine("WindowsCodePage: {0}", encoding.WindowsCodePage);
      // запись в текстовый файл
      StreamWriter writer = new StreamWriter(fileName, false, encoding);
      writer.WriteLine("проверка");
      writer.Flush();
      writer.Close();
      // чтение из текстового файла, вывод результатов
      StreamReader reader = new StreamReader(fileName, encoding);
      while (reader.Peek() > -1) {
        Console.WriteLine(reader.ReadLine());
      }
    }
  }
}    

 


 


Может пригодится:


Автор: Сергей Иванов
Прочитано: 4265
Рейтинг:
Оценить: 1 2 3 4 5

Комментарии: (0)

Добавить комментарий
Ваше имя*:
Ваш email:
URL Вашего сайта:
Ваш комментарий*:
Код безопастности*:

Рассылка новостей
Рейтинги
© 2007, Программирование Исходники.Ру