Файловый ввод-вывод в C#

Цель занятия

Изучить простые способы работы с файлами в C#.

Краткие теоретические сведения.

В данной работе будут изучены не только механизмы файлового ввода-вывода, но и другие важные программные принципы C#. Дополнительно рекомендуем [9].

Прежде всего, запустите Visual Studio .Net и выберите опцию New Project, а затем Windows AppUcation. На экране появится форма, на которую вам следует перетащить элементы управления: comboBox, PictureBox и Button, причем через свойство Items/CoUection окна свойств элемента comboboxi занесите начальные значения в comboBox (рис. 4.1).

Собственно, это и есть форма проекта, с которой будем иметь дело в работе. Смысл работы заключается в том, что у нас имеется (будет вами создан) некоторый файл, содержащий информацию о расположении рисунков. Например, его содержимое:    Мотоцикл:    mot.bmp,     Автомобиль:   avto.bmp,  Трактор:

lorry.bmp.

Рис. 4.1. Добавление элементов в выпадающий список

Пользователь будет выбирать из выпадающего списка (comboBox) название элемента — например, мотоцикл. Затем, нажимая кнопку Show Picture, он будет получать изображение мотоцикла (рис. 4.2).

Рис. 4.2. Окно приложения для отображения рисунков

Для решения этой задачи нужно научиться работать с comboBox и PictureBox, выполнять работу с файлами и уметь обрабатывать строки. Для первого занятия по C# этого вполне достаточно. Сначала о работе с элементами. Выбор элементов осуществляется из окна ToolBox, расположенного слева на экране (а если его нет, то включите его, воспользовавшись командой меню View). Выберите вкладку Window Forms окна ToolBox. Элементы добавляются так же, как и в среде программирования Delphi. Взгляните на конструкцию:

if (comboBoxl.SelectedIndex<O)

{

MessageBox.Show("No items selected");

}

Это чистая конструкция языка C#. Терм comboBoxl.Selectedindex получает значение индекса выделенного элемента списка com- boBox. Отметим, что терм comboBoxl.seiecteditem имеет значение выделенного элемента списка comboBox. В этой работе нам пока достаточно и этого. Чтобы добавить элемент в список, используйте команду comboBoxl.Items.Add("NewElement"), а чтобы удалить элемент из списка — команду comboBoxl .Items.Remove("NewElement") .

Работу с файлами лучше пояснить прямо из текста программы:

StreamReader sr= File.OpenText(test.path); string s=""; s=sr.ReadLine(); if (s!=nuU)

U

Объявляется потоковая переменная sr типа streamReader. Этой переменной присваивается значение файловой переменной File.OpenText (имя_файла). Переменная sr определяет текстовый файл для ввода, хотя, заметим, что представление информации в этом файле не соответствует ASCII (буцет использоваться кодировка UTF8Encoding). Чтение строки из файла осуществляет команда s=sr.ReadLine (). Если прочитан хотя бы один байт, то это устанавливает проверка if (s!=nuii) {}. Таким образом, если в нашем файле одна-единственная строка, а пока это так и есть, то переменная s имеет именно следующий вид: s

="MoTon,MKn:mot.bmp,Автомобиль:avto.bmp,Трактор:lorry.bmp"

Теперь основополагающий принцип. Программирование в C# выполняется как и в Java на основе классов. В каком-то одном из этих классов должен быть реализован метод Main (). В программе создаются объекты классов — как обычно, с помощью конструкторов. Временно оторвемся от нашей программы и создадим что-то очень простое: на форме разместим кнопку, по щелчку мыши на которой будем выдавать сообщение. Но в обработчике события от кнопки создадим объект, а для вывода сообщения воспользуемся методом этого объекта. В листинге 4.1 приведен программный код приложения, которое выполняет эти действия.

| Листинг 4.1. Каркас простого приложения с кнопкой

using System; class Ex

