gpt4 book ai didi

C# 创建带偏移量的 FileStream

转载 作者:行者123 更新时间:2023-11-30 21:56:55 27 4
gpt4 key购买 nike

问题

有没有办法在 C# 中创建带偏移量的 FileStream?例如,如果我在偏移量 100 处打开 SomeFile.binStream.Position 将等于 0,但读取和写入将偏移 100。

背景

我正在为我的公司开发一种混合文件格式,它结合了机器可读的二进制数据和现代 PC 可读的 OPC 文件(本质上是使用 System.IO.Packaging 创建的 ZIP 文件) .出于性能原因,二进制数据必须出现在文件的顶部。我知道 ZIP 文件允许这样做(例如自解压文件),但不幸的是内部 ZipIOCentralDirectoryBlock 类是 hard-coded to reject ZIP files where the first file header doesn't appear at offset 0 .为了避免临时文件(因为文件可以大到 3.99GB),我想愚弄 ZipPackage 以为它正在处理文件的开头,而实际上它正在读取 &以偏移量写入。

最佳答案

当然。这是装饰器模式的完美案例:

基本上你创建了一个类

  • 继承自 Stream(您正在装饰的抽象类)
  • 有一个接受该基类的单个实例的构造函数

然后您覆盖所有方法和属性,将调用传递给装饰实例。如果该方法或属性知道流的位置或长度,您可以根据需要应用适当的调整。

编辑注意: 看起来您需要装饰抽象流,如下所示(无法在不实际打开文件的情况下创建文件流实例).

这是装饰器本身的 [截断] 示例:

class OffsetStreamDecorator : Stream
{
private readonly Stream instance ;
private readonly long offset ;

public static Stream Decorate( Stream instance )
{
if ( instance == null ) throw new ArgumentNullException("instance") ;

FileStream decorator= new OffsetStreamDecorator( instance ) ;
return decorator;
}

private OffsetStreamDecorator( FileStream instance )
{
this.instance = instance ;
this.offset = instance.Position ;
}

#region override methods and properties pertaining to the file position/length to transform the file positon using the instance's offset

public override long Length
{
get { return instance.Length - offset ; }
}

public override void SetLength( long value )
{
instance.SetLength( value + offset );
}

public override long Position
{
get { return instance.Position - this.offset ; }
set { instance.Position = value + this.offset ; }
}

// etc.

#endregion

#region override all other methods and properties as simple pass-through calls to the decorated instance.

public override IAsyncResult BeginRead( byte[] array , int offset , int numBytes , AsyncCallback userCallback , object stateObject )
{
return instance.BeginRead( array , offset , numBytes , userCallback , stateObject );
}

public override IAsyncResult BeginWrite( byte[] array , int offset , int numBytes , AsyncCallback userCallback , object stateObject )
{
return instance.BeginWrite( array , offset , numBytes , userCallback , stateObject );
}

// etc.

#endregion

}

用法非常简单,大致如下:

using ( Stream baseStream = new FileStream( @"c:\foo\bar\somefile.dat" , FileMode.Open , FileAccess.Read , FileShare.Read ) )
{

// establish your offset
baseStream.Seek( 100 , SeekOrigin.Begin ) ;

using ( Stream decoratedStream = OffsetStreamDecorator.Decorate( baseStream ) )
{
// now you have a stream that reports a false position and length
// which you should be able to use anywhere a Stream is accepted.

PassDecoratedStreamToSomethingExpectingAVanillaStream( decoratedStream ) ;

}

}

简单! (除了涉及的所有样板)

关于C# 创建带偏移量的 FileStream,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31078598/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com