【问题标题】:Why does File.Open() not open the file?为什么 File.Open() 不打开文件?
【发布时间】:2016-03-05 10:41:36
【问题描述】:

我正在我的 VB.NET Windows 窗体应用程序中实现一个保存文件按钮。

我正在尝试封装 Windows 应用程序中保存按钮的正常预期行为。 IE:如果已经选择了一个文件,则打开当前文件,写入并保存;否则,如果没有当前文件,或者使用了另存为,则显示SaveFileDialog,然后打开、写入并保存。

我目前已经编写了下面的函数,但我不断收到异常:

无法访问已关闭的文件

文件创建得很好,但是是空的(它应该包含"Test string")。我无法理解文件是如何关闭的,除非某种垃圾收集以某种方式消除了它??

当前代码:

Function SaveFile(ByVal Type As ProfileType, ByVal suggestedFileName As String, ByVal saveAs As Boolean, ByVal writeData As String) As Boolean
    Dim FileStream As Stream = Nothing
    Dim FolderPath As String = Nothing
    Dim CancelSave As Boolean = False
    Dim SaveFileDialog As SaveFileDialog = New SaveFileDialog()

    Try
        If Type = ProfileType.Product Then 'Select the initial directory path
            FolderPath = ProductPath
        Else
            FolderPath = ProfilePath
        End If

        If (FileName = String.Empty Or saveAs = True) Then 'If a file is not already selected launch a dialog to allow the user to select one
            With SaveFileDialog
                .Title = "Save"
                .AddExtension = True
                .CheckPathExists = True
                .CreatePrompt = False
                .DefaultExt = "xml"
                .Filter = "Xml Files (*.xml)|*.xml"
                .FilterIndex = 0
                .FileName = suggestedFileName
                .InitialDirectory = FolderPath
                If .ShowDialog(Me) = Windows.Forms.DialogResult.OK Then
                    FullyQualfiedPathName = New String(SaveFileDialog.FileName) 'Save the path and name of the file
                    FileName = Path.GetFileName(FullyQualfiedPathName)
                Else
                    CancelSave = True
                End If
                .Dispose()
            End With
        End If

        If (FileName <> String.Empty) Then 'Write the string to the file if the filewas correctly selected
            FileStream = File.Open(FullyQualfiedPathName, FileMode.OpenOrCreate, FileAccess.ReadWrite) 'Open the file
            Using FileStreamWriter As New StreamWriter(FileStream) 'Create the stream writer
                FileStreamWriter.Write(writeData) 'Write the data
                FileStream.Close() 'Clse the file
            End Using
        ElseIf (CancelSave <> True) Then 'Only throw an exception if the user *didn't* cancel the SavefileDialog
            Throw New Exception("File stream was nothing", New IOException())
        End If

    Catch ex As Exception
        MessageBox.Show(ex.Message & Environment.NewLine & FullyQualfiedPathName)
    End Try
    Return True
End Function

【问题讨论】:

  • 您应该先关闭 FileStreamWriter,然后再关闭 FileStream。不是相反。
  • 有一个File.WriteAllText Method,您可以使用它来有效地替换 FileStream/FileStreamWriter 代码,其好处是它替换了当前文件,而不是在文件开头喷出数据。

标签: vb.net file-io streamwriter


【解决方案1】:

我看到的一个问题是您应该将File.Open 放在Using 块中:

Using fs = File.Open(fullyQualfiedPathName, FileMode.OpenOrCreate, FileAccess.ReadWrite)
    Using writer As New StreamWriter(fs) 'Create the stream writer
        writer.Write(writeData) 'Write the data
        'fs.Close() <--- you do not need this line becuase the "Using" block will take care of this for you.
    End Using
End Using

我不确定这是否能解决您的问题,因为我无法运行您的代码,但 Using 块会自动关闭和清理像 FileStreamStreamWriter 这样的一次性实例,甚至如果抛出异常。

顺便说一句,您应该为局部变量使用正确的命名约定(小写字母)。

【讨论】:

  • 感谢您的信息。已添加使用,但它没有解决问题。我想我记得 MSDN 告诉我,除了参数名称之外,几乎所有变量都应该是大写驼峰式?我看看能不能找到参考
  • 来自您的第二个链接:“PascalCasing 约定,用于除参数名称以外的所有标识符...”,“camelCasing 约定,仅用于参数名称...”。尽管 MSDN 确实立即自相矛盾:msdn.microsoft.com/en-us/library/aa240858(v=vs.60).aspx 所以我猜每个人都有自己的想法?
  • 在我阅读@the_lotus 评论后,您的回答实际上已经解决了问题,我删除了.Close() 并连续获得了我的End Using 鸭子并且它现在可以工作了。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-04
  • 1970-01-01
  • 1970-01-01
  • 2019-08-27
  • 2021-09-01
  • 2015-07-06
相关资源
最近更新 更多