• productconsumer


      1 参考多线程读写文件
      2 以下转贴
      3 using   System;   
      4   using   System.Threading;   
      5   using   System.IO;   
      6     
      7   namespace   CopyTest   
      8   {   
      9     
     10   //FileBuffer用来存放和取出缓冲区变量   
     11   public   class   FileBuffer{   
     12   private   int   m_readsize   =   1024;   
     13   //定义了m_capacity个字节的缓冲区   
     14   private   byte[]   m_buffer   =   new   byte[4096];   
     15   //确认缓冲区内已放字节的个数   
     16   private   int   bufferCount=0;   
     17   //确定读写的位置   
     18   private   int   readLocation=0,writeLocation=0;   
     19     
     20   public   FileBuffer()   {   
     21     
     22   }   
     23     
     24   //从缓冲区中取数据   
     25   public   byte[]   getBuffer()   {   
     26   //加上了共享锁   
     27   lock(this)   {   
     28   //判断如果缓冲区内无内容,则读取者进入wait状态,并且释放对象锁   
     29   if(bufferCount==0)   {   
     30   Console.WriteLine("缓冲区无数据,无法读取");   
     31   Monitor.Wait(this);   
     32   }   
     33     
     34   byte[]   newBuf   =   new   byte[m_readsize];   
     35   Buffer.BlockCopy(m_buffer,   readLocation,   newBuf,   0,   m_readsize);   
     36     
     37   //已经从缓冲区读取了内容,所以bufferCount要进行自减.   
     38   bufferCount-=m_readsize;   
     39   //求余的目的是为了循环使用缓冲区   
     40   readLocation=(readLocation   +   m_readsize)%m_buffer.Length;   
     41   //通知对象的第一个等待线程可以从WaitSleepJoin转换到Started状态.   
     42   Monitor.Pulse(this);   
     43   //返回给读取者取出的数值   
     44   return   newBuf;   
     45   }   
     46   }   
     47     
     48   //将数据放入缓冲区   
     49   public   void   setBuffer(byte[]   writeValue)   {   
     50   //锁住共享数据区   
     51   lock(this)   {   
     52   //如果缓冲区已满,那么进入waitsleepjoin状态   
     53   if(bufferCount==m_buffer.Length)   {   
     54   Console.WriteLine("缓冲区溢出!");   
     55   Monitor.Wait(this);   
     56   }   
     57   //向缓冲区写入数据   
     58   Buffer.BlockCopy(writeValue,   0,   m_buffer,   writeLocation,   m_readsize);   
     59   //自加,代表缓冲区现在到底有几个数据   
     60   bufferCount+=m_readsize;   
     61   //用%实现缓冲区的循环利用   
     62   writeLocation=(writeLocation   +   m_readsize)%m_buffer.Length;   
     63   //唤醒waitSleepJoin状态的进程,到started状态   
     64   Monitor.Pulse(this);   
     65   }//使用lock隐式的释放了共享锁   
     66   }   
     67   }   
     68     
     69       
     70     
     71       
     72   //写入者类,向缓冲区中放入数据   
     73   public   class   Writer   {     
     74   //定义了同步变量   
     75   FileBuffer   shared;   
     76   FileStream   file;   
     77   //此处构造函数的作用是在启动类中调用写入者的时候,把启动类中定义的sharedLocation传过来   
     78   public   Writer(FileBuffer   sharedLocation)   {   
     79   file   =   new   FileStream("C:\\Test.txt",FileMode.Open);   
     80   shared=sharedLocation;   
     81   }   
     82   //定义写入过程   
     83   public   void   Write()   {   
     84   //将数据放入缓冲区   
     85   Byte[]   datas   =   new   byte[1024];   
     86     
     87   for(int   byteread=0;byteread<=file.Length;byteread   +=   datas.Length)   {   
     88   file.Read(datas,   byteread,   datas.Length);   
     89   shared.setBuffer(datas);   
     90   }   
     91     
     92   file.Close();   
     93     
     94   //得到当前线程的名字   
     95   string   name=Thread.CurrentThread.Name;   
     96   //此线程执行完毕   
     97   Console.WriteLine(name+"done   writeing");   
     98   }   
     99   }   
    100     
    101   public   class   Reader   {//定义读取者   
    102   byte[]   value;   
    103   FileStream   file;   
    104   //定义同步变量   
    105   FileBuffer   shared;   
    106   //定义构造函数,负责传递启动类中的shared   
    107   public   Reader(FileBuffer   sharedLocation)   {   
    108   file   =   new   FileStream("C:\\Data.txt",FileMode.Create);   
    109   shared=sharedLocation;   
    110   }   
    111     
    112   public   void   Read()   {   
    113   //从缓冲区中循环读取   
    114   for(int   bytewrite=0;bytewrite<=65535;)   {   
    115   value=shared.getBuffer();   
    116   file.Write(value,   bytewrite,   value.Length);   
    117   bytewrite+=value.Length;   
    118   }   
    119     
    120   file.Close();   
    121     
    122   //取得当前线程的名字   
    123   string   name=Thread.CurrentThread.Name;   
    124   Console.WriteLine(name+"done   reading");   
    125   }   
    126   }   
    127     
    128   public   class   ThreadTest   {   //设置为启动类   
    129   public   static   void   Main()   {   
    130   FileBuffer   shared=new   FileBuffer();   
    131   //初始化了写入者和读取者,并且把shared参数传递了过去   
    132   Writer   Writer1=new   Writer(shared);   
    133   Reader   Reader1=new   Reader(shared);   
    134     
    135   Thread   WriterThread   =   new   Thread(new   ThreadStart   (Writer1.Write));   
    136   WriterThread.Name="写入者";   
    137     
    138   Thread   ReaderThread   =   new   Thread(new   ThreadStart   (Reader1.Read));   
    139   ReaderThread.Name="读取者";   
    140   //启动这两个线程   
    141   WriterThread.Start();   
    142   ReaderThread.Start();   
    143   WriterThread.Join();   
    144   ReaderThread.Join();   
    145   Console.ReadLine();   
    146   }   
    147   }   
    148   }
    149 
  • 相关阅读:
    IP地址,子网掩码,默认网关----学习
    解析报文报错:Exception:org.xml.sax.SAXParseException: The processing instruction target matching "[xX][mM][lL]" is not allowed.
    看到一篇spring原理介绍,挺好的,记录下
    spring--学习摘要
    java集合 :map 学习
    java集合 :set 学习
    java集合 :list 学习
    EDM发送的邮件,outlook显示问题
    ftl页面自定义日期格式
    html静态页面传值
  • 原文地址:https://www.cnblogs.com/hq2008/p/829509.html
Copyright © 2020-2023  润新知