{ // Объявление собственного класса с методом ShowStr() public void ShowStr()

MessageBox.Show("Hy, что, получили?"); return ;

public class Forml : System.Windows.Forms.Form

static void Main()

Application.Run(new Forml());

private void buttonl_Click(object sender, System.EventArgs e)

Ex myObj = new Ex(); myObj.ShowStr();

Многоточие заменяет все производимые системой подстановки, в которых нам пока нет никакой нужды. Главное, что мы объявили свой собственный класс:

class Ex

public void ShowStr()

MessageBox.Show("Hy, что, получили?"); return ;

И вот теперь его используем общепринятым образом:

Ex myObj= new Ex(); myObj.ShowStr();

Но все это известно из других языков. Теперь возвращаемся снова к нашей программе и приводим ее полный текст (листинг 4.2).

| Листинг 4.2. Полный текст приложения для чтения из файла j и рисования картинки

using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Data; using System.IO; using System.Text; namespace ComboandFiles

/// <summary>

/// Summary description for Forml.

/// </summa ry>

public class Forml : System.Windows.Forms.Form

private System.Windows.Forms.ComboBox comboBoxl; private System.Windows.Forms.PictureBox pictureBoxl; private System.Windows.Forms.Button buttonl;

/// <summary>

/// Required designer variable.

/// </summary>

private System.ComponentModel.Container components = null; private Bitmap MyImage; public Forml()

{

//

// Required for Windows Form Designer support //

InitializeComponent();

//

// TODO: Add any constructor code after InitializeComponent // call //

}

/// <summary>

/// Clean up any resources being used.

/// </summary>

protected override void Dispose( bool disposing )

{

if( disposing )

{

if (components != null)

{

components.Dispose ();

}

}

base.Dispose( disposing );

class Test {

public string path; public Test()

{

path=0"d:/msdev/test.txt";

}

public string getinfo()

{

if (!File.Exists(path))

{return ("File does not exists");} else {return ("OK");}

}

}

#region Windows Form Designer generated code /// <summary>

/// Required method for Designer support – do not modify /// the contents of this method with the code editor.

/// </summary>

private void InitializeComponent()

{

this.comboBoxl = new System.Windows.Forms.ComboBox(); this.pictureBoxl = new System.Windows.Forms.PictureBox(); this.buttonl = new System.Windows.Forms.Button(); this.SuspendLayout();

//

// comboBoxl //

this.comboBoxl.Items.AddRange(new object[] {"Мотоцикл",

"Автомобиль", "Трактор"}); this.comboBoxl.Location = new System.Drawing.Point(40, 48); this.comboBoxl.Name = "comboBoxl";

this.comboBoxl.Size = new System.Drawing.Size(128, 21);

this.comboBoxl.TabIndex = 0;

this.comboBoxl.Text = "comboBoxl";

//

// pictureBoxl //

this.pictureBoxl.BackColor =

System.Drawing.SystemColors.Control;

this.pictureBoxl.Location = new System.Drawing.Point(232, 48) ;

this.pictureBoxl.Name = "pictureBoxl";

this.pictureBoxl.Size = new System.Drawing.Size(208, 232); this.pictureBoxl.TabIndex = 1; this.pictureBoxl.TabStop = false;

//

// buttonl //

this.buttonl.BackColor=System.Drawing.Color.FromArgb(

((System.Byte) (255)),   ((System.Byte) (192)),

((System.Byte) (192))) ;

this.buttonl.Font = new System.Drawing.Font("Microsoft Sans Serif",

9.75F, System.Drawing.FontStyle.Bold,

System.Drawing.GraphicsUnit.Point, ((System.Byte) (204))); this.buttonl.Location = new System.Drawing.Point(42, 16); this.buttonl.Name = "buttonl";

this.buttonl.Size = new System.Drawing.Size(126, 24); this.buttonl.TabIndex = 2; this.buttonl.Text = "Show Picture ";

this.buttonl.Click += new

System.EventHandler(this.buttonl_Click);

//

// Forml //

this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); this.BackColor = System.Drawing.Color.RosyBrown;

this.ClientSize = new System.Drawing.Size(456, 397);

this.Controls.Add(this.buttonl);

this.Controls.Add(this.pictureBoxl);

this.Controls.Add(this.comboBoxl);

this.Name = "Forml";

this.Text = "Forml";

this.ResumeLayout(false);

}

#endregion /// <summary>

/// The main entry point for the application.

/// </summary>

[STAThread]

static void Main()

{

Application.Run(new Forml());

}

private void buttonl_Click(object sender, System.EventArgs e)

{

if (comboBoxl.SelectedIndex<O)

{MessageBox.Show("No items selected");} else {

Test test=new Test(); string stest=test.getinfo(); if (stest=="OK")

{

i f (MyImage!=null)

{ MyImage.Dispose();}

StreamReader sr= File.OpenText(test.path); string s=""; s=sr.ReadLine(); if (s!=null)

string sl= comboBoxl.SelectedItem.ToString(); int k= s.IndexOf(sl,0,s.Length);

if (k<0)

{

MessageBox.Show("ComBoItem not Found"); goto labelfin;

}

k=s.IndexOf(‘:’,k,s.Length-к) ; if (k<0)

{

MessageBox.Show(": not found after specified combo Item") ;

goto labelfin;

}

s=s.Substring(k+1,s.Length-к-1);

k=s.IndexOf(‘,’,0,s.Length);

if (k>=0)

{s=s.Substring(0,k);}

s=0"d:\msdev\"+s;

pictureBoxl.SizeMode=

PictureBoxS izeMode.StretchImage;

MyImage= new Bitmap(s);

pictureBoxl.ClientSize=new Size (120,120);

pictureBoxl.Image=(Image) MyImage; labelfin: ;

}

}

else

{

MessageBox.Show(stest);

FileStream fs=File.Create(test.path,1024);

{

Byte[]info=new UTF8Encoding(true) .GetBytes("M0T0u,MKn: mot.bmp,

Автомобиль: avto.bmp, Трактор: lorry.bmp"); fs.Write(info,0,info.Length) ;

MessageBox.Show("File Created.Repeat then");

}

}

}

}

}

}

