首页 | 编程语言 | 网站建设 | 游戏天堂 | 冲浪宝典 | 网络安全 | 操作系统 | 软件时空 | 硬件指南 | 病毒相关 | IT 认证
软讯网络 > 编程语言 > .NET > C#.NET > 对同一文件进行多线程写入
【标  题】:对同一文件进行多线程写入
【关键字】:
【来  源】:http://blog.csdn.net/fengart/archive/2007/03/07/1523444.aspx

对同一文件进行多线程写入

 考多线程读写文件(三种方法)
以下转贴
using   System;  
  using   System.Threading;  
  using   System.IO;  
   
  namespace   CopyTest  
  {  
   
  //FileBuffer用来存放和取出缓冲区变量  
  public   class   FileBuffer{  
  private   int   m_readsize   =   1024;  
  //定义了m_capacity个字节的缓冲区  
  private   byte[]   m_buffer   =   new   byte[4096];  
  //确认缓冲区内已放字节的个数  
  private   int   bufferCount=0;  
  //确定读写的位置  
  private   int   readLocation=0,writeLocation=0;  
   
  public   FileBuffer()   {  
   
  }  
   
  //从缓冲区中取数据  
  public   byte[]   getBuffer()   {  
  //加上了共享锁  
  lock(this)   {  
  //判断如果缓冲区内无内容,则读取者进入wait状态,并且释放对象锁  
  if(bufferCount==0)   {  
  Console.WriteLine("缓冲区无数据,无法读取");  
  Monitor.Wait(this);  
  }  
   
  byte[]   newBuf   =   new   byte[m_readsize];  
  Buffer.BlockCopy(m_buffer,   readLocation,   newBuf,   0,   m_readsize);  
   
  //已经从缓冲区读取了内容,所以bufferCount要进行自减.  
  bufferCount-=m_readsize;  
  //求余的目的是为了循环使用缓冲区  
  readLocation=(readLocation   +   m_readsize)%m_buffer.Length;  
  //通知对象的第一个等待线程可以从WaitSleepJoin转换到Started状态.  
  Monitor.Pulse(this);  
  //返回给读取者取出的数值  
  return   newBuf;  
  }  
  }  
   
  //将数据放入缓冲区  
  public   void   setBuffer(byte[]   writeValue)   {  
  //锁住共享数据区  
  lock(this)   {  
  //如果缓冲区已满,那么进入waitsleepjoin状态  
  if(bufferCount==m_buffer.Length)   {  
  Console.WriteLine("缓冲区溢出!");  
  Monitor.Wait(this);  
  }  
  //向缓冲区写入数据  
  Buffer.BlockCopy(writeValue,   0,   m_buffer,   writeLocation,   m_readsize);  
  //自加,代表缓冲区现在到底有几个数据  
  bufferCount+=m_readsize;  
  //用%实现缓冲区的循环利用  
  writeLocation=(writeLocation   +   m_readsize)%m_buffer.Length;  
  //唤醒waitSleepJoin状态的进程,到started状态  
  Monitor.Pulse(this);  
  }//使用lock隐式的释放了共享锁  
  }  
  }  
   
     
   
     
  //写入者类,向缓冲区中放入数据  
  public   class   Writer   {    
  //定义了同步变量  
  FileBuffer   shared;  
  FileStream   file;  
  //此处构造函数的作用是在启动类中调用写入者的时候,把启动类中定义的sharedLocation传过来  
  public   Writer(FileBuffer   sharedLocation)   {  
  file   =   new   FileStream("C:\\Test.txt",FileMode.Open);  
  shared=sharedLocation;  
  }  
  //定义写入过程  
  public   void   Write()   {  
  //将数据放入缓冲区  
  Byte[]   datas   =   new   byte[1024];  
   
  for(int   byteread=0;byteread<=file.Length;byteread   +=   datas.Length)   {  
  file.Read(datas,   byteread,   datas.Length);  
  shared.setBuffer(datas);  
  }  
   
  file.Close();  
   
  //得到当前线程的名字  
  string   name=Thread.CurrentThread.Name;  
  //此线程执行完毕  
  Console.WriteLine(name+"done   writeing");  
  }  
  }  
   
  public   class   Reader   {//定义读取者  
  byte[]   value;  
  FileStream   file;  
  //定义同步变量  
  FileBuffer   shared;  
  //定义构造函数,负责传递启动类中的shared  
  public   Reader(FileBuffer   sharedLocation)   {  
  file   =   new   FileStream("C:\\Data.txt",FileMode.Create);  
  shared=sharedLocation;  
  }  
   
  public   void   Read()   {  
  //从缓冲区中循环读取  
  for(int   bytewrite=0;bytewrite<=65535;)   {  
  value=shared.getBuffer();  
  file.Write(value,   bytewrite,   value.Length);  
  bytewrite+=value.Length;  
  }  
   
  file.Close();  
   
  //取得当前线程的名字  
  string   name=Thread.CurrentThread.Name;  
  Console.WriteLine(name+"done   reading");  
  }  
  }  
   
  public   class   ThreadTest   {   //设置为启动类  
  public   static   void   Main()   {  
  FileBuffer   shared=new   FileBuffer();  
  //初始化了写入者和读取者,并且把shared参数传递了过去  
  Writer   Writer1=new   Writer(shared);  
  Reader   Reader1=new   Reader(shared);  
   
  Thread   WriterThread   =   new   Thread(new   ThreadStart   (Writer1.Write));  
  WriterThread.Name="写入者";  
   
  Thread   ReaderThread   =   new   Thread(new   ThreadStart   (Reader1.Read));  
  ReaderThread.Name="读取者";  
  //启动这两个线程  
  WriterThread.Start();  
  ReaderThread.Start();  
  WriterThread.Join();  
  ReaderThread.Join();  
  Console.ReadLine();  
  }  
  }  
  }

