c# - 以这种方式使用 FileStream.seek 安全吗?

标签 c# .net filestream seek

假设我有一个由一系列对象组成的文件格式,其中每个对象都有一个格式如下的标题:

public struct FileObjectHeader {
    //The type of the object (not important for this question, but it exists)
    public byte TypeID;
    //The length of the object's data, which DOES NOT include the size of the header.
    public UInt16 Length;
}

后跟指定长度的数据。

我通过首先为每个对象和对象的标题创建位置列表来读取此数据:

struct FileObjectIndex {
    public FileObjectHeader Header;
    public long Location;
}
public List<FileObject> ReadObjects(Stream s) {
    List<FileObjectReference> objectRefs = new List<FileObjectReference>();

    try {
        while (true) {
            FileObjectHeader header = ReadObjectHeader(s); 
            //The above advances the stream by the size of the header as well.
            FileObjectReference reference = new FileObjectReference() { Header = header, Position = stream.Position };
            objectRefs.add(reference);
            //Advance the stream to the next object's header.
            s.Seek(header.Length, SeekOrigin.Current);
        }
    } catch (EndOfStreamException) {
        //Do nothing as this is an expected case
    }

    //Now we'd read all of the objects that we've previously located.
    //This code isn't too important for the question but I'm including it for reference.
    List<FileObject> objects = new List<FileObject>();
    foreach (var reference in objectRefs) {
        s.seek(reference.Location, SeekOrigin.Begin);

        objects.add(ReadObject(reference.Header, s));
    }

    return objects;
}

一些注意事项:

  • 如果未能读取所有需要的数据(IE,如果它们到达流的结尾)。
  • 我在这里使用 Seek 是因为对象可以引用其他对象,并且会有逻辑来确保父对象在其子对象之前加载(文件格式不保证父对象位于子对象之前)。我没有在上面的示例代码中包含它,因为它会使示例变得复杂,但不会改进它。
  • 在大多数情况下,这可能是一个只读的 FileStream,但我也不能保证。但是,对于这种情况,我主要担心 FileStreams。

我的问题是:

因为我正在使用 FileStream.seek ,是否会使用 seek 导致超出流末尾并无限期扩展文件的情况?根据文档:

You can seek to any location beyond the length of the stream. When you seek beyond the length of the file, the file size grows. In Windows NT and later versions, data added to the end of the file is set to zero. In Windows 98 or earlier versions, data added to the end of the file is not set to zero, which means that previously deleted data is visible to the stream.

按照上述方式,它似乎可以在我不扩展到的情况下扩展文件,导致文件不断增长,因为它从 header 读取 3 个字节。实际上,这似乎不会发生,但我想确认它不会发生。

最佳答案

FileStream.Read() 的文档然而说:

Return Value
Type: System.Int32
The total number of bytes read into the buffer. This might be less than the number of bytes requested if that number of bytes are not currently available, or zero if the end of the stream is reached.

因此我强烈怀疑(但你应该自己验证这一点)这种追尾只适用于你之后写入文件的情况。这是有道理的 - 如果您知道自己需要它,您可以预留空间,而无需在其中实际写入任何内容(这会很慢)。

然而,当读取时,我的猜测是您应该返回 0 并且不会读取任何数据。此外,没有文件扩展。

关于c# - 以这种方式使用 FileStream.seek 安全吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28860951/

相关文章:

.net - 在 F# 中定义静态类

C# - 从文件中读取特定字符串的字节

c# - 将 System.IO.Stream 转换为 Byte[]

c# - MVVM 中的上下文菜单

c# - 是否有与 StreamReader 的 Peek 方法等效的异步方法?

c# - EF6,如果没有 App.config,SQLite 将无法工作

c# - 如何根据其他单元格中的值禁用(只读)DataGridView CheckBox 列中的单元格?

c# - 没有这样的主机已知 —> System.Net.Http.HttpRequestException :

c# - 使用 C# 编程格式化可移动媒体

tsql - 使用 SQL INSERT 创建带有 FileTable 的目录