このドキュメントは対象とするMonoのバージョンが古くなっています。 より新しいバージョンについては以下のページを参照してください。
ここでは、同じソースコードをコンパイルした物を、RedHat Linux 9上のMono 1.0とWindows XP上の.NET Framework version 1.1とで動作させた場合の結果の相違について考察します。 それぞれ、対象となる各名前空間に存在する基本的なクラスを用いて簡単な動作をさせています。 また、一方で生成したアセンブリが他方でも動作するかもテストします。 コンパイラにはmcsおよび.NET Framework version 1.1のcscを使用しました。
System名前空間
System名前空間に存在するクラスを利用してみます。
using System;
namespace SamtaMarta.Samples.Mono.Compatibility
{
class System
{
static void Main(string[] args)
{
// 簡単な入出力
Console.WriteLine( "Hello world!" );
int a, b;
Console.Write( "a = ? " );
a = Int32.Parse( Console.ReadLine().Trim() );
Console.Write( "b = ? " );
b = Int32.Parse( Console.ReadLine().Trim() );
Console.WriteLine( "{0}+{1}={2}", a, b, a + b );
Console.WriteLine( "{0}-{1}={2}", a, b, a - b );
Console.WriteLine( "{0}*{1}={2}", a, b, a * b );
Console.WriteLine( "{0}/{1}={2}", a, b, a / b );
Console.WriteLine();
// Environmentクラス
Console.WriteLine( "OSVersion: {0} {1}", Environment.OSVersion.Platform, Environment.OSVersion.Version );
Console.WriteLine( "CurrentDirectory: {0}", Environment.CurrentDirectory );
Console.WriteLine( "SystemDirectory: {0}", Environment.SystemDirectory );
Console.WriteLine( "UserName: {0}", Environment.UserName );
Console.WriteLine( "MachineName: {0}", Environment.MachineName );
Console.WriteLine();
// Mathクラス
Console.WriteLine( "Sin(π/2) = {0}", Math.Sin( Math.PI / 2.0 ) );
Console.WriteLine( "Cos(π/3) = {0}", Math.Cos( Math.PI / 3.0 ) );
Console.WriteLine( "e^2 = {0}", Math.Pow( Math.E, 2.0 ) );
Console.WriteLine();
// Randomクラス
Random rand = new Random( 0 );
Console.WriteLine( rand.Next() );
Console.WriteLine( rand.Next() );
Console.WriteLine( rand.Next() );
Console.WriteLine();
// DateTime構造体
Console.WriteLine( "Now: {0}", DateTime.Now );
Console.WriteLine( "UtcNow: {0}", DateTime.UtcNow );
}
}
}
Hello world! a = ? 6 b = ? 2 6+2=8 6-2=4 6*2=12 6/2=3 OSVersion: 128 2.4.20.31 CurrentDirectory: /home/santamarta/programming_cs/MonoCompatibility/System SystemDirectory: UserName: santamarta MachineName: localhost.localdomain Sin(π/2) = 1 Cos(π/3) = 0.5 e^2 = 7.38905609893065 1559595546 1755192844 1649316166 Now: 2004/07/25 2:03:01 UtcNow: 2004/07/24 17:03:01
Hello world! a = ? 6 b = ? 2 6+2=8 6-2=4 6*2=12 6/2=3 OSVersion: Win32NT 5.1.2600.0 CurrentDirectory: D:\Temporaly\MonoCompatibility SystemDirectory: C:\WINDOWS\System32 UserName: santa marta MachineName: AYAYA Sin(π/2) = 1 Cos(π/3) = 0.5 e^2 = 7.38905609893065 1559595546 1755192844 1649316166 Now: 2004/07/25 15:35:29 UtcNow: 2004/07/25 6:35:29
- cscでコンパイルしたアセンブリ、RedHat Linux上のMonoで動作OK
- mcsでコンパイルしたアセンブリ、Windows XP上の.NET Frameworkで動作OK
結果について見てみます。 OSのバージョンやシステムディレクトリなど、システムに依存する部分の結果は異なっています。 OSのバージョンについては、 Monoではカーネルのバージョンが表示されています。 また、乱数については同じシード値を用いていて全く同じ結果が出力されていることから、同じ乱数生成アルゴリズムが使われていると考えられます。
System.Collections名前空間
次にSystem.Collections名前空間に存在するクラスを利用してみます。
using System;
using System.Collections;
namespace SamtaMarta.Samples.Mono.Compatibility
{
class SystemCollections
{
static void Main(string[] args)
{
// ArrayList
ArrayList arr = new ArrayList();
arr.Add( "a" );
arr.Add( "c" );
arr.Add( "d" );
arr.Add( "e" );
arr.Add( "g" );
arr.Add( "b" );
arr.Add( "f" );
foreach ( string str in arr )
{
Console.Write( "{0} ", str );
}
Console.WriteLine();
arr.Sort();
foreach ( string str in arr )
{
Console.Write( "{0} ", str );
}
Console.WriteLine();
Console.WriteLine();
// Stack
Stack s = new Stack();
Console.Write( "Pushed: " );
for ( int i = 0; i < 10; i++ )
{
s.Push( i );
Console.Write( "{0} ", i );
}
Console.WriteLine();
Console.Write( "Popped: " );
while ( 0 < s.Count )
{
Console.Write( "{0} ", (int)s.Pop() );
}
Console.WriteLine();
Console.WriteLine();
// Queue
Queue q = new Queue();
Console.Write( "Enqueued: " );
for ( int i = 0; i < 10; i++ )
{
q.Enqueue( i );
Console.Write( "{0} ", i );
}
Console.WriteLine();
Console.Write( "Dequeued: " );
while ( 0 < q.Count )
{
Console.Write( "{0} ", (int)q.Dequeue() );
}
Console.WriteLine();
}
}
}
a c d e g b f a b c d e f g Pushed: 0 1 2 3 4 5 6 7 8 9 Popped: 9 8 7 6 5 4 3 2 1 0 Enqueued: 0 1 2 3 4 5 6 7 8 9 Dequeued: 0 1 2 3 4 5 6 7 8 9
a c d e g b f a b c d e f g Pushed: 0 1 2 3 4 5 6 7 8 9 Popped: 9 8 7 6 5 4 3 2 1 0 Enqueued: 0 1 2 3 4 5 6 7 8 9 Dequeued: 0 1 2 3 4 5 6 7 8 9
- cscでコンパイルしたアセンブリ、RedHat Linux上のMonoで動作OK
- mcsでコンパイルしたアセンブリ、Windows XP上の.NET Frameworkで動作OK
環境に依存する処理も無いので、全く同じ結果が出力されています。
System.IO名前空間
続いて、System.IO名前空間に存在するクラスを利用してみます。
using System;
using System.IO;
namespace SamtaMarta.Samples.Mono.Compatibility
{
class SystemIO
{
static void Main(string[] args)
{
// 論理ドライブ一覧の表示
foreach ( string drive in Environment.GetLogicalDrives() )
{
Console.Write( "{0}, ", drive );
}
Console.WriteLine();
Console.WriteLine();
// ファイルの読み書き
Console.WriteLine( "File IO" );
FileStream stream = null;
StreamWriter writer = null;
StreamReader reader = null;
try
{
stream = new FileStream( "test.txt", FileMode.Create, FileAccess.ReadWrite, FileShare.None );
writer = new StreamWriter( stream );
writer.WriteLine( "Hello mono." );
writer.WriteLine( "writing text file" );
writer.WriteLine( stream.Name );
writer.Flush();
stream.Seek( 0, SeekOrigin.Begin );
reader = new StreamReader( stream );
while ( reader.Peek() != -1 )
{
Console.WriteLine( reader.ReadLine() );
}
}
finally
{
if ( stream != null ) stream.Close();
}
Console.WriteLine();
// FileInfoクラス
FileInfo file = new FileInfo( "test.txt" );
Console.WriteLine( "FullName: {0}", file.FullName );
Console.WriteLine( "Attributes: {0}", file.Attributes.ToString() );
Console.WriteLine( "CreationTime: {0}", file.CreationTime );
Console.WriteLine( "LastWriteTime: {0}", file.LastWriteTime );
Console.WriteLine( "LastAccessTime: {0}", file.LastAccessTime );
file.CopyTo( "../test.txt", true );
if ( File.Exists( "../test.txt" ) ) Console.WriteLine( "File copyed." );
file.Delete();
if ( !File.Exists( "test.txt" ) ) Console.WriteLine( "File deleted." );
Console.WriteLine();
// DirectoryInfoクラス
DirectoryInfo dir = file.Directory;
Console.WriteLine( "FullName: {0}", dir.FullName );
Console.WriteLine( "Attributes: {0}", dir.Attributes.ToString() );
Console.WriteLine( "CreationTime: {0}", dir.CreationTime );
Console.WriteLine( "LastWriteTime: {0}", dir.LastWriteTime );
Console.WriteLine( "LastAccessTime: {0}", dir.LastAccessTime );
Console.WriteLine( "Parent: {0}", dir.Parent.FullName );
Console.WriteLine( "Root: {0}", dir.Root.FullName );
Console.WriteLine();
foreach ( FileSystemInfo info in dir.GetFileSystemInfos() )
{
Console.WriteLine( info.FullName );
}
Console.WriteLine();
// Pathクラス
Console.WriteLine( "AltDirectorySeparatorChar: {0}", Path.AltDirectorySeparatorChar );
Console.WriteLine( "DirectorySeparatorChar: {0}", Path.DirectorySeparatorChar );
Console.WriteLine( "PathSeparator: {0}", Path.PathSeparator );
Console.WriteLine( "VolumeSeparatorChar: {0}", Path.VolumeSeparatorChar );
Console.Write( "InvalidPathChars: " );
foreach ( char invalidPathChar in Path.InvalidPathChars )
{
Console.Write( "{0} ", invalidPathChar );
}
Console.WriteLine();
}
}
}
/, /boot, /home, /tmp, /usr, /usr/local, /var, File IO Hello mono. writing text file test.txt FullName: /home/santamarta/programming_cs/MonoCompatibility/System.IO/test.txt Attributes: Archive CreationTime: 2004/07/25 2:04:42 LastWriteTime: 2004/07/25 2:04:42 LastAccessTime: 2004/07/25 2:04:42 File copyed. File deleted. FullName: /home/santamarta/programming_cs/MonoCompatibility/System.IO Attributes: Directory CreationTime: 2004/07/25 2:04:42 LastWriteTime: 2004/07/25 2:04:42 LastAccessTime: 2004/07/25 2:04:42 Parent: /home/santamarta/programming_cs/MonoCompatibility Root: / /home/santamarta/programming_cs/MonoCompatibility/System.IO/SystemIO.cs /home/santamarta/programming_cs/MonoCompatibility/System.IO/SystemIO.cs~ /home/santamarta/programming_cs/MonoCompatibility/System.IO/SystemIO.exe /home/santamarta/programming_cs/MonoCompatibility/System.IO/SystemIO.txt AltDirectorySeparatorChar: \ DirectorySeparatorChar: / PathSeparator: : VolumeSeparatorChar: / InvalidPathChars:
A:\, C:\, D:\, E:\, F:\, G:\, H:\, I:\, J:\, K:\, L:\, File IO Hello mono. writing text file D:\Temporaly\MonoCompatibility\test.txt FullName: D:\Temporaly\MonoCompatibility\test.txt Attributes: Archive CreationTime: 2004/07/25 15:46:22 LastWriteTime: 2004/07/25 15:46:22 LastAccessTime: 2004/07/25 15:46:22 File copyed. File deleted. FullName: D:\Temporaly\MonoCompatibility Attributes: Directory CreationTime: 2004/07/24 19:13:44 LastWriteTime: 2004/07/25 15:46:22 LastAccessTime: 2004/07/25 15:46:22 Parent: D:\Temporaly Root: D:\ D:\Temporaly\MonoCompatibility\System.exe D:\Temporaly\MonoCompatibility\SystemCollection.exe D:\Temporaly\MonoCompatibility\SystemDrawing.exe D:\Temporaly\MonoCompatibility\SystemGlobalization.exe D:\Temporaly\MonoCompatibility\SystemIO.exe D:\Temporaly\MonoCompatibility\SystemRuntimeSerialization.exe D:\Temporaly\MonoCompatibility\SystemSecurityCryptography.exe D:\Temporaly\MonoCompatibility\SystemText.exe D:\Temporaly\MonoCompatibility\SystemThreading.exe D:\Temporaly\MonoCompatibility\SystemXml.exe AltDirectorySeparatorChar: / DirectorySeparatorChar: \ PathSeparator: ; VolumeSeparatorChar: : InvalidPathChars: " < > |
- cscでコンパイルしたアセンブリ、RedHat Linux上のMonoで動作OK
- mcsでコンパイルしたアセンブリ、Windows XP上の.NET Frameworkで動作OK
Windows とLinuxでファイルシステムが異なっているため、論理ドライブ名は各ディレクトリとして出力されています。 ファイルの属性などはWindowsのファイルシステムのものが表示されるようになっています。 DirectorySeparatorCharなどはシステムに依存した値になっています。 また、ファイルへの書き込み、移動・コピーなども正常に行われました。
System.Text名前空間
次はSystem.Text名前空間に存在するクラスを利用してみます。
using System;
using System.IO;
using System.Text;
namespace SamtaMarta.Samples.Mono.Compatibility
{
class SystemText
{
static void Main(string[] args)
{
// エンコーディング
Encoding[] encodings = new Encoding[] {
Encoding.Default,
Encoding.ASCII,
Encoding.UTF8,
Encoding.GetEncoding( "euc-jp" ),
Encoding.GetEncoding( "shift_jis" )
};
string[] fileNames = new string[] {
"default.txt",
"ascii.txt",
"utf8.txt",
"eucjp.txt",
"shiftjis.txt"
};
for ( int index = 0; index < fileNames.Length; index++ )
{
Encoding encoding = encodings[index];
string fileName = fileNames[index];
FileStream stream = null;
StreamWriter writer = null;
try
{
stream = new FileStream( fileName, FileMode.Create, FileAccess.Write, FileShare.None );
writer = new StreamWriter( stream, encoding );
writer.WriteLine( encoding.EncodingName );
writer.WriteLine( encoding.WebName );
writer.WriteLine( "1234567890" );
writer.WriteLine( "abcdefghij" );
writer.WriteLine( "あいう亜井宇" );
writer.Flush();
}
finally
{
if ( stream != null ) stream.Close();
}
}
}
}
}
Japanese (EUC) euc-jp 1234567890 abcdefghij あいう亜井宇
日本語 (シフト JIS) shift_jis 1234567890 abcdefghij あいう亜井宇
- cscでコンパイルしたアセンブリ、RedHat Linux上のMonoで動作OK
- mcsでコンパイルしたアセンブリ、Windows XP上の.NET Frameworkで動作OK
default.txt はシステムで用いられているエンコーディングで文字列を出力したファイルです。 LinuxではEUC-JP、WindowsではShiftJISを使用しているので上記の様な結果になっています。 また、ほかのエンコーディングで出力した結果もそれぞれ同じになっています。
System.Threading名前空間
続いて、System.Threading名前空間に存在するクラスを利用してみます。
using System;
using System.Threading;
namespace SamtaMarta.Samples.Mono.Compatibility
{
class SystemThreading
{
static void Main(string[] args)
{
Thread t = new Thread( new ThreadStart( CalculateA ) );
t.Start();
CalculateB();
Console.WriteLine( "Finished" );
}
static void CalculateA()
{
int count = 0;
while ( count++ < 10 )
{
Console.WriteLine( "CalculateA" );
Thread.Sleep( 100 );
}
}
static void CalculateB()
{
int count = 0;
while ( count++ < 5 )
{
Console.WriteLine( "CalculateB" );
Thread.Sleep( 250 );
}
}
}
}
CalculateA CalculateB CalculateA CalculateA CalculateB CalculateA CalculateA CalculateB CalculateA CalculateA CalculateA CalculateB CalculateA CalculateA CalculateB Finished
CalculateB CalculateA CalculateA CalculateA CalculateB CalculateA CalculateA CalculateB CalculateA CalculateA CalculateA CalculateB CalculateA CalculateA CalculateB Finished
- cscでコンパイルしたアセンブリ、RedHat Linux上のMonoで動作OK
- mcsでコンパイルしたアセンブリ、Windows XP上の.NET Frameworkで動作OK
実行順序はシステムの状態によって可変するので結果は異なっていますが、CalculateAとCalculateBはそれぞれ10回・5回ずつ呼び出されています。
System.Globalization名前空間
次はSystem.Globalozation名前空間に存在するクラスを利用してみます。
using System;
using System.Threading;
using System.Globalization;
namespace SamtaMarta.Samples.Mono.Compatibility
{
class SystemGlobalization
{
static void Main(string[] args)
{
// 現在のカルチャ
CultureInfo culture = CultureInfo.CurrentCulture;
Console.WriteLine( culture.Name );
Console.WriteLine( culture.DisplayName );
Console.WriteLine( culture.EnglishName );
Console.WriteLine( culture.NativeName );
Console.WriteLine( culture.ThreeLetterISOLanguageName );
Console.WriteLine( culture.Calendar );
Console.WriteLine( culture.TextInfo.ANSICodePage );
Console.WriteLine( culture.NumberFormat.CurrencySymbol );
Console.WriteLine();
// 現在のスレッドのカルチャ
Console.WriteLine( "CurrentCulture: {0}", CultureInfo.CurrentCulture.NativeName );
Console.WriteLine( "{0:C}", 123456.789 );
Console.WriteLine( "{0}", DateTime.Now );
Console.WriteLine();
// 現在のスレッドのカルチャを変更
Thread.CurrentThread.CurrentCulture = new CultureInfo( "en-US" );
Console.WriteLine( "CurrentCulture: {0}", CultureInfo.CurrentCulture.NativeName );
Console.WriteLine( "{0:C}", 123456.789 );
Console.WriteLine( "{0}", DateTime.Now );
Console.WriteLine();
// 現在のスレッドの暦を変更
Thread.CurrentThread.CurrentCulture = new CultureInfo( "ja-JP" );
Console.WriteLine( "{0}", DateTime.Now );
Thread.CurrentThread.CurrentCulture.DateTimeFormat.Calendar = new JapaneseCalendar();
Console.WriteLine( "{0}", DateTime.Now );
Console.WriteLine();
// インストールされているカルチャ
foreach ( CultureInfo cul in CultureInfo.GetCultures( CultureTypes.AllCultures ) )
{
Console.WriteLine( cul.Name + ", " + cul.NativeName );
}
}
}
}
ja-JP Japanese (Japan) Japanese (Japan) 日本語 (日本) jpn System.Globalization.GregorianCalendar 0 \ CurrentCulture: 日本語 (日本) \123,457 2004/07/25 2:01:28 CurrentCulture: English (United States) $123,456.79 7/25/2004 2:01:28 AM 2004/07/25 2:01:28 0016/07/25 2:01:28 ar, ??????? bg, Български ca, catala cs, ?e?tina da, Dansk de, Deutsch el, Ελληνικ? en, English es, espanol fi, suomi fr, francais he, ????? hu, magyar is, islenska it, italiano ja, 日本語 ko, ??? nl, Nederlands pl, polski pt, portugues ro, Roman? ru, Русский hr, hrvatski sk, slovensky sq, shqipe sv, svenska th, ??? tr, Turkce id, Bahasa Indonesia uk, Укра?нська be, Беларуск? sl, Sloven??ina et, Eesti lv, latvie?u lt, Lietuvi? fa, ????? vi, Ti?ng Vi?t hy, ??????? eu, euskara mk, македонски af, Afrikaanse fo, foroyskt hi, ????? sw, Kiswahili gu, ??????? ta, ????? te, ?????? kn, ????? mr, ????? gl, galego kok, ?????? bg-BG, Български (България) ca-ES, catala (Espanya) cs-CZ, ?e?tina (?eska republika) da-DK, Dansk (Danmark) de-DE, Deutsch (Deutschland) el-GR, Ελληνικ? (Ελλ?δα) en-US, English (United States) fi-FI, suomi (Suomi) fr-FR, francais (France) he-IL, ????? (?????) hu-HU, magyar (Magyarorszag) is-IS, islenska (Island) it-IT, italiano (Italia) ja-JP, 日本語 (日本) ko-KR, ??? (????) nl-NL, Nederlands (Nederland) pl-PL, polski (Polska) pt-BR, portugues (Brasil) ro-RO, Roman? (Romania) ru-RU, Русский (Россия) hr-HR, hrvatski (Hrvatska) sk-SK, slovensky (Slovenska republika) sq-AL, shqipe (Shqiperia) sv-SE, svenska (Sverige) th-TH, ??? (?????????) tr-TR, Turkce (Turkiye) id-ID, Bahasa Indonesia (Indonesia) uk-UA, Укра?нська (Укра?на) be-BY, Беларуск? (Беларусь) sl-SI, Sloven??ina (Slovenija) et-EE, Eesti (Eesti) lv-LV, latvie?u (Latvija) lt-LT, Lietuvi? (Lietuva) fa-IR, ????? (?????) vi-VN, Ti?ng Vi?t (Vi?t Nam) hy-AM, ??????? (????????? ??????????????) hy-AM, ??????? (????????? ??????????????) eu-ES, euskara (Espainia) mk-MK, македонски (Македони?а) af-ZA, Afrikaanse (Suid-Afrika) fo-FO, foroyskt (Foroyar) hi-IN, ????? (????) sw-KE, Kiswahili (Kenya) gu-IN, ??????? (????) ta-IN, ????? (???????) te-IN, ?????? (???? ????) kn-IN, ????? (????) mr-IN, ????? (????) gl-ES, galego (Espana) kok-IN, ?????? (????) ar-IQ, ??????? (??????) de-CH, Deutsch (Schweiz) en-GB, English (United Kingdom) es-MX, espanol (Mexico) fr-BE, francais (Belgique) it-CH, italiano (Svizzera) nl-BE, Nederlands (Belgie) pt-PT, portugues (Portugal) sv-FI, svenska (Finland) ar-EG, ??????? (???) de-AT, Deutsch (Osterreich) en-AU, English (Australia) es-ES, espanol (Espana) fr-CA, francais (Canada) ar-LY, ??????? (?????) de-LU, Deutsch (Luxemburg) en-CA, English (Canada) es-GT, espanol (Guatemala) fr-CH, francais (Suisse) ar-DZ, ??????? (???????) en-NZ, English (New Zealand) es-CR, espanol (Costa Rica) fr-LU, francais (Luxembourg) ar-MA, ??????? (??????) en-IE, English (Ireland) es-PA, espanol (Panama) ar-TN, ??????? (????) en-ZA, English (South Africa) es-DO, espanol (Republica Dominicana) ar-OM, ??????? (????) es-VE, espanol (Venezuela) ar-YE, ??????? (?????) es-CO, espanol (Colombia) ar-SY, ??????? (?????) es-PE, espanol (Peru) ar-JO, ??????? (??????) es-AR, espanol (Argentina) ar-LB, ??????? (?????) en-ZW, English (Zimbabwe) es-EC, espanol (Ecuador) ar-KW, ??????? (??????) en-PH, English (Philippines) es-CL, espanol (Chile) ar-AE, ??????? (???????? ??????? ???????) es-UY, espanol (Uruguay) ar-BH, ??????? (???????) es-PY, espanol (Paraguay) ar-QA, ??????? (???) es-BO, espanol (Bolivia) es-SV, espanol (El Salvador) es-HN, espanol (Honduras) es-NI, espanol (Nicaragua) es-PR, espanol (Puerto Rico)
ja-JP 日本語 (日本) Japanese (Japan) 日本語 (日本) jpn System.Globalization.GregorianCalendar 932 \ CurrentCulture: 日本語 (日本) \123,457 2004/07/25 16:10:28 CurrentCulture: English (United States) $123,456.79 7/25/2004 4:10:28 PM 2004/07/25 16:10:28 平成 16/7/25 16:10:28 ar, ??????? ar-SA, ??????? (??????? ??????? ????????) ar-IQ, ??????? (??????) ar-EG, ??????? (???) ar-LY, ??????? (?????) ar-DZ, ??????? (???????) ar-MA, ??????? (??????? ????????) ar-TN, ??????? (????) ar-OM, ??????? (????) ar-YE, ??????? (?????) ar-SY, ??????? (?????) ar-JO, ??????? (??????) ar-LB, ??????? (?????) ar-KW, ??????? (??????) ar-AE, ??????? (???????? ??????? ???????) ar-BH, ??????? (???????) ar-QA, ??????? (???) bg, български bg-BG, български (България) ca, catala ca-ES, catala (catala) zh-CHS, 中文(?体) zh-TW, 中文(繁體) (台灣) zh-CN, 中文(?体) (中?人民共和国) zh-HK, 中文(繁體) (香港特?行政区) zh-SG, 中文(?体) (新加坡) zh-MO, 中文(?体) (澳?特?行政区) zh-CHT, 中文(繁體) cs, ?e?tina cs-CZ, ?e?tina (?eska?republika) da, dansk da-DK, dansk (Danmark) de, Deutsch de-DE, Deutsch (Deutschland) de-CH, Deutsch (Schweiz) de-AT, Deutsch (Osterreich) de-LU, Deutsch (Luxemburg) de-LI, Deutsch (Liechtenstein) el, ελληνικ? el-GR, ελληνικ? (Ελλ?δα) en, English en-US, English (United States) en-GB, English (United Kingdom) en-AU, English (Australia) en-CA, English (Canada) en-NZ, English (New Zealand) en-IE, English (Eire) en-ZA, English (South Africa) en-JM, English (Jamaica) en-CB, English (Caribbean) en-BZ, English (Belize) en-TT, English (Trinidad y Tobago) en-ZW, English (Zimbabwe) en-PH, English (Philippines) es, espanol es-MX, Espanol (Mexico) es-ES, espanol (Espana) es-GT, Espanol (Guatemala) es-CR, Espanol (Costa Rica) es-PA, Espanol (Panama) es-DO, Espanol (Republica Dominicana) es-VE, Espanol (Republica Bolivariana de Venezuela) es-CO, Espanol (Colombia) es-PE, Espanol (Peru) es-AR, Espanol (Argentina) es-EC, Espanol (Ecuador) es-CL, Espanol (Chile) es-UY, Espanol (Uruguay) es-PY, Espanol (Paraguay) es-BO, Espanol (Bolivia) es-SV, Espanol (El Salvador) es-HN, Espanol (Honduras) es-NI, Espanol (Nicaragua) es-PR, Espanol (Puerto Rico) fi, suomi fi-FI, suomi (Suomi) fr, francais fr-FR, francais (France) fr-BE, francais (Belgique) fr-CA, francais (Canada) fr-CH, francais (Suisse) fr-LU, francais (Luxembourg) fr-MC, francais (Principaute de Monaco) he, ????? he-IL, ????? (?????) hu, Magyar hu-HU, Magyar (Magyarorszag) is, islenska is-IS, islenska (Island) it, italiano it-IT, italiano (Italia) it-CH, italiano (Svizzera) ja, 日本語 ja-JP, 日本語 (日本) ko, ??? ko-KR, ??? (????) nl, Nederlands nl-NL, Nederlands (Nederland) nl-BE, Nederlands (Belgie) no, norsk nb-NO, norsk (bokmal) (Norge) nn-NO, norsk (nynorsk) (Noreg) pl, polski pl-PL, polski (Polska) pt, Portugues pt-BR, Portugues (Brasil) pt-PT, portugues (Portugal) ro, roman? ro-RO, roman? (Romania) ru, русский ru-RU, русский (Россия) hr, hrvatski hr-HR, hrvatski (Hrvatska) sr-SP-Latn, srpski (Srbija) sr-SP-Cyrl, српски (?угослави?а) sk, sloven?ina sk-SK, sloven?ina (Slovenska republika) sq, shqipe sq-AL, shqipe (Shqiperia) sv, svenska sv-SE, svenska (Sverige) sv-FI, svenska (Finland) th, ??? th-TH, ??? (???) tr, Turkce tr-TR, Turkce (Turkiye) ur, ????? ur-PK, ????? (???????) id, Bahasa Indonesia id-ID, Bahasa Indonesia (Indonesia) uk, укра?ньска uk-UA, укра?ньска (Укра?на) be, Беларуск? be-BY, Беларуск? (Беларусь) sl, slovenski sl-SI, slovenski (Slovenija) et, eesti et-EE, eesti (Eesti) lv, latvie?u lv-LV, latvie?u (Latvija) lt, lietuvi? lt-LT, lietuvi? (Lietuva) fa, ????? fa-IR, ????? (?????) vi, Tie?ng Vie?t Nam vi-VN, Tie?ng Vie?t Nam (Vie?t Nam) hy, ??????? hy-AM, ??????? (????????) az, Az?rbaycan-?l? az-AZ-Latn, Az?rbaycan-?l? (Az?rbaycanca) az-AZ-Cyrl, Аз?рба??ан (Аз?рба??ан) eu, euskara eu-ES, euskara (euskara) mk, македонски ?азик mk-MK, македонски ?азик (Македони?а) af, Afrikaans af-ZA, Afrikaans (Suid Afrika) ka, ??????? ka-GE, ??????? (??????????) fo, foroyskt fo-FO, foroyskt (Foroyar) hi, ????? hi-IN, ????? (????) ms, Bahasa Malaysia ms-MY, Bahasa Malaysia (Malaysia) ms-BN, Bahasa Malaysia (Brunei Darussalam) kk, ?азащb kk-KZ, ?аза? (?аза?стан) ky, Кыргыз ky-KZ, Кыргыз (Кыргызстан) sw, Kiswahili sw-KE, Kiswahili (Kenya) uz, U'zbek uz-UZ-Latn, U'zbek (U'zbekiston Respublikasi) uz-UZ-Cyrl, ?збек (?збекистон) tt, Татар tt-RU, Татар (Россия) pa, ?????? pa-IN, ?????? (????) gu, ??????? gu-IN, ??????? (????) ta, ????? ta-IN, ????? (???????) te, ?????? te-IN, ?????? (?????????) kn, ????? kn-IN, ????? (????) mr, ????? mr-IN, ????? (????) sa, ??????? sa-IN, ??????? (??????) mn, Монгол?хэл mn-MN, Монгол?хэл (Монгол?улс) gl, galego gl-ES, galego (galego) kok, ?????? kok-IN, ?????? (????) syr, ?????? syr-SY, ?????? (?????) div, ?????????? div-MV, ?????????? (?????? ??????) , Invariant Language (Invariant Country)
- cscでコンパイルしたアセンブリ、RedHat Linux上のMonoで動作OK
- mcsでコンパイルしたアセンブリ、Windows XP上の.NET Frameworkで動作OK
現在のスレッドのカルチャを取得・設定したり、暦を変更したりすることも問題なく出来ています。 表示されたカルチャセットに相違があるのは、カルチャセットがシステムに存在するか否かによるからです。
System.Security.Cryptography名前空間
続いては、System.Security.Cryptography名前空間に存在するクラスを利用してDESアルゴリズムによる暗号化・復号化を試みます。
using System;
using System.IO;
using System.Text;
using System.Security;
using System.Security.Cryptography;
namespace SamtaMarta.Samples.Mono.Compatibility
{
class SystemSecurityCryptography
{
static void Main(string[] args)
{
// 鍵(8バイト)
byte[] key = Encoding.ASCII.GetBytes( "password" );
// 原文
MemoryStream originalStream = new MemoryStream();
StreamWriter writer = new StreamWriter( originalStream, Encoding.Unicode );
writer.WriteLine( "0123456789" );
writer.WriteLine( "ABCDEFG" );
writer.WriteLine( "あいうえお" );
writer.WriteLine( "アイウエオ" );
writer.WriteLine( "亜井宇江尾" );
writer.Flush();
Output( originalStream.ToArray() );
// 暗号化
MemoryStream encryptedStream = new MemoryStream( 128 );
EncryptByDES( originalStream.ToArray(), encryptedStream, key );
Output( encryptedStream.ToArray() );
// 復号化
MemoryStream decryptedStream = new MemoryStream( 128 );
DecryptByDES( encryptedStream.ToArray(), decryptedStream, key );
Output( decryptedStream.ToArray() );
}
// 暗号化
static void EncryptByDES( byte[] original, Stream encryptedStream, byte[] encryptionKey )
{
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
des.Key = encryptionKey;
des.IV = encryptionKey;
CryptoStream cryptoStream = null;
try
{
cryptoStream = new CryptoStream( encryptedStream, des.CreateEncryptor(), CryptoStreamMode.Write);
cryptoStream.Write( original, 0, original.Length );
}
finally
{
if ( cryptoStream != null ) cryptoStream.Close();
}
}
// 復号化
static void DecryptByDES( byte[] encrypted, Stream decryptedStream, byte[] decryptionKey )
{
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
des.Key = decryptionKey;
des.IV = decryptionKey;
CryptoStream cryptoStream = null;
try
{
cryptoStream = new CryptoStream( decryptedStream, des.CreateDecryptor(), CryptoStreamMode.Write);
cryptoStream.Write( encrypted, 0, encrypted.Length );
}
finally
{
if ( cryptoStream != null ) cryptoStream.Close();
}
}
// 出力
static void Output( byte[] text )
{
MemoryStream stream = new MemoryStream( text );
StreamReader reader = new StreamReader( stream, Encoding.Unicode );
Console.WriteLine( reader.ReadToEnd() );
Console.WriteLine();
reader.Close();
}
}
}
0123456789 ABCDEFG あいうえお アイウエオ 亜井宇江尾 ???????????????????鮫??幹??????????????N 0123456789 ABCDEFG あいうえお アイウエオ 亜井宇江尾
0123456789 ABCDEFG あいうえお アイウエオ 亜井宇江尾 ???????????梅?冉??颯?????????蹇?元?????????ノ????? 0123456789 ABCDEFG あいうえお アイウエオ 亜井宇江尾
- cscでコンパイルしたアセンブリ、RedHat Linux上のMonoで動作OK
- mcsでコンパイルしたアセンブリ、Windows XP上の.NET Frameworkで動作OK
暗号化・復号化ともに問題なく動作しています。
System.Runtime.Serialization名前空間
System.Runtime.Serialization名前空間に存在するクラスを用いて、バイナリシリアル化を実行してみます。
using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
namespace SamtaMarta.Samples.Mono.Compatibility
{
class SystemRuntimeSerialization
{
static void Main(string[] args)
{
SerializationTarget s = new SerializationTarget( "test", 12345, 3.1415, 2.718m );
Console.WriteLine( s );
Console.WriteLine();
byte[] serialized = Serialize( s );
Dump( serialized );
Console.WriteLine();
Console.WriteLine( Deserialize( serialized ) );
Console.WriteLine();
}
// シリアル化
static byte[] Serialize( SerializationTarget s )
{
MemoryStream stream = new MemoryStream();
BinaryFormatter formatter = new BinaryFormatter( null, new StreamingContext( StreamingContextStates.All ) );
formatter.Serialize( stream, s );
stream.Close();
return stream.ToArray();
}
// 逆シリアル化
static SerializationTarget Deserialize( byte[] serialized )
{
SerializationTarget s;
MemoryStream stream = new MemoryStream( serialized );
BinaryFormatter formatter = new BinaryFormatter( null, new StreamingContext( StreamingContextStates.All ) );
s = formatter.Deserialize( stream ) as SerializationTarget;
stream.Close();
return s;
}
// ダンプ
static void Dump( byte[] arr )
{
int pos = 0;
int len = arr.Length;
do
{
int i;
int c;
if ( len <= pos + 0x10 )
{
c = len - pos;
}
else
{
c = 0x10;
}
for ( i = 0; i <= c - 1; i += 1 )
{
Console.Write( "{0:X2} ", arr[pos + i]);
}
Console.WriteLine();
pos += 0x10;
} while ( !( ( len <= pos ) ) );
}
}
/// <summary>
/// シリアル化の対象となるクラス
/// </summary>
[Serializable()]
class SerializationTarget : ISerializable
{
private string stringValue;
private int intValue;
private double doubleValue;
private decimal decimalValue;
public SerializationTarget( string stringValue, int intValue, double doubleValue, decimal decimalValue )
{
this.stringValue = stringValue;
this.intValue = intValue;
this.doubleValue = doubleValue;
this.decimalValue = decimalValue;
}
// 逆シリアル化に必要な暗黙のコンストラクタ
private SerializationTarget( SerializationInfo info, StreamingContext context )
{
this.stringValue = info.GetString( "String" );
this.intValue = info.GetInt32( "Int32" );
this.decimalValue = info.GetDecimal( "Decimal" );
}
// GetObjectData()メソッドの実装
public void GetObjectData( SerializationInfo info, StreamingContext context )
{
info.AddValue( "String", this.stringValue );
info.AddValue( "Int32", this.intValue );
info.AddValue( "Decimal", this.decimalValue );
// doubleValueはシリアル化しない
}
public override string ToString()
{
return String.Format( "{{stringValue:{0}, intValue:{1}, doubleValue:{2}, decimalValue:{3}}}", stringValue, intValue, doubleValue, decimalValue );
}
}
}
{stringValue:test, intValue:12345, doubleValue:3.1415, decimalValue:2.718} 00 01 00 00 00 FF FF FF FF 01 00 00 00 00 00 00 00 0C 02 00 00 00 51 53 79 73 74 65 6D 52 75 6E 74 69 6D 65 53 65 72 69 61 6C 69 7A 61 74 69 6F 6E 2C 20 56 65 72 73 69 6F 6E 3D 30 2E 30 2E 30 2E 30 2C 20 43 75 6C 74 75 72 65 3D 6E 65 75 74 72 61 6C 2C 20 50 75 62 6C 69 63 4B 65 79 54 6F 6B 65 6E 3D 6E 75 6C 6C 05 01 00 00 00 39 53 61 6D 74 61 4D 61 72 74 61 2E 53 61 6D 70 6C 65 73 2E 4D 6F 6E 6F 2E 43 6F 6D 70 61 74 69 62 69 6C 69 74 79 2E 53 65 72 69 61 6C 69 7A 61 74 69 6F 6E 54 61 72 67 65 74 03 00 00 00 06 53 74 72 69 6E 67 05 49 6E 74 33 32 07 44 65 63 69 6D 61 6C 01 00 00 08 05 02 00 00 00 06 03 00 00 00 04 74 65 73 74 39 30 00 00 05 32 2E 37 31 38 0B {stringValue:test, intValue:12345, doubleValue:0, decimalValue:2.718}
{stringValue:test, intValue:12345, doubleValue:3.1415, decimalValue:2.718} 00 01 00 00 00 FF FF FF FF 01 00 00 00 00 00 00 00 0C 02 00 00 00 51 53 79 73 74 65 6D 52 75 6E 74 69 6D 65 53 65 72 69 61 6C 69 7A 61 74 69 6F 6E 2C 20 56 65 72 73 69 6F 6E 3D 30 2E 30 2E 30 2E 30 2C 20 43 75 6C 74 75 72 65 3D 6E 65 75 74 72 61 6C 2C 20 50 75 62 6C 69 63 4B 65 79 54 6F 6B 65 6E 3D 6E 75 6C 6C 05 01 00 00 00 39 53 61 6D 74 61 4D 61 72 74 61 2E 53 61 6D 70 6C 65 73 2E 4D 6F 6E 6F 2E 43 6F 6D 70 61 74 69 62 69 6C 69 74 79 2E 53 65 72 69 61 6C 69 7A 61 74 69 6F 6E 54 61 72 67 65 74 03 00 00 00 06 53 74 72 69 6E 67 05 49 6E 74 33 32 07 44 65 63 69 6D 61 6C 01 00 00 08 05 02 00 00 00 06 03 00 00 00 04 74 65 73 74 39 30 00 00 05 32 2E 37 31 38 0B {stringValue:test, intValue:12345, doubleValue:0, decimalValue:2.718}
- cscでコンパイルしたアセンブリ、RedHat Linux上のMonoで動作OK
- mcsでコンパイルしたアセンブリ、Windows XP上の.NET Frameworkで動作OK
シリアル化・逆シリアル化は正常に行われています。 ダンプ結果も同じ事から、Monoでシリアル化したデータを.NET Frameworkで逆シリアル化する事、またその逆も可能であると考えられます。
System.Xml名前空間
最後にSystem.Xml名前空間に存在するクラスを利用して簡単なXML文書(RSS)を作成してみます。
using System;
using System.Xml;
namespace SamtaMarta.Samples.Mono.Compatibility
{
class SystemXml
{
static void Main(string[] args)
{
XmlDocument document = new XmlDocument();
// ?xml
document.AppendChild( document.CreateXmlDeclaration( "1.0", "utf-8", "" ) );
// rss
XmlElement elementRss = document.CreateElement( "rss" );
elementRss.SetAttribute( "version", "2.0" );
document.AppendChild( elementRss );
// rss/channel
XmlElement elementRssChannel = document.CreateElement( "channel" );
elementRss.AppendChild( elementRssChannel );
// rss/channel/title
XmlElement elementRssChannelTitle = document.CreateElement( "title" );
elementRssChannelTitle.AppendChild( document.CreateTextNode( ".NETでいきまっしょい!" ) );
elementRssChannel.AppendChild( elementRssChannelTitle );
// rss/channel/link
XmlElement elementRssChannelLink = document.CreateElement( "link" );
elementRssChannelLink.AppendChild( document.CreateTextNode( "http://santamartadotnet.hp.infoseek.co.jp/" ) );
elementRssChannel.AppendChild( elementRssChannelLink );
// rss/channel/webMaster
XmlElement elementRssChannelWebmaster = document.CreateElement( "webMaster" );
elementRssChannelWebmaster.AppendChild( document.CreateTextNode( "santamartaofthepeace@hotmail.com" ) );
elementRssChannel.AppendChild( elementRssChannelWebmaster );
// rss/item
XmlElement elementRssItem = document.CreateElement( "item" );
elementRss.AppendChild( elementRssItem );
// rss/item/title
XmlElement elementRssItemTitle = document.CreateElement( "title" );
elementRssItemTitle.AppendChild( document.CreateTextNode( "samlpe RSS item" ) );
elementRssItem.AppendChild( elementRssItemTitle );
// rss/item/link
XmlElement elementRssItemLink = document.CreateElement( "link" );
elementRssItemLink.AppendChild( document.CreateTextNode( "http://santamartadotnet.hp.infoseek.co.jp/" ) );
elementRssItem.AppendChild( elementRssItemLink );
// rss/item/pubDate
XmlElement elementRssItemPubdate = document.CreateElement( "pubDate" );
elementRssItemPubdate.AppendChild( document.CreateTextNode( DateTime.UtcNow.ToString("r", System.Globalization.CultureInfo.InvariantCulture.DateTimeFormat) ) );
elementRssItem.AppendChild( elementRssItemPubdate );
// ファイルに保存
document.Save( "rss.xml" );
}
}
}
<?xml version="1.0" encoding="utf-8"?> <rss version="2.0"> <channel> <title>.NETでいきまっしょい!</title> <link>http://santamartadotnet.hp.infoseek.co.jp/</link> <webMaster>santamartaofthepeace@hotmail.com</webMaster> </channel> <item> <title>samlpe RSS item</title> <link>http://santamartadotnet.hp.infoseek.co.jp/</link> <pubDate>Sat, 24 Jul 2004 17:10:03 GMT</pubDate> </item> </rss>
<?xml version="1.0" encoding="utf-8"?> <rss version="2.0"> <channel> <title>.NETでいきまっしょい!</title> <link>http://santamartadotnet.hp.infoseek.co.jp/</link> <webMaster>santamartaofthepeace@hotmail.com</webMaster> </channel> <item> <title>samlpe RSS item</title> <link>http://santamartadotnet.hp.infoseek.co.jp/</link> <pubDate>Sun, 25 Jul 2004 07:25:44 GMT</pubDate> </item> </rss>
- cscでコンパイルしたアセンブリ、RedHat Linux上のMonoで動作OK
- mcsでコンパイルしたアセンブリ、Windows XP上の.NET Frameworkで動作OK
双方ともに全く問題なく動作しています。
まとめ
今回はコアライブラリに含まれる基本的なクラスだけを抜粋して検証してきましたが、システムに依存する部分を除けばその全てについて.NET Frameworkと完全に同じ結果が得られる事が分かりました。 他のクラスについてもほぼ同様だと考えられます。 また、mcsでコンパイルしたアセンブリもcscでコンパイルしたアセンブリも、Monoおよび.NET Frameworkのどちらでも動作することが確認できました。 このことからも分かるとおり、今回調査したコアライブラリのクラスだけについて見れば、 Monoは.NET Frameworkと完全な互換性を持っているということが言えると思います。