我的代码不断使用文件,无法手动删除或使用代码删除

时间:2012-02-17 19:18:27

标签: vb.net upload filestream delete-file

我正在尝试用谷歌的语音API进行语音识别。

我修改了可以在codeproject上找到的UPLOADFILEEX函数......

我想删除的文件是C:\ record.flac

以下是

的功能
         Public Shared Function UploadFile(ByVal uploadfilename As String, ByVal url As String, ByVal fileFormName As String, ByVal contenttype As String, ByVal querystring As System.Collections.Specialized.NameValueCollection, ByVal cookies As CookieContainer) As String
    If (fileFormName Is Nothing) OrElse (fileFormName.Length = 0) Then
        fileFormName = "file"
    End If
    If (contenttype Is Nothing) OrElse (contenttype.Length = 0) Then
        contenttype = "application/octet-stream"
    End If
    Dim postdata As String
    postdata = "?"
    If Not (querystring Is Nothing) Then
        For Each key As String In querystring.Keys
            postdata += key + "=" + querystring.Get(key) + "&"
        Next
    End If
    Dim uri As Uri = New Uri(url + postdata)
    Dim boundary As String = "----------" + DateTime.Now.Ticks.ToString("x")
    Dim webrequest As HttpWebRequest = CType(Net.WebRequest.Create(uri), HttpWebRequest)
    webrequest.CookieContainer = cookies
    webrequest.ContentType = "audio/x-flac; rate=16000"
    webrequest.Method = "POST"
    Dim sb As StringBuilder = New StringBuilder
    sb.Append("--")
    sb.Append(boundary)
    sb.Append("" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "")
    sb.Append("Content-Disposition: form-data; name=""")
    sb.Append(fileFormName)
    sb.Append("""; filename=""")
    sb.Append(IO.Path.GetFileName(uploadfilename))
    sb.Append("""")
    sb.Append("" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "")
    sb.Append("Content-Type: ")
    sb.Append(contenttype)
    sb.Append("" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "")
    sb.Append("" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "")
    Dim postHeader As String = sb.ToString
    Dim postHeaderBytes As Byte() = Encoding.UTF8.GetBytes(postHeader)
    Dim boundaryBytes As Byte() = Encoding.ASCII.GetBytes("" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "--" + boundary + "" & Microsoft.VisualBasic.Chr(13) & "" & Microsoft.VisualBasic.Chr(10) & "")
    Dim fileStreama As FileStream = New FileStream(uploadfilename, FileMode.Open, FileAccess.Read)
    Dim length As Long = postHeaderBytes.Length + fileStreama.Length + boundaryBytes.Length
    webrequest.ContentLength = length
    Dim requestStream As Stream = webrequest.GetRequestStream
    requestStream.Write(postHeaderBytes, 0, postHeaderBytes.Length)
    Dim sendBuffer(Math.Min(4096, fileStreama.Length)) As Byte
    Dim bytesRead As Integer = 0
    Do
        bytesRead = fileStreama.Read(sendBuffer, 0, sendBuffer.Length)
        If bytesRead = 0 Then Exit Do
        requestStream.Write(sendBuffer, 0, bytesRead)
    Loop
    requestStream.Write(boundaryBytes, 0, boundaryBytes.Length)
    Dim responce As WebResponse = webrequest.GetResponse
    Dim s As Stream = responce.GetResponseStream
    Dim sr As StreamReader = New StreamReader(s)
    Return sr.ReadToEnd
    sr.Dispose()
    s.Dispose()
    fileStreama.Dispose()
    requestStream.Dispose()
    webrequest.Abort()
    responce.Close()

End Function

函数WORKS(Thankgod)但是每当我想要清理时(即删除位于c :)中的音频文件,它就会挂起并且没有任何反应......

以下是我在formclosing事件上执行的代码....

      Private Sub Form1_Close(sender As System.Object, e As System.EventArgs) Handles MyBase.FormClosing
    Dim di As New IO.DirectoryInfo("c:\")
    Dim diar1 As IO.FileInfo() = di.GetFiles()
    Dim dra As IO.FileInfo
    For Each dra In diar1
        If dra.Name.Contains("record.") Then
            dra.Delete()
        End If
    Next
End Sub

正如您可能从功能中看到我已经尝试删除所有流并关闭它们因此文件未被访问

但它仍然挂起,当我尝试手动删除它...它告诉我它正在被另一个进程(这是我的程序)使用 - (我使用ffmpeg将.wav转换为.flac文件,但是没有引起任何问题)....

我做错了什么......

我是否错过了某些流或某事的结束。

顺便说一下uploadfilename字符串是c:\ record.flac(仅供参考 - 我认为不会有帮助)

2 个答案:

答案 0 :(得分:0)

在处理文件流之前,您的函数正在调用Return。这意味着您的Dispose调用永远不会被触发..并且流保存在文件引用上。

答案 1 :(得分:0)

我同意Boo的意见,处理前的回报可能是原因。因此解决方案是将sr.ReadToEnd的结果存储在变量中,关闭流然后返回var。

但更好的解决方案是在每个必须调用的类上使用Using语句(http://msdn.microsoft.com/en-us/library/htd05whh.aspx).Dispose()on(aka实现IDisposable的类。

这样可以提供更清晰的代码,因为您可以轻松查看代码中正在使用的资源。与.NET相比,错误较少​​的代码确保一旦离开使用块的范围就会处理所有内容。