关于不同线程访问同一文件的问题。

tracyweisheit 2010-06-28 04:22:29
UI线程和程序中的另一子线程都需要写log文件,那么我需要解决的问题是:两个线程同时访问log文件时会发生冲突,出现同时打开文件执行写操作的情况。我使用FileStream时,会发生要打开写的文件正在被其他占用的错误,那么:

1.FileStream本身就是独占的方式打开文件的么?

2.想要避免一个线程打开文件时出现上述错误,我想知道文件是否已经被打开?如果能知道,那么等待一定时间后再进行写文件操做就可以避免出错。有什么好方法么?可否提供稍详细的实现方法。
...全文
179 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
DevinXie 2010-07-24
  • 打赏
  • 举报
回复
收藏了...
robake 2010-07-23
  • 打赏
  • 举报
回复
我已经测试过了,使用多线程分块读取同一个文件后,写成指定数量的块,再合并还原成文件。


代码是有效的。。。。

我的代码的读取线程默认为5个。。。
robake 2010-07-23
  • 打赏
  • 举报
回复
楼主参考一下我的代码,或者浏览http://topic.csdn.net/u/20100716/11/4addfa0d-db8e-4604-9e7b-f2e14958a59e.html


Imports System.IO
Imports System.Threading
Imports System.Text
Public Class Form1
Private p As String = "" '文件路径
Private fLength As Integer
Private fl As Integer = 102400 '定义缓冲区大小
Private fStart As Integer = 0 '定义读取起始位置
Private m As Integer = 1
Private fCount As Integer = 0 '分块数
Private cInte As Integer = 0 '当前块

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
OpenFileDialog1.ShowDialog()
TextBox1.Text = OpenFileDialog1.FileName
End Sub

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
p = TextBox1.Text
Dim a As New FileInfo(p)
fLength = a.Length
fStart = 0
Dim u As Thread
fStart = -fl
Dim c, d As Double
c = Int(fLength / fl)
d = fLength / fl
If c < d Then
fCount = c + 1
Else
fCount = d
End If
For i As Integer = 1 To ThreadCount.Text
u = New Thread(AddressOf Work)
u.IsBackground = True
u.Name = i
u.Start()
Next
End Sub

Sub Work()
SyncLock Thread.CurrentThread
Do While Not cInte >= fCount
fStart += fl
cInte += 1
ReadData(fStart, fl, cInte)
Loop
If cInte = fCount Then
Dim temppath As String = "E:\1\"
'========合并文件=========
Dim pm As New System.Diagnostics.Process()
pm.StartInfo.FileName = "cmd.exe"
pm.StartInfo.UseShellExecute = False
pm.StartInfo.CreateNoWindow = True
pm.StartInfo.RedirectStandardInput = True
pm.StartInfo.RedirectStandardOutput = True
pm.Start()
Dim temp As String = ""
Dim fEx As New FileInfo(p)

For i As Integer = 1 To fCount
If temp = "" Then
temp = "E:\1\" & fEx.Name.Replace(fEx.Extension, "." & i & fEx.Extension)
Else
temp = temp & " + " & "E:\1\" & fEx.Name.Replace(fEx.Extension, "." & i & fEx.Extension)
End If
Next
'MsgBox(temp)
pm.StandardInput.WriteLine("copy /b " & temp & " " & temppath & "OK.txt")
pm.StandardInput.WriteLine("exit")
pm.WaitForExit()
End If
End SyncLock
End Sub

'读取指定位置的内容
Sub ReadData(ByVal Start As Integer, ByVal l As Integer, ByVal cuinte As Integer)
Dim u As New FileStream(p, FileMode.Open, FileAccess.Read)

Dim sBy(l - 1) As Byte
u.Seek(Start, SeekOrigin.Begin)
u.Read(sBy, 0, sBy.Length)
u.Close()
u.Dispose()
writeData(cuinte, sBy)
End Sub
'写文件
Sub writeData(ByVal cuinte As Integer, ByVal data As Byte())
Try
Dim fEx As New FileInfo(p)
Dim TEMP As String = "c:\" & fEx.Name.Replace(fEx.Extension, "." & cuinte & fEx.Extension)
Dim u As New FileStream(TEMP, FileMode.OpenOrCreate, FileAccess.Write)
Dim Bw As New System.IO.BinaryWriter(u)
Bw.Write(data)
u.Close()
u.Dispose()
Bw.Close()
Catch ex As Exception
Err.Clear()
Exit Sub
End Try
End Sub



Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
End
End Sub


c001q 2010-07-22
  • 打赏
  • 举报
回复
这是多线程资源争用的问题,net下有专门的处理类。具体查看thread命名空间的类库。
兔子-顾问 2010-06-28
  • 打赏
  • 举报
回复
如果一个进程内,你可以写个log类。这个类,写文件的地方,可以写
Monitor.Enter(me)
写文件
Monitor.Exit(me)
兔子-顾问 2010-06-28
  • 打赏
  • 举报
回复
并发肯定出错。但是不报错。结果会乱而已。
tracyweisheit 2010-06-28
  • 打赏
  • 举报
回复
那可能不行吧,如果两个进程同时写,会不会出现同时写同一行,内容混在一起的情况?
兔子-顾问 2010-06-28
  • 打赏
  • 举报
回复
打开文件时候可以共享读写。

16,553

社区成员

发帖
与我相关
我的任务
社区描述
VB技术相关讨论,主要为经典vb,即VB6.0
社区管理员
  • VB.NET
  • 水哥阿乐
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