Статья описывает Windows Workflow Activity FileRead. Activity разработана на языке C#. Activity получает от клиента имя файла произвольного типа, читает его,
формирует байтовый массив и передает клиенту посредством Web Service WCF. Клиент получает и отображает байтовый массив, записывает точную копию считанного файла на локальный диск с новым именем. Представлен рабочий проект MS Visual Studio 2010 WCF + WorkFlow, в котором применяется описываемое Activity. В состав проекта входят WorkFlow, библиотека входных и выходных классов,
Windows Form клиент запрашивающий, получающий и записывающий данные в файл. Клиент отображает полученный с сервера байтовый массив.
1. Входные данные Activity FileRead.
Единственым входным аргументом Activity служит имя файла :
[RequiredArgument]
public InArgument<string> fileName { get; set; }
2. Выходные данные Activity FileRead.
Выходные аргументы для Activity находяться в класса OutputArguments и состоят из двух свойств.
namespace ClassLibrary
{
public class OutputArguments
{
public byte[] data { get; set; }
public string error { get; set; }
}
}
3. Исходный текст Activity FileRead.
Класс реализующий Activity FileRead создан асинхронным, содержащим два метода:
- BeginExecute;
- EndExecute.
Как видно из приведенного ниже текста, чтение файла начинается в методе BeginExecute, затем работа Activity приостаналивается и завершается процесс в методе EndExecute.
/* 28.07.2012 Activity для асинхронного чтения файла.
Входной параметр - имя файла.
Выходными параметрами являются массив байтов и строка ошибки.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Activities;
using System.IO;
using ClassLibrary;
namespace ActivityLibrary
{
public sealed class ReadFile : AsyncCodeActivity
{
[RequiredArgument]
public InArgument<string> fileName { get; set; }
[RequiredArgument]
public OutArgument<OutputArguments> OutputArguments { get; set; }
private byte[] buff = null;
private FileStream file = null;
private String FileName = String.Empty;
private OutputArguments outData = null;
protected override IAsyncResult BeginExecute(AsyncCodeActivityContext context, AsyncCallback callback, object state)
{
try
{
// Check name file
if (String.IsNullOrEmpty(fileName.Get(context))) throw new ArgumentNullException("Value", "File Name is null");
// Get name file
FileName = Path.GetFullPath(fileName.Get(context));
// Check file
if (!File.Exists(FileName)) throw new ArgumentNullException("Value", "Not Exists File");
// Open file
file = File.Open(FileName, FileMode.Open, FileAccess.Read, FileShare.Read);
context.UserState = file;
// Size file
int length = (int)file.Length;
buff = new byte[length];
//Start read file
return file.BeginRead(buff, 0, length, callback, state);
}
catch (Exception ex)
{
outData.error = ex.ToString();
Console.WriteLine(ex.Message);
return null;
}
}
protected override void EndExecute(AsyncCodeActivityContext context, IAsyncResult result)
{
try
{
file = (FileStream)context.UserState;
file.EndRead(result);
// Create output argument
outData = new OutputArguments();
outData.data = buff;
}
catch (Exception ex)
{
outData.error = ex.ToString();
Console.WriteLine(ex.Message);
}
finally
{
file.Close();
}
OutputArguments.Set(context, outData);
}
}
}
4. Клиент для Activity FileRead.
/* 28.07.2012
Клиент для проверки Activity ReadFile.
1. Обеспечивает диалог для выбора имени файла.
2. Передает имя файла Activity.
3. Принимает byte[] и отображает в textBox в виде списка байтов.
4. Записывает массив на диск в виде файла.
*/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ClassLibrary;
using System.IO;
namespace ClientReadFileAsyncActivity
{
public partial class Form1 : Form
{
OutputArguments outData = null;
OpenFileDialog dialog = null;
string ext = String.Empty;
string fileName = String.Empty;
string new_name = String.Empty;
ServiceReference.ServiceClient client;
public Form1()
{
InitializeComponent();
outData = new OutputArguments();
client = new ServiceReference.ServiceClient();
}
// Write file
private void button1_Click(object sender, EventArgs e)
{
try
{
if (String.IsNullOrEmpty(textBox2.Text)) throw new ArgumentNullException("Value", "Name file empty");
if (String.IsNullOrEmpty(textBox3.Text)) throw new ArgumentNullException("Value", "New name file is empty");
outData = client.GetData(textBox2.Text);
string outStr = null;
if (outData.error == null)
{
// Output byte
foreach(byte item in outData.data) outStr += item.ToString() + " ";
textBox1.Text = outStr;
// Write file
File.WriteAllBytes(textBox3.Text, outData.data);
}
else
{
MessageBox.Show(outData.error);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString(), "Error",MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
// Open dialog and select file
private void button2_Click(object sender, EventArgs e)
{
// Open Dialog
dialog = new OpenFileDialog();
dialog.InitialDirectory = "G:\\";
dialog.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
dialog.FilterIndex = 2;
dialog.RestoreDirectory = true;
if (dialog.ShowDialog() == DialogResult.OK)
{
//Create new name
textBox2.Text = dialog.FileName;
ext = dialog.FileName.Substring(dialog.FileName.IndexOf(".") + 1);
fileName = dialog.FileName.Substring(dialog.FileName.IndexOf("\\") + 1);
new_name = fileName.Substring(0, fileName.IndexOf(".")) + "_new" + "." + ext;
textBox3.Text = @"G:\" + new_name;
}
}
}
}