Java と .NET Framework の違い

自分が知りえた違いをいくつか列挙しておく

---
### ストリーム

JavaはInputStream([java.io.InputStream](http://docs.oracle.com/javase/jp/6/api/java/io/InputStream.html))とOutputStream([java.io.OutputStream](http://docs.oracle.com/javase/jp/6/api/org/omg/CORBA/portable/OutputStream.html))というように、入力と出力で二つに分かれている

一方、.NET Framework では、Stream([System.IO.Stream](https://msdn.microsoft.com/ja-jp/library/system.io.stream(v=vs.110).aspx))というように、入出力で一本化している

しかし、

> // C# のサンプルコード
> DeflateStream compressionStream = ne
w DeflateStream(compressedFileStream, CompressionMode.Compress));

みたいにすると、出力系(write)はよいが、入力(read)しようとするとエラーになるので、必ず入出力できると思っていると痛い目にあう

---
### ストリームの終了

javaは「-1」
.NET Frameworkは「0」。(readByte()メソッドのみ「-1」)

---
### ストリーム(CopyTo)

.NET Framework4以降の CopyTo(distStream)メソッドは便利

---
### フィルタストリーム

Javaにはフィルタストリームという概念のクラス([java.io.FilterInputStream](http://docs.oracle.com/javase/jp/6/api/java/io/FilterInputStream.html)と[java.io.FilterOutputStream](http://docs.oracle.com/javase/jp/6/api/java/io/FilterOutputStream.html))があるので、これを継承して作る

.NET Framework にはそういうものはなく、Streamを継承して作る

---
### メモリストリーム

Javaは[java.io.ByteArrayInputStream](http://docs.oracle.com/javase/jp/6/api/java/io/ByteArrayInputStream.html)と[java.io.ByteArrayOutputStream](http://docs.oracle.com/javase/jp/6/api/java/io/ByteArrayOutputStream.html)

.NET Frameworkは[System.IO.MemoryStream](https://msdn.microsoft.com/ja-jp/library/system.io.memorystream(v=vs.110).aspx)

Java/.NET Framework共に、データがちょろちょろとリアルタイムに発生するような場面では使いづらい → read() が終了してしまう。

---
### メモリストリーム(ちょろちょろ対応)

Java は[java.io.PipedInputStream](http://docs.oracle.com/javase/jp/6/api/java/io/PipedInputStream.html)と[java.io.PipedOutputStream](http://docs.oracle.com/javase/jp/6/api/java/io/PipedOutputStream.html)を使えばいい

.NET Frameworkにはこのようなクラスを知らない
あえて言えば、匿名パイプのクラス([System.IO.Pipes.AnonymousPipeClientStream](https://msdn.microsoft.com/ja-jp/library/system.io.pipes.anonymouspipeclientstream(v=vs.110).aspx)と[System.IO.Pipes.AnonymousPipeServerStream](https://msdn.microsoft.com/ja-jp/library/system.io.pipes.anonymouspipeserverstream(v=vs.110).aspx))か

---
### 暗号/ハッシュなど(Java)

Javaは細かい

- 暗号
 - [javax.crypto.CipherInputStream](http://docs.oracle.com/javase/jp/6/api/javax/crypto/CipherInputStream.html)と[javax.crypto.CipherOutputStream](http://docs.oracle.com/javase/jp/6/api/javax/crypto/CipherOutputStream.html)
 - それらの実体となる[javax.crypto.Cipher](http://docs.oracle.com/javase/jp/6/api/javax/crypto/Cipher.html)
- ハッシュ
 - [java.security.DigestInputStream](http://docs.oracle.com/javase/jp/6/api/java/security/DigestInputStream.html)と[java.security.DigestOutputStream](http://docs.oracle.com/javase/jp/6/api/java/security/DigestOutputStream.html)
 - それらの実体となる[java.security.MessageDigest](http://docs.oracle.com/javase/jp/6/api/java/security/MessageDigest.html)
- チェックサム
 - [java.util.zip.CheckedInputStream](http://docs.oracle.com/javase/jp/6/api/java/util/zip/CheckedInputStream.html)と[java.util.zip.CheckedOutputStream](http://docs.oracle.com/javase/jp/6/api/java/util/zip/CheckedOutputStream.html)
 - それらの実体となる[java.util.zip.Checksum](http://docs.oracle.com/javase/jp/6/api/java/util/zip/Checksum.html)
- MAC
 - 実体となる[javax.crypto.Mac](http://docs.oracle.com/javase/jp/6/api/javax/crypto/Mac.html)
 - ストリームはない。・・・という事で作ってみた([MacInputStream/MacOutputStream](http://rocketeer.dip.jp/sanaki/cgi-bin/jfree12.stm))

---
### 暗号/ハッシュなど(.NET Framework)

統一的に扱っている

ベースとなるクラス

- [System.Security.Cryptography.CryptoStream](https://msdn.microsoft.com/ja-jp/library/system.security.cryptography.cryptostream(v=vs.110).aspx)

上記のクラスに割り当てる[System.Security.Cryptography.ICryptoTransform](https://msdn.microsoft.com/ja-jp/library/system.security.cryptography.icryptotransform(v=vs.110).aspx)インターフェイスとして

- 暗号
 - [System.Security.Cryptography.SymmetricAlgorithm](https://msdn.microsoft.com/ja-jp/library/system.security.cryptography.symmetricalgorithm(v=vs.110).aspx)のCreateEncryptor/CreateDecryptor メソッド
- ハッシュ
 - ICryptoTransform を継承した[System.Security.Cryptography.HashAlgorithm](https://msdn.microsoft.com/ja-jp/library/system.security.cryptography.hashalgorithm(v=vs.110).aspx)

HMACは HashAlgorithm 下に

 - [System.Security.Cryptography.KeyedHashAlgorithm](https://msdn.microsoft.com/ja-jp/library/system.security.cryptography.keyedhashalgorithm(v=vs.110).aspx)

がある。

---
### 圧縮

Java/.NET Framework共にリアルタイムに圧縮する機能がなかったが、Java7より[java.util.zip.Deflater#SYNC_FLUSH] (http://docs.oracle.com/javase/jp/8/docs/api/java/util/zip/Deflater.html)が新設されて、リアルタイムなzlib圧縮が可能になった

.NET Framework の場合は、[zlib.NET.dll](http://www.componentace.com/zlib_.NET.htm)を使えばいいと思うよ。
[C#/.NET Frameworkで圧縮を同期的(リアルタイム)に行う方法](https://qiita.com/tomoki0sanaki/items/68b7ca38b8fefa199363)

---
### SSL

Javaは[java.net.Socket](http://docs.oracle.com/javase/jp/6/api/java/net/Socket.html)を継承した[javax.net.ssl.SSLSocket](http://docs.oracle.com/javase/jp/6/api/javax/net/ssl/SSLSocket.html)

.NET Frameworkは[System.IO.Stream](https://msdn.microsoft.com/ja-jp/library/system.io.stream(v=vs.110).aspx)を継承した[System.Net.Security.SslStream](https://msdn.microsoft.com/ja-jp/library/system.net.security.sslstream(v=vs.110).aspx)

.NET FrameworkがStreamを継承しているのに対して、JavaはInputStream/OutputStreamに分岐しているから!? Socketを継承している


---
### SSL オプション(Java)

Javaは多彩

- JavaVM としてサポートされているプロトコル/暗号スイート
 - getSupportedProtocols()
 - getSupportedCipherSuites()
- インスタンスで有効なものを設定/取得
- getEnabledProtocols()
- getEnabledCipherSuites()
- setEnabledProtocols(String[] protocols)
- setEnabledCipherSuites(String[] suites)

---
### SSL オプション(.NET Framework)

.NET Framework はプロトコル制御のみ!?

- [SslProtocol](https://msdn.microsoft.com/ja-jp/library/system.net.security.sslstream.sslprotocol(v=vs.110).aspx)

---
### Reader/Writer

Java/.NET Framework共に内部文字コードUTF16で統一している

Javaは基本的に実装ごとに用意している
AudioFileReader、FileReader、FilterReader、InputStreamReader、LineNumberReader、PipedReader、PushbackReader、Reader、XMLStreamReader....多すぎ

.NET Frameworkは、[System.IO.StreamReader](https://msdn.microsoft.com/ja-jp/library/system.io.streamreader(v=vs.110).aspx)と[System.IO.StreamWriter](https://msdn.microsoft.com/ja-jp/library/system.io.streamwriter(v=vs.110).aspx)に統一している感じ

---
### ReaderのReadToEnd()

[System.IO.StreamReader.ReadToEnd()](https://msdn.microsoft.com/ja-jp/library/system.io.streamreader.readtoend(v=vs.110).aspx)は便利。

VisualBASIC6.0(Scripting.FileSystemObject)のファイル操作の ReadAll() に近い。とても便利。

---
### マルチキャストUDP

.NET Framework/Java 共に、マルチキャストはUDPとして実装されている

JavaはUDPの実体である[java.net.DatagramSocket](http://docs.oracle.com/javase/jp/6/api/java/net/DatagramSocket.html)を継承した[java.net.MulticastSocket](http://docs.oracle.com/javase/jp/6/api/java/net/MulticastSocket.html)

.NET FrameworkはUDPの実体である[System.Net.Sockets.UdpClient](https://msdn.microsoft.com/ja-jp/library/system.net.sockets.udpclient(v=vs.110).aspx)そのもの

---
### サウンド

JavaではStreamを継承した[javax.sound.sampled.AudioInputStream](http://docs.oracle.com/javase/jp/6/api/javax/sound/sampled/AudioInputStream.html)なので、録音は簡単にできる。

出力(スピーカーへの音声再生)は、Stream ではないが、Streamを継承させるラッパーは簡単に作れるでしょうね

.NET Frameworkは Managed DirectX(MDX) か、3rd Party の [SlimDX](https://www.slimdx.org/) を使うしかないが結構コーディングは大変かも。

---
### Web(HttpClient)

Javaは[java.net.URLConnection](http://docs.oracle.com/javase/jp/6/api/java/net/URLConnection.html)を継承した[java.net.HttpURLConnection](http://docs.oracle.com/javase/jp/6/api/java/net/HttpURLConnection.html)「http専用」とその子供の[javax.net.ssl.HttpsURLConnection](http://docs.oracle.com/javase/jp/6/api/javax/net/ssl/HttpsURLConnection.html)「https用」

.NET Frameworkは[System.Net.WebRequest](https://msdn.microsoft.com/ja-jp/library/system.net.webrequest(v=vs.110).aspx)を継承した[System.Net.HttpWebRequest](https://msdn.microsoft.com/ja-jp/library/system.net.httpwebrequest(v=vs.110).aspx)「http/https兼用」

Androidはorg.apache.http.client.HttpClientクラス

---
### 型の種類

Javaはint,longなど基本的なもの(必要十分なものだけ)

.NET Frameworkは Int32,UInt32,,,など多彩

---
### byte型

Javaは-128～127  (JRuby/Jythonと相互変換する際には注意が必要)

.NET Frameworkは 0～255

個人的には、バイト型に負数とか意味分からん

---
### Staticメソッド

Javaはインスタンス化したオブジェクトの中にもstaticなメソッドが置ける → thisで呼べる

.NET Framework は thisでは呼べない

---
### スレッド

Javaはクラス自体を[java.lang.Thread](http://docs.oracle.com/javase/jp/6/api/java/lang/Thread.html)クラス([java.lang.Runnable](http://docs.oracle.com/javase/jp/6/api/java/lang/Runnable.html)インターフェイス)を継承して実装する
→ スレッドはクラス単位と言える

.NET Frameworkは、[System.Threading.Thread](https://msdn.microsoft.com/ja-jp/library/system.threading.thread(v=vs.110).aspx)にメソッドを登録する
→ スレッドはメソッド単位と言える

---
### ロック処理

Javaのロックは「synchronized」

.NET Framework のロックはいろいろ(Windowsの進化と共に...)

---
### Base64

JDK8より java.util.Base64

.NET Framework はいろんなところにBase64

---
### URLエンコード

JavaのURLエンコード([java.net.URLEncoder](http://docs.oracle.com/javase/jp/6/api/java/net/URLEncoder.html)と[java.net.URLDecoder](http://docs.oracle.com/javase/jp/6/api/java/net/URLDecoder.html))は対象が文字列
→ 使えない

---
### 文字列の比較

Javaの文字列比較はequals()メソッド

---
### switch文

Javaでは文字列で switch()できない。→ Java8で解消!?

---
### Zlibのリアルタイム圧縮

[C#/.NET Frameworkで圧縮を同期的(リアルタイム)に行う方法](https://qiita.com/tomoki0sanaki/items/68b7ca38b8fefa199363)

---
### XML の外部参照

Java は [javax.xml.parsers.DocumentBuilder#setEntityResolver()メソッド](https://docs.oracle.com/javase/jp/6/api/javax/xml/parsers/DocumentBuilder.html#setEntityResolver(org.xml.sax.EntityResolver))

.NET Framework は [System.Xml.XmlDocument#XmlResolver プロパティ](https://docs.microsoft.com/ja-jp/dotnet/api/system.xml.xmldocument.xmlresolver?view=netframework-4.7.2#System_Xml_XmlDocument_XmlResolver)

---
#### XML の外部参照の NULL の挙動

上記のメソッドとプロパティの違いだけでなく、NULL を指定した際の挙動も異なる。

Java は既定のオブジェクトが採用される(つまり、メソッドを呼び出さないでXMLを解析するのと同じ)。

.NET Framework は NULL オブジェクト(つまり、外部参照しない/外部参照を禁止)。

---
#### XML の外部参照のオブジェクト

上記の外部参照のリゾルバを指定するオブジェクトは、

Java の場合は [org.xml.sax.EntityResolver インターフェイス](https://docs.oracle.com/javase/jp/6/api/org/xml/sax/EntityResolver.html)

.NET Framework の場合は [System.Xml.XmlResolver 抽象クラス](https://docs.microsoft.com/ja-jp/dotnet/api/system.xml.xmlresolver?view=netframework-4.7.2)

---
#### XML の外部参照のオブジェクトの唯一実装が必要なクラス

上記の外部参照のリゾルバを指定するオブジェクトに唯一実装する必要があるのが、**「外部参照を示す URIのコンテンツを返すメソッド」**というのは自明だろう。

---
##### XML の外部参照のオブジェクトの唯一実装が必要なクラス(Java)

Java の場合は [org.xml.sax.InputSource.InputSource resolveEntity(String publicId,String systemId) メソッド](https://docs.oracle.com/javase/jp/6/api/org/xml/sax/EntityResolver.html#resolveEntity(java.lang.String,%20java.lang.String))

第二引数が String 型だけど外部参照を示す URI が来て、[org.xml.sax.InputSource.InputSource クラス](https://docs.oracle.com/javase/jp/6/api/org/xml/sax/InputSource.html)が返る。

---
##### XML の外部参照のオブジェクトの唯一実装が必要なクラス(.NET Framework)

.NET Framework の場合は [object GetEntity(Uri absoluteUri, string role, Type ofObjectToReturn) メソッド](https://docs.microsoft.com/ja-jp/dotnet/api/system.xml.xmlresolver.getentity?view=netframework-4.7.2#System_Xml_XmlResolver_GetEntity_System_Uri_System_String_System_Type_)だけ。

第一引数に [System.Uri クラス](https://docs.microsoft.com/ja-jp/dotnet/api/system.uri?view=netframework-4.7.2)で外部参照を示す URI が来て、[System.IO.Stream クラス](https://docs.microsoft.com/ja-jp/dotnet/api/system.io.stream?view=netframework-4.7.2)を返すだけ。

返してほしい型/クラスを示す第三引数があるけど、現実は [System.IO.Stream クラス](https://docs.microsoft.com/ja-jp/dotnet/api/system.io.stream?view=netframework-4.7.2) しか与えないようなので、やっぱり結局[System.IO.Stream クラス](https://docs.microsoft.com/ja-jp/dotnet/api/system.io.stream?view=netframework-4.7.2)を返すだけ。

---
#### XML の外部参照のオブジェクトが返す InputSource クラスとは

上記の .NET FrameWork の場合は [System.IO.Stream クラス](https://docs.microsoft.com/ja-jp/dotnet/api/system.io.stream?view=netframework-4.7.2)を返すだけなので、すっきりしているが、Java の場合の[org.xml.sax.InputSource.InputSource クラス](https://docs.oracle.com/javase/jp/6/api/org/xml/sax/InputSource.html)とは何かというと、
[java.io.InputStream クラス](https://docs.oracle.com/javase/jp/6/api/java/io/InputStream.html)と [java.io.Reader クラス](https://docs.oracle.com/javase/jp/6/api/java/io/Reader.html) (と文字コード)をまとめた感じと表現すると分かりやすいと思う。

---
### 定番の 3rd party ライブラリ

Java の場合は、[Apache-Commons](https://commons.apache.org/)に大抵は何かある

.NET Frameworkは...知らない

---
### 定番の 3rd party ライブラリ(.NET Frameworkのハッシュ)

[Classless.Hasher](https://sourceforge.net/projects/classlesshasher/)は便利だった

---
### 定番の 3rd party ライブラリ(.NET Frameworkの乱数)

[麗の小屋 C#乱数ライブラリ](http://www.rei.to/random.html)は便利だった

---
### 定番の 3rd party ライブラリ(.NET Framework/Javaの暗号)

[The Legion of the Bouncy Castle](http://bouncycastle.org/)はJava/.NET Framework共に定番の暗号ライブラリかもしれない