导出 (0) 打印
全部展开

BufferedStream 类

给另一流上的读写操作添加一个缓冲层。无法继承此类。

命名空间:System.IO
程序集:mscorlib(在 mscorlib.dll 中)

[ComVisibleAttribute(true)] 
public sealed class BufferedStream : Stream
/** @attribute ComVisibleAttribute(true) */ 
public final class BufferedStream extends Stream
ComVisibleAttribute(true) 
public final class BufferedStream extends Stream

有关创建文件和向文件中写入文本的示例,请参见 如何:向文件写入文本。有关从文件中读取文本的示例,请参见 如何:从文件读取文本。有关读取和写入二进制文件的示例,请参见 如何:对新建的数据文件进行读取和写入

缓冲区是内存中的字节块,用于缓存数据,从而减少对操作系统的调用次数。缓冲区可提高读取和写入性能。使用缓冲区可进行读取或写入,但不能同时进行这两种操作。BufferedStreamReadWrite 方法自动维护缓冲区。

BufferedStream 可写在某些类型的流周围。它提供从基础数据源或储存库读取字节以及将字节写入基础数据源或储存库的实现。使用 BinaryReaderBinaryWriter 读取和写入其他数据类型。BufferedStream 用于在不需要缓冲区时防止缓冲区降低输入和输出速度。如果您读取和写入的大小始终大于内部缓冲区的大小,那么 BufferedStream 可能甚至无法分配内部缓冲区。BufferedStream 也在共享缓冲区中缓冲读取和写入。假设您几乎始终执行一系列读取或写入操作,而很少在读取和写入之间切换。

下面的代码示例说明如何在 NetworkStream 类之上使用 BufferedStream 类,以提高某些 I/O 操作的性能。启动客户端之前,先在远程计算机上启动服务器。启动客户端时,将远程计算机名指定为一个命令行参数。改变 dataArraySizestreamBufferSize 常数,以查看它们对性能的影响。

using System;
using System.IO;
using System.Globalization;
using System.Net;
using System.Net.Sockets;

public class Client 
{
    const int dataArraySize    =   100;
    const int streamBufferSize =  1000;
    const int numberOfLoops    = 10000;

    static void Main(string[] args) 
    {
        // Check that an argument was specified when the 
        // program was invoked.
        if(args.Length == 0)
        {
            Console.WriteLine("Error: The name of the host computer" +
                " must be specified when the program is invoked.");
            return;
        }

        string remoteName = args[0];

        // Create the underlying socket and connect to the server.
        Socket clientSocket = new Socket(AddressFamily.InterNetwork,
            SocketType.Stream, ProtocolType.Tcp);

        clientSocket.Connect(new IPEndPoint(
            Dns.Resolve(remoteName).AddressList[0], 1800));

        Console.WriteLine("Client is connected.\n");

        // Create a NetworkStream that owns clientSocket and 
        // then create a BufferedStream on top of the NetworkStream.
        // Both streams are disposed when execution exits the
        // using statement.
        using(Stream 
            netStream = new NetworkStream(clientSocket, true),
            bufStream = 
                  new BufferedStream(netStream, streamBufferSize))
        {
            // Check whether the underlying stream supports seeking.
            Console.WriteLine("NetworkStream {0} seeking.\n",
                bufStream.CanSeek ? "supports" : "does not support");

            // Send and receive data.
            if(bufStream.CanWrite)
            {
                SendData(netStream, bufStream);
            }
            if(bufStream.CanRead)
            {
                ReceiveData(netStream, bufStream);
            }

            // When bufStream is closed, netStream is in turn 
            // closed, which in turn shuts down the connection 
            // and closes clientSocket.
            Console.WriteLine("\nShutting down the connection.");
            bufStream.Close();
        }
    }

