完善 Windows 运维封装与 NTFS 索引解析
- 新增自启动幂等配置、统一错误语义、进程等待和进程树终止能力 - 增强服务生命周期管理,支持等待状态、重启、幂等创建和配置更新 - 新增 NTFS 卷索引、文件 ID 解析、文件遍历、USN 变更监听和 bookmark 持久化 - 修复 NTFS boot sector、fragment、MFT、USN 解析边界和路径重建问题 - 补充权限、进程、服务、NTFS 解析和工作流回归测试 - 增加 Windows 测试脚本和管理员 NTFS smoke 验证脚本 - 升级 Go 兼容版本到 1.18,并更新 stario、win32api 及相关间接依赖
This commit is contained in:
+26
-15
@@ -1,25 +1,24 @@
|
||||
/*
|
||||
Package fragment contains a Reader which can read Fragments which may be scattered around a volume (and perhaps even
|
||||
not in sequence). Typically these could be translated from MFT attribute DataRuns. To convert MFT attribute DataRuns
|
||||
to Fragments for use in the fragment Reader, use mft.DataRunsToFragments().
|
||||
Package fragment contains a Reader which can read Fragments which may be scattered around a volume (and perhaps even
|
||||
not in sequence). Typically these could be translated from MFT attribute DataRuns. To convert MFT attribute DataRuns
|
||||
to Fragments for use in the fragment Reader, use mft.DataRunsToFragments().
|
||||
|
||||
Implementation notes
|
||||
# Implementation notes
|
||||
|
||||
When the fragment Reader is near the end of a fragment and a Read() call requests more data than what is left in
|
||||
the current fragment, the Reader will exhaust only the current fragment and return that data (which could be less
|
||||
than len(p)). A next Read() call will then seek to the next fragment and continue reading there. When the last
|
||||
fragment is exhausted by a Read(), it will return the remaining bytes read and a nil error. Any subsequent Read()
|
||||
calls after that will return 0, io.EOF.
|
||||
When the fragment Reader is near the end of a fragment and a Read() call requests more data than what is left in
|
||||
the current fragment, the Reader will exhaust only the current fragment and return that data (which could be less
|
||||
than len(p)). A next Read() call will then seek to the next fragment and continue reading there. When the last
|
||||
fragment is exhausted by a Read(), it will return the remaining bytes read and a nil error. Any subsequent Read()
|
||||
calls after that will return 0, io.EOF.
|
||||
|
||||
When accessing a new fragment, the Reader will seek using the absolute Length in the fragment from the start
|
||||
of the contained io.ReadSeeker (using io.SeekStart).
|
||||
When accessing a new fragment, the Reader will seek using the absolute Length in the fragment from the start
|
||||
of the contained io.ReadSeeker (using io.SeekStart).
|
||||
*/
|
||||
package fragment
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
// Fragment contains an absolute Offset in bytes from the start of a volume and a Length of the fragment, also in bytes.
|
||||
@@ -33,22 +32,25 @@ type Fragment struct {
|
||||
// fragment has been exhaused, each subsequent Read() will return io.EOF.
|
||||
type Reader struct {
|
||||
src io.ReadSeeker
|
||||
closer io.Closer
|
||||
fragments []Fragment
|
||||
idx int
|
||||
remaining int64
|
||||
file *os.File
|
||||
}
|
||||
|
||||
// NewReader initializes a new Reader from the io.ReaderSeeker and fragments and returns a pointer to. Note that
|
||||
// fragments may not be sequential in order, so the io.ReadSeeker should support seeking backwards (or rather, from the
|
||||
// start).
|
||||
func NewReader(src io.ReadSeeker, fragments []Fragment) *Reader {
|
||||
return &Reader{src: src, fragments: fragments, idx: -1, remaining: 0}
|
||||
r := &Reader{src: src, fragments: fragments, idx: -1, remaining: 0}
|
||||
if closer, ok := src.(io.Closer); ok {
|
||||
r.closer = closer
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func (r *Reader) Read(p []byte) (n int, err error) {
|
||||
if r.idx >= len(r.fragments) {
|
||||
r.src.(*os.File).Close()
|
||||
return 0, io.EOF
|
||||
}
|
||||
|
||||
@@ -81,3 +83,12 @@ func (r *Reader) Read(p []byte) (n int, err error) {
|
||||
r.remaining -= int64(n)
|
||||
return n, err
|
||||
}
|
||||
|
||||
func (r *Reader) Close() error {
|
||||
if r.closer == nil {
|
||||
return nil
|
||||
}
|
||||
err := r.closer.Close()
|
||||
r.closer = nil
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user