2013-04-24 70 views
2

我目前正在忙於開發使用MonoTouch的iOS應用程序。隱藏NSInputStream和NSOutputStream到System.IO.Stream - Xamarin.iOS(MonoTouch)

當連接到外部附件並建立一個EASession時,我需要將NSInputStream和NSOutputStream傳遞給另一個方法,用於輸入和輸出流的System.IO.Stream。

我不知道如何處理這個問題,因爲我使用了一些C#庫,這些庫被編寫成獨立於平臺,因此我無法更改預期NSInputStream/NSOutputStream的方法。

將這些流轉換爲System.IO.Stream的最佳方法是什麼?

感謝

回答

0

這就是我如何正確工作。如果有人有任何建議,請讓我知道。

InputStream非常簡單,但OutputStream有點不同。下面的代碼將允許您調用Write()結束WriteByte()方法。我已經在Console.WriteLine()中留給人們看看它是如何工作的。

的InputStream:

class CustomInputStream : System.IO.Stream 
{ 

    NSInputStream input_stream; 

    public CustomInputStream (NSInputStream str) 
    { 
     input_stream = str; 
    } 

    public override void Flush() 
    { 
     throw new NotSupportedException(); 
    } 

    public override int Read(byte[] buffer, int offset, int count) 
    { 
     if (offset != 0) 
      throw new NotSupportedException(); 
     return input_stream.Read (buffer, (uint)count); 
    } 

    public override long Seek (long offset, System.IO.SeekOrigin origin) 
    { 
     throw new NotSupportedException(); 
    } 

    public override void SetLength (long value) 
    { 
     throw new NotSupportedException(); 
    } 

    public override void Write (byte[] buffer, int offset, int count) 
    { 
     throw new NotSupportedException(); 
    } 

    public override bool CanRead { 
     get { 
      return true; 
     } 
    } 

    public override bool CanSeek { 
     get { 
      return false; 
     } 
    } 

    public override bool CanWrite { 
     get { 
      return false; 
     } 
    } 

    public override long Length { 
     get { 
      throw new NotSupportedException(); 
     } 
    } 

    public override long Position { 
     get { 
      throw new NotSupportedException(); 
     } 
     set { 
      throw new NotSupportedException(); 
     } 
    } 

} 

的OutputStream:

class CustomOutputStream : System.IO.Stream 
{ 

    NSOutputStream output_stream; 
    List<byte> buffer; 

    public CustomOutputStream (NSOutputStream str) 
    { 
     output_stream = str; 
     buffer = new List<byte>(); 
    } 

    public override void Flush() 
    { 
     Write(buffer.ToArray(),0,buffer.Count); 
     buffer.Clear(); 
    } 

    public override int Read (byte[] buffer, int offset, int count) 
    {  
      throw new NotSupportedException(); 
    } 

    public override long Seek (long offset, System.IO.SeekOrigin origin) 
    { 
     throw new NotSupportedException(); 
    } 

    public override void SetLength (long value) 
    { 
     throw new NotSupportedException(); 
    } 

    public override void Write (byte[] buffer, int offset, int count) 
    { 
     if (offset != 0) 
      throw new NotSupportedException(); 

     int sent = 0; 
     var stillToSend = new byte[buffer.Length-offset]; 
     buffer.CopyTo(stillToSend, offset); 

     Console.WriteLine("out while begin (buffer: {0})",buffer.LongLength); 
     while (count > 0) 
     {  
      if (output_stream.HasSpaceAvailable()) 
      { 
       Console.WriteLine("in while has space"); 
       var bytesWritten = output_stream.Write(buffer, (uint)count); 
       if (bytesWritten == -1) 
       { 
        Console.WriteLine(@"write error"); 
        break; 
       } 
       else if (bytesWritten > 0) 
       { 
        Console.WriteLine("Bytes written: "+ bytesWritten.ToString()); 
        count -= bytesWritten; 
        if (0 == count) 
         break; 

        var temp = new List<byte>(); 
        for (var i=bytesWritten; i<stillToSend.Length; i++) 
        { 
         temp.Add(stillToSend[i]); 
        } 
        stillToSend = temp.ToArray(); 
       } 
      } 
      else 
      { 
       Console.WriteLine("in while has NO space"); 
      } 
     } 


    } 
    public override void WriteByte (byte value) 
    { 

     buffer.Add(value); 

    } 

    public override bool CanRead { 
     get { 
      return false; 

     } 
    } 


    public override bool CanSeek { 
     get { 
      return false; 
     } 
    } 

    public override bool CanWrite { 
     get { 
      return true; 
     } 
    } 

    public override long Length { 
     get { 
      throw new NotSupportedException(); 
     } 
    } 

    public override long Position { 
     get { 
      throw new NotSupportedException(); 
     } 
     set { 
      throw new NotSupportedException(); 
     } 
    } 

} 
2

目前存在於NSInputStream/NSOutputStream轉換爲System.IO.Stream沒有內置的方式,但你可以很容易地編寫自己的System.IO.Stream的包裝,像這樣:

class MyInputStream : System.IO.Stream 
{ 
    NSInputStream input_stream; 
    public MyInputStream (NSInputStream str) 
    { 
     input_stream = str; 
    } 

    public override void Flush() 
    { 
     throw new NotSupportedException(); 
    } 

    public override int Read (byte[] buffer, int offset, int count) 
    { 
     if (offset != 0) 
      throw new NotSupportedException(); 
     return input_stream.Read (buffer, count); 
    } 

    public override long Seek (long offset, System.IO.SeekOrigin origin) 
    { 
     throw new NotSupportedException(); 
    } 

    public override void SetLength (long value) 
    { 
     throw new NotSupportedException(); 
    } 

    public override void Write (byte[] buffer, int offset, int count) 
    { 
     throw new NotSupportedException(); 
    } 

    public override bool CanRead { 
     get { 
      return true; 
     } 
    } 

    public override bool CanSeek { 
     get { 
      return false; 
     } 
    } 

    public override bool CanWrite { 
     get { 
      return false; 
     } 
    } 

    public override long Length { 
     get { 
      throw new NotSupportedException(); 
     } 
    } 

    public override long Position { 
     get { 
      throw new NotSupportedException(); 
     } 
     set { 
      throw new NotSupportedException(); 
     } 
    } 
} 
+0

感謝您的響應。有道理,但現在我堅持以下幾點:該框架使用Stream的BeginRead(IAsyncResult)和EndRead(IAsyncResult)方法...您有關於如何使用該方法的建議嗎? – 2013-04-25 12:15:11

+0

System.IO.Stream包含BeginRead和EndRead(它是同步的)的默認實現 - 這不適合你嗎? – 2013-04-25 12:20:50

相關問題