    static void SendData(Stream netStream, Stream bufStream)
    {
        DateTime startTime;
        double networkTime, bufferedTime;

        // Create random data to send to the server.
        byte[] dataToSend = new byte[dataArraySize];
        new Random().NextBytes(dataToSend);

        // Send the data using the NetworkStream.
        Console.WriteLine("Sending data using NetworkStream.");
        startTime = DateTime.Now;
        for(int i = 0; i < numberOfLoops; i++)
        {
            netStream.Write(dataToSend, 0, dataToSend.Length);
        }
        networkTime = (DateTime.Now - startTime).TotalSeconds;
        Console.WriteLine("{0} bytes sent in {1} seconds.\n",
            numberOfLoops * dataToSend.Length, 
            networkTime.ToString("F1"));

        // Send the data using the BufferedStream.
        Console.WriteLine("Sending data using BufferedStream.");
        startTime = DateTime.Now;
        for(int i = 0; i < numberOfLoops; i++)
        {
            bufStream.Write(dataToSend, 0, dataToSend.Length);
        }
        bufStream.Flush();
        bufferedTime = (DateTime.Now - startTime).TotalSeconds;
        Console.WriteLine("{0} bytes sent in {1} seconds.\n",
            numberOfLoops * dataToSend.Length, 
            bufferedTime.ToString("F1"));

        // Print the ratio of write times.
        Console.WriteLine("Sending data using the buffered " +
            "network stream was {0} {1} than using the network " +
            "stream alone.\n",
            (networkTime/bufferedTime).ToString("P0"),
            bufferedTime < networkTime ? "faster" : "slower");
    }

    static void ReceiveData(Stream netStream, Stream bufStream)
    {
        DateTime startTime;
        double networkTime, bufferedTime = 0;
        int bytesReceived = 0;
        byte[] receivedData = new byte[dataArraySize];

        // Receive data using the NetworkStream.
        Console.WriteLine("Receiving data using NetworkStream.");
        startTime = DateTime.Now;
        while(bytesReceived < numberOfLoops * receivedData.Length)
        {
            bytesReceived += netStream.Read(
                receivedData, 0, receivedData.Length);
        }
        networkTime = (DateTime.Now - startTime).TotalSeconds;
        Console.WriteLine("{0} bytes received in {1} seconds.\n",
            bytesReceived.ToString(), 
            networkTime.ToString("F1"));

        // Receive data using the BufferedStream.
        Console.WriteLine("Receiving data using BufferedStream.");
        bytesReceived = 0;
        startTime = DateTime.Now;
        while(bytesReceived < numberOfLoops * receivedData.Length)
        {
            bytesReceived += bufStream.Read(
                receivedData, 0, receivedData.Length);
        }
        bufferedTime = (DateTime.Now - startTime).TotalSeconds;
        Console.WriteLine("{0} bytes received in {1} seconds.\n",
            bytesReceived.ToString(), 
            bufferedTime.ToString("F1"));

        // Print the ratio of read times.
        Console.WriteLine("Receiving data using the buffered network" +
            " stream was {0} {1} than using the network stream alone.",
            (networkTime/bufferedTime).ToString("P0"),
            bufferedTime < networkTime ? "faster" : "slower");
    }
}

import System.*;
import System.IO.*;
import System.Globalization.*;
import System.Net.*;
import System.Net.Sockets.*;

public class Client
{
    private static int dataArraySize = 100;
    private static int streamBufferSize = 1000;
    private static int numberOfLoops = 10000;

