首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >.NET并行文件创建

.NET并行文件创建
EN

Stack Overflow用户
提问于 2013-08-29 13:22:40
回答 3查看 252关注 0票数 0

我正在创建一个从数据库获取文件数据的程序。要求文件在存在“IMAGE_00001.JPG”、“IMAGE_00002.JPG”、.

由于性能问题,我将并行加载数据,但创建文件时会遇到问题。

代码语言:javascript
复制
For i As Long = 1 To maxSeqNr
    DIDir = New DirectoryInfo(currDir)
    If DIDir.GetFiles(currFilePrefix & Microsoft.VisualBasic.Right(maxSeqNrLeadingZeros & CStr(i), Len(maxSeqNr.ToString)) & ".*", SearchOption.TopDirectoryOnly).Length = 0 Then
        sRetValue = currFilePrefix & Microsoft.VisualBasic.Right(maxSeqNrLeadingZeros & CStr(i), Len(maxSeqNr.ToString)) & currFileExtention

        Dim oSW As StreamWriter
        oSW = New StreamWriter(currDir & sRetValue)
        oSW.WriteLine("")
        oSW.Close()
        oSW.Dispose()
        oSW = Nothing

        Exit For
    End If
Next

问题是,有时两个线程运行的代码行相同。我添加了日志,我发现了以下内容:

代码语言:javascript
复制
Check for 'IMAGE_00001.JPG' ; Directory: ''
Check for 'IMAGE_00001.JPG' ; Directory: ''
Check for 'IMAGE_00002.JPG' ; Directory: 'IMAGE_00001.JPG'
Check for 'IMAGE_00003.JPG' ; Directory: 'IMAGE_00001.JPG,IMAGE_00002.JPG'

是否有可能在执行Exists语句之前“锁定”工作目录。在我创建文件后“释放”?其他线程应该等待,直到它们能够“锁定”目录。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-08-29 14:15:21

您应该生成要使用的名称,然后尝试使用该名称创建FileStream对象。使用合适的构造函数接受FileMode参数(例如这一个)并指定CreateNew

如果抛出一个IOException并生成一个新名称,则捕获它。

否则,你所面对的是一种典型的种族。这取决于您是选择组合原始策略(检查是否存在,然后尝试打开文件),还是只尝试创建文件并期望异常。

一旦您成功地打开了FileStream,就可以将它传递给接受Stream参数的StreamWriter构造函数,然后从那里开始。

票数 1
EN

Stack Overflow用户

发布于 2013-08-29 14:12:03

我会使用syn / lock策略:当线程想要写入文件并停止所有其他线程时锁定,直到完成为止,然后释放锁。http://msdn.microsoft.com/de-de/library/vstudio/ms173179.aspx

或者,使用一个非阻塞整数作为计数器,因此它将保证一个唯一的文件,但它可能会搞乱您的“编号”要求。http://msdn.microsoft.com/en-us/library/system.threading.interlocked.aspx

票数 0
EN

Stack Overflow用户

发布于 2013-08-29 14:29:02

如果只需通过IMG_00000.jpg IMG_XXXXX.jpg生成空白文件,则可以使用Parallel.For循环来创建不存在的文件。这将确保两个数字不被两个不同的线程检查,而是在线程之间划分出数字。

虽然我不知道这实际上会更快,特别是如果您必须在目录中搜索一个扩展名与图像名称匹配的文件:

代码语言:javascript
复制
Dim width = Len(maxSeqNr.ToString)
Dim DIDir = New DirectoryInfo(currDir)
Parallel.For(1L, maxSeqNr, Sub(i)
    Dim pattern = currFilePrefix & Microsoft.VisualBasic.Right(maxSeqNrLeadingZeros & CStr(i), Len(maxSeqNr.ToString)) & ".*"
    If Not DDir.EnumerateFiles(pattern, SearchOption.TopDirectoryOnly).Any Then
        Dim fn = currFilePrefix & Microsoft.VisualBasic.Right(maxSeqNrLeadingZeros & CStr(i), width) & currFileExtention
        File.Create(fn).Close
    End If
End Sub)

如果您正在搜索的文件夹很小,这可能会更好(假设您实际上关心与模式匹配的任何文件名):

代码语言:javascript
复制
' My VB.Net is horrible
Dim width = Len(maxSeqNr.ToString)
Dim files = Directory.GetFiles(currDir)
Parallel.For(1L, maxSeqNr, Sub(i)
    Dim pattern = currFilePrefix & Microsoft.VisualBasic.Right(maxSeqNrLeadingZeros & CStr(i), Len(maxSeqNr.ToString))
    ' consider case-insenstive matching
    If Not files.Any(Function(fn) Path.GetFileNameWithoutExtension(fn) = pattern) Then
        Dim fn = currFilePrefix & Microsoft.VisualBasic.Right(maxSeqNrLeadingZeros & CStr(i), width) & currFileExtention
        File.Create(fn).Close
    End If
End Sub)

或者,如果您真正需要的是只在不存在的情况下创建一个文件,那么您只需继续访问所有文件:

代码语言:javascript
复制
Parallel.For(1L, maxSeqNr, Sub(i)
    Dim fn = currFilePrefix & Microsoft.VisualBasic.Right(maxSeqNrLeadingZeros & CStr(i), width) & currFileExtention
    File.Open(fn, FileMode.OpenOrCreate).Close
End Sub)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18512228

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档