String -> C-like string. Подскажите, как лучше?
Задача - преобразовать строку типа String в С-like String. Язык - VB.NET, фреймворк 2.0.
Идеи, как это сделать:
1. Преобразовать в Memory stream посимвольно, добаавить нулевой байт в конце.
2. Преобразовать в массив символов, добавить нулевой байт в конце.
Сложность в том, что должны быть доступны операции конкатенации и деконкатенации по нулевому байту. Кроме прочего, всё это должно быть преобразуемо в поток для передачи по сети.
Сейчас я склоняюсь к посимвольному преобразованию каждой строки в Stream, с дописыванием при помощи Write и EndWrite, деконкатенацию удобно было бы проводить после преобразования .ToString.
using System.Collections.Generic;
using System.Text;
using Microsoft.VisualBasic;
using System.Threading;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
String str = "I am a pupil";
str += "\0";
for (int i = 0; i < str.Length;i++ )
{
Console.Write(Conversion.Hex(str) + " ");
}
Thread.Sleep(10000);
}
}
}
Это совсем не то. Conversion.Hex(char ch) преобразует символ в шестнадцатиричное представление. Я привёл пример строки в HEX-виде, поскольку только так понятно отличие С-строк от обычных. То есть, обычные строки начинаются с заголовка, содержащего информауию о длине строки, в простом случае это один байт. С-строки начинаются сразу с первого символа строки, и заканчиваются всегда 0x00. Поэтому я пришёл к мысли, что надо писать в стрим символы и в конце дописывать 0х00. Насколько я понял, при передачи строки в стрим она передаётся целиком вместе с заголовком длины. Или я не прав?
using System.Collections.Generic;
using System.Text;
using Microsoft.VisualBasic;
using System.Threading;
using System.Runtime.InteropServices;
using System.IO;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
String path="F:\\test.txt";
FileStream fs = new FileStream(path,FileMode.OpenOrCreate, FileAccess.ReadWrite);
StreamWriter sw = new StreamWriter(fs);
BufferedStream bs = new BufferedStream(sw.BaseStream);
String str1 = "free";
sw.Write(str1);
Console.WriteLine(bs.Length);
Thread.Sleep(5000);
sw.Close();
fs.Close();
}
}
}
Copies the contents of a managed [COLOR=#0000ff]String[/COLOR] into unmanaged memory, converting into ANSI format as it copies.
Namespace: System.Runtime.InteropServices
Assembly: mscorlib (in mscorlib.dll)
Return Value: The address, in unmanaged memory, to where s was copied, or 0 if a null string was supplied.
[COLOR=blue]using[/COLOR] [COLOR=blue]namespace[/COLOR] System::Runtime::InteropServices;
[COLOR=blue]int[/COLOR] main()
{
[COLOR=green]// Create a managed string.[/COLOR]
String^ managedString = [COLOR=maroon]"Hello unmanaged world (from the managed world)."[/COLOR];
[COLOR=green]// Marshal the managed string to unmanaged memory.[/COLOR]
[COLOR=blue]char[/COLOR]* stringPointer = ([COLOR=blue]char[/COLOR]*) Marshal::StringToHGlobalAnsi(managedString ).ToPointer();
[COLOR=green]// Always free the unmanaged string.[/COLOR]
Marshal::FreeHGlobal(IntPtr(stringPointer));
[COLOR=blue]return[/COLOR] 0;
}
using System.Collections.Generic;
using System.Text;
using Microsoft.VisualBasic;
using System.Threading;
using System.Runtime.InteropServices;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Windows.Forms;
namespace ConsoleApplication2
{
class Program
{
public static void Main(string[] args)
{
string str = "free";
MemoryStream ms=new MemoryStream();
BinaryWriter bw = new BinaryWriter(ms);
bw.Write(str);
byte[] buf = ms.ToArray();
ms.Dispose();
Console.WriteLine("For BUF");
Console.WriteLine("BUFFER LENGHT: {0}",buf.Length);
Console.Write("\n");
for (int i = 0; i < buf.Length; i++)
{
Console.Write("0x{0:X} ", buf);
}
Console.Write("\n");
for (int i = 0; i < buf.Length; i++)
{
Console.Write("{0} ", Convert.ToChar(buf));
}
byte[] buf_1 = new byte[buf.Length];
Array.Copy(buf, 1, buf_1, 0, buf.Length - 1);
Console.WriteLine("For BUF_1");
Console.WriteLine("BUFFER_1 LENGHT: {0}", buf.Length);
Console.Write("\n");
for (int i = 0; i < buf_1.Length; i++)
{
Console.Write("0x{0:X} " , buf_1);
}
for (int i = 0; i < buf.Length; i++)
{
Console.Write("{0} ", Convert.ToChar(buf_1));
}
Thread.Sleep(5000);
}
}
}
Copies the contents of a managed [COLOR=#0000ff]String[/COLOR] into unmanaged memory, converting into ANSI format as it copies.
Namespace: System.Runtime.InteropServices
Assembly: mscorlib (in mscorlib.dll)
Return Value: The address, in unmanaged memory, to where s was copied, or 0 if a null string was supplied.
Ого. Это, ИМХО, паллиативный метод; я полагаю, лучше тогда вообще работать с ArrayList и методами классов System.Text. Кстати, скорее всего так работать лучше всего, поскольку с ArrayList удобнее реализовать функцинальность строк. Есть вариант создать такой класс:
Inherits ArrayList
'Здесь у нас будет код, специфический для эмуляции С-строк
End Class
Ещё бы она не передавалась. Она по идее не должна передаваться только в том случае, когда читается посимвольно.