    public static void main(String[] args)
    {
        // Check that an argument was specified when the 
        // program was invoked.
        if ( args.length == 0 ) {
            Console.WriteLine(("Error: The name of the host computer" 
                + " must be specified when the program is invoked."));
            return;
        }
        String remoteName = args[0];

        // Create the underlying socket and connect to the server.
        Socket clientSocket =  new Socket(AddressFamily.InterNetwork, 
            SocketType.Stream, ProtocolType.Tcp);

        clientSocket.Connect(
            new IPEndPoint(Dns.Resolve(remoteName).get_AddressList()[0], 1800));

        Console.WriteLine("Client is connected.\n");

        // Create a NetworkStream that owns clientSocket and 
        // then create a BufferedStream on top of the NetworkStream.
        // Both streams are disposed when execution exits the
        // using statement.

        Stream netStream = new NetworkStream(clientSocket, true);
        Stream bufStream = new BufferedStream(netStream, streamBufferSize);
        try {
            try {
                // Check whether the underlying stream supports seeking.
                Console.WriteLine("NetworkStream {0} seeking.\n",
                    (bufStream.get_CanSeek())? "supports" : "does not support");
                // Send and receive data.
                if ( bufStream.get_CanWrite()  ) {
                    SendData(netStream, bufStream);
                }
                if ( bufStream.get_CanRead()  ) {
                    ReceiveData(netStream, bufStream);
                }

                // When execution exits the using statement, netStream
                // is disposed, which in turn shuts down the connection 
                // and closes clientSocket.
                Console.WriteLine("\nShutting down the connection.");
            }
            finally {
                netStream.Dispose();
            }
        }
        finally {
            bufStream.Dispose();
        }         
    } //main   
   
    static void SendData(Stream netStream, Stream bufStream) 
    {
        DateTime startTime;
        double networkTime,bufferedTime;

        // Create random data to send to the server.        
        ubyte dataToSend[] = new ubyte[dataArraySize];
        new Random().NextBytes(dataToSend);

        // Send the data using the NetworkStream.
        Console.WriteLine("Sending data using NetworkStream.");
        startTime = DateTime.get_Now();
        for(int i=0;i < numberOfLoops;i++) {
            netStream.Write(dataToSend, 0, dataToSend.length);
        }        
        networkTime =
            ((DateTime.get_Now()).Subtract(startTime)).get_TotalSeconds();
        Console.WriteLine("{0} bytes sent in {1} seconds.\n",
            System.Convert.ToString(numberOfLoops * dataToSend.length),
            ((System.Double) networkTime).ToString("F1"));

        // Send the data using the BufferedStream.
        Console.WriteLine("Sending data using BufferedStream.");
        startTime = DateTime.get_Now();
        for(int i=0;i < numberOfLoops;i++) {
            bufStream.Write(dataToSend, 0, dataToSend.length);
        }        
        bufStream.Flush();
        bufferedTime = 
            ((DateTime.get_Now()).Subtract(startTime)).get_TotalSeconds();
        Console.WriteLine("{0} bytes sent in {1} seconds.\n",
            System.Convert.ToString (numberOfLoops * dataToSend.length),
            ((System.Double)bufferedTime).ToString("F1"));

        // Print the ratio of write times.
        Console.WriteLine("Sending data using the buffered "
            + "network stream was {0} {1} than using the network "
            + "stream alone.\n",
            ((System.Double)(networkTime / bufferedTime)).ToString("P0"),
            (bufferedTime < networkTime) ? "faster" : "slower");
    } //SendData
   
    static void ReceiveData(Stream netStream, Stream bufStream) 
    {
        DateTime startTime;
        double bufferedTime = 0;
        double networkTime;
        int bytesReceived = 0;
        ubyte receivedData[] = new ubyte[dataArraySize];

        // Receive data using the NetworkStream.
        Console.WriteLine("Receiving data using NetworkStream.");
        startTime = DateTime.get_Now();
        while((bytesReceived < numberOfLoops * receivedData.length)) {
            bytesReceived += netStream.Read(receivedData,0,receivedData.length);
        }
        networkTime = 
            ((DateTime.get_Now()).Subtract(startTime)).get_TotalSeconds();
        Console.WriteLine("{0} bytes received in {1} seconds.\n",
            (new Integer(bytesReceived)).ToString(),
            ((System.Double)networkTime).ToString("F1"));

        // Receive data using the BufferedStream.
        Console.WriteLine("Receiving data using BufferedStream.");
        bytesReceived = 0;
        startTime = DateTime.get_Now();
        while((bytesReceived < numberOfLoops * receivedData.length)) {
            bytesReceived += bufStream.Read(receivedData,0,receivedData.length);
        }
        bufferedTime =
            ((DateTime.get_Now()).Subtract(startTime)).get_TotalSeconds();
        Console.WriteLine("{0} bytes received in {1} seconds.\n",
            (new Integer(bytesReceived)).ToString(),
            ((System.Double) bufferedTime).ToString("F1"));

        // Print the ratio of read times.
        Console.WriteLine("Receiving data using the buffered network"
            + " stream was {0} {1} than using the network stream alone.",
            ((System.Double)(networkTime / bufferedTime)).ToString("P0"),
            (bufferedTime < networkTime) ? "faster" : "slower");
    } //ReceiveData
} //Client

