【问题标题】:Random access files at clean VB.NET way以干净的 VB.NET 方式随机访问文件
【发布时间】:2013-10-15 08:37:25
【问题描述】:

在 VB.NET 工作一段时间后,我想摆脱 Microsoft.VisualBasic 依赖项。
由于文本文件和字符串操作在这里很容易,我不知道该怎么做。

是否可以在不使用 Microsoft.VisualBasic 命名空间的情况下在 VB.NET 中编写等效代码以及该代码的外观?

Dim fnum As Integer = FreeFile()
FileOpen(fnum, "Setup\myadmin", OpenMode.Random, OpenAccess.ReadWrite, OpenShare.Shared, Len(idstruct))
FilePut(fnum, idstruct, 1) 'structure data to file in record 1
FileClose(fnum)

【问题讨论】:

  • idstruct 的结构实际上是什么样的?它是否包含所有固定长度的字符串,或整数,或可变长度的字符串,或组合?您需要新代码与旧文件格式兼容,还是愿意接受新的文件格式?
  • 为什么不也放弃随机访问文件呢?可以使用 XML 吗?...
  • 嗨史蒂夫,空闲。我想保留带有数据的旧文件。这个改变我稍后会做,但现在我仍然有不同类型的程序用旧版本的 MS basic 编写,它们使用相同的文件(比如用于 DOS 的 QB4.5 :)
  • 数据是混合的,固定长度的字符串。
  • @user973238 如果你想保持文件格式,最好还是坚持FileOpen/FilePut

标签: vb.net


【解决方案1】:

尽管我很同情您希望删除对 Microsoft.VisualBasic 命名空间的所有引用,并且尽管我认为这样做很有价值,但有时它只是不值得麻烦。命名空间确实包含一些有用的工具,没有它就不容易复制。

例如,我想到了TextFieldParser。它允许您轻松读取 CSV 和固定宽度文件。 .NET 框架中没有其他类似的类。那么,为了不引用Microsoft.VisualBasic 命名空间而重新发明轮子是否值得?我认为这不值得。

虽然可以使用FileStreamStreamReaderStreamWriterBinaryReaderBinaryReaderBinaryWriter 类来重现FileGetFilePut 的行为,但这可能并不值得所有麻烦。 FileGetFilePut 方法是专门为向后兼容而提供的,所以如果与旧系统兼容是您的目标,尽管我这么说很痛苦,但使用 FileGetFilePut 是一个合适的解决方案。

但是,其中一些建议取决于数据类型。例如,如果结构只包含固定宽度的字符串,那么使用StreamReaderStreamWriterTextFieldParser 很容易复制。或者,如果它只包含整数,那么使用BinaryReaderBinaryWriter 可能很容易重现。

但是,即使您可以使用其他非 VB-only 类轻松地重现逻辑,这样做也不会为您带来任何好处。事实上,您的代码会更复杂,并且不会自我记录。当您看到使用FileGetFilePut 的代码时,不仅很容易分辨出正在做什么,而且很明显这是为了向后兼容。如果您用自己的逻辑替换它们,那么在不向代码中添加 cmets 的情况下,向后兼容的必要性将不明显。

如果您不喜欢看它们,我当然可以理解,将它们包装在包装类中可能是值得的。例如,您可以创建一个带有加载/保存方法的数据访问样式类,该类在内部只使用FileGetFilePut。无论如何,这样做将是一个好习惯。这样,如果您选择以不同的格式或不同的数据源(例如数据库)存储数据,您可以在一个类中更改它,而无需重写所有代码。

【讨论】:

  • 初读时我想到的很少。如果这些数据包含访问数据库的参数(如用户名、密码等),那么将数据存储在数据库中是不聪明(或有用)的。其次,你所谓的“向后兼容性”不应该这样称呼,因为这样不是任何向后兼容性,而是所有普通编程语言都具有的“某种磁盘访问方式”。好的,现在在大多数情况下(unicode)都缺少固定长度的字符串,但毕竟我可以得出结论,“他们没有做所有需要做的事情”!在这种情况下,Microsoft.VisualBasic 是不错的选择。
【解决方案2】:

我刚刚发现的另一件事是有关 My.Computer.FileSystem 的 MSDN 页面:

http://msdn.microsoft.com/en-us/library/0b485hf7%28v=vs.90%29.aspx

我发现是从 FilePut 上的 MSDN 页面引用的:

http://msdn.microsoft.com/en-us/library/0s9sa1ab%28v=vs.90%29.aspx

来自like this one 的帖子我的理解是无论如何它只是 System.IO 的一个包装器,但它应该为底层 IO 功能提供一个“更方便和易于理解”的接口。

【讨论】:

  • 几乎所有的 VB 命名空间,当然兼容层只是底层 NET 操作的包装器。 “方便易懂”是主观的
【解决方案3】:

看看System.IO.FileStream。方法有点不同,但很简单。

 Dim fs As New FileStream(mUserFile, FileMode.XXX, FileAccess.XXX)

或:

 Using fs as New FileStream....

 End Using

主要的改变是,与其编写结构,不如将其转换为字节数组(Count 将是数组的长度,在您的示例中偏移量为 0):

 fs.Write(byt(), lOffset, lCount)

如果有很多遗留代码需要支持,您可以将其全部封装在一个类中以模拟旧的随机访问文件方法。还有一个BinaryReaderBinaryWriter,如果数据很大但大部分是静态的,你也可以考虑序列化。

【讨论】:

  • 好吧,我总是可以读取像 bytearray 这样的文件,然后根据我的结构进行转换,或者通过添加偏移量来逐个读取元素,但这些解决方法正是我试图避免的。
  • 最初的问题只是询问了旧版 VB 文件 IO 功能的 NET equiv,并没有提到与 QB 的兼容性。既然现在揭示了这一点,我可能不会费心转换 NET 并且 XML 和序列化等某些东西特别不合适。
  • 没关系,如果我知道我的问题的答案,我不会问它。在这种情况下,保持 Microsoft.Visual basic 可能是最便宜的解决方案。
【解决方案4】:

如果您指的是您对 LEN() 函数的使用(这是我能看到的唯一一个引用 Microsoft.VisualBasic 命名空间的东西,除非我遗漏了什么),那么您可以只使用 String.Length反而。例如。 idstruct.Length,假设 idstruct 是一个字符串。

【讨论】:

猜你喜欢
  • 2010-12-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-19
  • 2015-01-10
相关资源
最近更新 更多