Займемся теперь разъяснением этой программы с учетом того, что очень важные вещи мы уже объяснили. Большая часть этого кода была автоматически добавлена самой системой. Фрагмент:

using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Data; using System.IO; using System.Text;

используется для подключения библиотек классов, содержащих описания системных функций. Например, функции для работы с файлами содержатся в классе System.io. Строка namespace combo- andFiies используется для объявления пространства имен, что является новшеством, впервые введенным в С++. Пространство имен содержит определения имен, используемых в некотором контексте. Например, в программе может встретиться имя функции ReadLine (), которое конфликтует с именем стандартной функции. В этом случае для системы важно, какое пространство имен используется в качестве контекста. Далее идет длинное описание класса public class Forml:                             System.Windows.Forms.Form. Это

описание ничем не занимательно, так как система создает его сама. Но мы поместили внутрь данного описания следующее определение собственного встроенного класса: class Test

public string path; public Test()

{

path=0"d:/msdev/test.txt" ;

}

public string getinfo()

{

if (!File.Exists(path))

{return ("File does not exists");} else {return ("OK");}

}

}

Это описание включает объявление переменной path, конструктора Test (), который данную переменную инициализирует, и метода getinfo(), проверяющего, имеется ли данный файл в указанном каталоге. Кстати, запомните эту простую команду: File.Exists (path). Остается привести код обработчика события от нажатия кнопки и пояснить его, что сделано с помощью помещенных рядом с командами комментариев.

private void buttonl_Click(object sender, System.EventArgs e)

{

if (comboBoxl.SelectedIndex<O) // Проверяет, вьщелен ли // элемент в комбосписке {MessageBox.Show("No items selected");} // Сообщение, если

// не выделен

else

{

Test test=new Test (); // Иначе создает объект класса Test string stest=test.getinfo(); // Метод getinfo()Knacca Test // Сообщает о наличии файла данных if (stest=="OK")

if (MyImage!=null) // Проверяет наличие рисунка // и удаляет текущий рисунок

{ MyImage.Dispose();}

StreamReader sr= File.OpenText(test.path); // Создает / / файловую переменную для ввода строки из файла // с адресами рисунков string s="";

s=sr.ReadLine(); // Читает строку из файла, имя которого // помещено в переменной test.path if (s!=null) // Строка не пуста?

{

string sl=comboBoxl.SelectedItem.ToString(); //

Преобразует

// в подстроку выделенный элемент списка

int k= s.IndexOf(s1,0,s.Length); // Определяет

// местонахождение данной подстроки в строке из файла

if (k<0)

{

MessageBox.Show("ComBoItem not Found");

goto labelfin; // Редкое использование оператора goto

}

k=s.IndexOf(‘:’,k,s.Length-k); // Определяет позицию // ":" вслед за именем подстроки if (k<0)

{

MessageBox.Show(": not found after specified combo Item") ;

goto labelfin;

}

s=s.Substring(k+1,s.Length-k-1); // Определяет адрес

// файла с рисунком

k=s.IndexOf(‘,’,0,s.Length);

if (k>=0)

{s=s.Substring(0,k); }

s=0"d:\msdev\"+s; // Добавляет к имени файла // полный путь; в вашей работе этот оператор следует // изменить

pictureBoxl.SizeMode= PictureBoxSizeMode.StretchImage; MyImage= new Bitmap(s); // Создает битовый образ

// картинки из файла pictureBoxl.ClientSize=new Size(120,120); // Задает

// размеры // картинки

pictureBoxl.Image=(Image) MyImage; // Преобразует

/ / BitMap в Image

labelfin: ;

}

}

else // Файл с адресами картинок не существует, и он // создается

{

MessageBox.Show(stest);

FileStream fs=File.Create(test.path,1024);

{ Byte [] info=new UTF8Encoding(true).GetBytes("M0T0UHKn: mot.bmp,

Автомобиль: avto.bmp, Трактор: lorry.bmp");

fs.Write(info,0,info.Length); // Занесение информации

// в файл из буфера

MessageBox.Show("File Created.Repeat then");

}

}

}

}

}

}