using System;
using System.Net;
using System.Net.Sockets;

public class Server 
{
    static void Main() 
    {
        // This is a Windows Sockets 2 error code.
        const int WSAETIMEDOUT = 10060;

        Socket serverSocket;
        int bytesReceived, totalReceived = 0;
        byte[] receivedData = new byte[2000000];

        // Create random data to send to the client.
        byte[] dataToSend = new byte[2000000];
        new Random().NextBytes(dataToSend);

        IPAddress ipAddress =
            Dns.Resolve(Dns.GetHostName()).AddressList[0];

        IPEndPoint ipEndpoint = new IPEndPoint(ipAddress, 1800);

        // Create a socket and listen for incoming connections.
        using(Socket listenSocket = new Socket(
            AddressFamily.InterNetwork, SocketType.Stream, 
            ProtocolType.Tcp))
        {
            listenSocket.Bind(ipEndpoint);
            listenSocket.Listen(1);

            // Accept a connection and create a socket to handle it.
            serverSocket = listenSocket.Accept();
            Console.WriteLine("Server is connected.\n");
        }

        try
        {
            // Send data to the client.
            Console.Write("Sending data ... ");
            int bytesSent = serverSocket.Send(
                dataToSend, 0, dataToSend.Length, SocketFlags.None);
            Console.WriteLine("{0} bytes sent.\n", 
                bytesSent.ToString());

            // Set the timeout for receiving data to 2 seconds.
            serverSocket.SetSocketOption(SocketOptionLevel.Socket,
                SocketOptionName.ReceiveTimeout, 2000);

            // Receive data from the client.
            Console.Write("Receiving data ... ");
            try
            {
                do
                {
                    bytesReceived = serverSocket.Receive(receivedData,
                        0, receivedData.Length, SocketFlags.None);
                    totalReceived += bytesReceived;
                }
                while(bytesReceived != 0);
            }
            catch(SocketException e)
            {
                if(e.ErrorCode == WSAETIMEDOUT)
                {
                    // Data was not received within the given time.
                    // Assume that the transmission has ended.
                }
                else
                {
                    Console.WriteLine("{0}: {1}\n", 
                        e.GetType().Name, e.Message);
                }
            }
            finally
            {
                Console.WriteLine("{0} bytes received.\n",
                    totalReceived.ToString());
            }
        }
        finally
        {
            serverSocket.Shutdown(SocketShutdown.Both);
            Console.WriteLine("Connection shut down.");
            serverSocket.Close();
        }
    }
}

System.Object
   System.MarshalByRefObject
     System.IO.Stream
      System.IO.BufferedStream

此类型的任何公共静态(Visual Basic 中的 Shared)成员都是线程安全的,但不保证所有实例成员都是线程安全的。

Windows 98、Windows 2000 SP4、Windows Millennium Edition、Windows Server 2003、Windows XP Media Center Edition、Windows XP Professional x64 Edition、Windows XP SP2、Windows XP Starter Edition

.NET Framework 并不是对每个平台的所有版本都提供支持。有关受支持版本的列表,请参见系统要求

.NET Framework

受以下版本支持:2.0、1.1、1.0

社区附加资源

添加
显示:
© 2014 Microsoft