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
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