Для отображения рисунка на форме необходимо разместить компонент класса PictureBox. У этого компонента имеется свойство image, которое в качестве значения получает массив

пикселов (или иначе — битмап-образ). В программе это реализовано следующим образом:

MyImage= new Bitmap(s); // Создает битовый образ картинки из

// файла

pictureBoxl.ClientSize=new Size (120,120); // Задает размеры

// картинки

pictureBoxl.Image=(Image) MyImage;

Переменная Myimage объявлена в самом начале класса Formi следующим образом:

private Bitmap MyImage;

В этом приложении неоднократно использовалось диалоговое окно для вывода текстового сообщения MessageBox.show.

Следует также обратить внимание на получение массива байтов, кодирующих отдельные символы строки:

Byte [] info=new UTF8Enc0ding(true).GetBytes("M0T0UHKn: mot.bmp, Автомобиль: avto.bmp, Трактор: lorry.bmp");

Задание

Итак, поставленная в работе цель достигнута. Вам надлежит несколько усложнить задачу, а именно: смоделировать простой SQL-запрос к базе данных в текстовом файле. Следует реализовать задачу поиска автомобиля, например, не старше 1990 года выпуска и стоимостью не выше $1000. Для этого вам нужно включить в текстовый файл поля :

avto: … , price:      …, year:      … ,  photo : …    ,           

avto: … , price: …, year: … , photo : …

Далее потребуется несколько дополнительных возможностей. Во-первых, показываем, как преобразовать строку в целое число на примере:

string s= textBoxl.Text; int i=Convert.ToInt32(s,10);

Во-вторых, рассмотрим, как осуществлять запись и чтение в текстовый файл не одной-единственной строки, а нескольких строк.

В C# для этих целей используют классы streamWriter и streamReader. Покажем это на примере:

using System; using System.IO; class Ex2 {

public static void Main()

{

FileStream ous=File.Create(0"c:\data.txt");

StreamWriter sw= new StreamWriter(ous); sw.WriteLine("one"); sw.WriteLine("two"); sw.Flush() ; sw.Close () ;

StreamReader sr= File.OpenText(0"c:\data.txt"); string sl;

while((sl=sr.ReadLine())!=null)

{

Console.WriteLine(sl);

}

Console.ReadLine(); sr.Close () ;

}

}

Здесь создаем объект StreamWriter для записи В фаЙЛ И StreamReader — для чтения. Предварительно порождаем файловую переменную Fiiestream ous. Запись в файл реализуем комавдой WriteLine (), чтение — ReadLine (). Признаком достижения конца файла является условие sr.ReadLine o==nuii. Теперь вы должны самостоятельно построить простейшее приложение для поиска автомобиля по цене и году.

Источник: Герман О. B., Герман Ю. О., Программирование на Java и C# для студента. — СПб.: БХВ-Петербург, 2005. — 512 c.: ил.

Вы можете следить за любыми ответами на эту запись через RSS 2.0 ленту. Вы можете оставить ответ, или trackback с вашего собственного сайта.

Оставьте отзыв

XHTML: Вы можете использовать следующие теги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

 
Rambler's Top100