==========================================================================================

使用Mutex
每个程序在打开文件,进行写的时候,用mutex包含,例如:
Mutex mtx = new Mutex();
mtx.WaitOne();
//Write file here
mtx.ReleaseMutex();
=========================================================================================
private static  void WriteFile(object parm)
        {
            FileStream fileStream = null;
            BinaryWriter binaryWriter = null;
            FileInfo fileInfo = new FileInfo("C:\\test.txt");
            try
            {
                fileStream = fileInfo.Open(FileMode.Open, FileAccess.Write, FileShare.Write);//注意Open方法的参数
            }
            catch (IOException e)
            {
                throw new IOException("构造FileStream对象时出错", e);
            }
            try
            {
                binaryWriter = new BinaryWriter(fileStream);
            }
            catch (IOException e)
            {
                fileStream.Close();
                throw new IOException("构造BinaryWriter对象时出错", e);
            }
            try
            {
                //将该流的当前位置设置为适当的位置
                fileStream.Seek(0, SeekOrigin.End);//此方法可能出现出现 I/O 错误,抛出IOException异常
                //将数据块写入文件
                binaryWriter.Write(parm.ToString());//此方法可能出现出现 I/O 错误,抛出IOException异常
            }
            catch (IOException e)
            {
                throw new IOException("将数据块写入文件时出错", e);
            }
            finally
            {
                //关闭流,BinaryWriter也将关闭FileStream对象,所以无需再调用fileStream.Close()
                binaryWriter.Close();
            }
        }

public static void Main()
{
    //多线程写文件
    for (int i = 0; i < 100; i++)
        {
                string str= "This is string " + i + " ";
                System.Threading.Thread thread = new System.Threading.Thread(
                    new System.Threading.ParameterizedThreadStart(WriteFile));
                thread.Start(str);
        }
}       
  
               
asp.net父窗体调用子窗体,并将值传回父窗体:【上一篇】
“C#高级编程学习“ 内存:引用和值变量:【下一篇】
【相关文章】
没有相关文章
【随机文章】
  • shawl.qiu Javascript 语法高亮函数 v1.0
  • 注意Java正则表达式的数量表示符
  • 第9章. 流程建模
  • solarisのkernalパラメータの値を読み出す方法について(日本語練習)
  • 多线程编程——实战篇(二)
  • 3550 without using "ip default-network"
  • 十天学会ASP之第一天
  • FreeBSD的部分Package简介(一)
  • 21世纪十大营销法则
  • Rhino的开发环境配置
  • 【相关评论】
    没有相关评论
    【发表评论】
    姓名:
    邮件:
    随机码*
    评论*
          
    |  首 页  |  版权声明  |  联系我们   |  网站地图  |
    CopyRight © 2004-2007 软讯网络 All Rigths Reserved.