fscan/Common/output/Manager.go
ZacharyZcR 2f9c213e80 refactor: 系统性清理common包中的死代码和未使用变量
主要清理内容:
- logging包:移除DetailedFormatter、JSONFormatter及相关方法
- output包:清理Manager和Statistics中的未使用方法
- parsers包:移除各Parser中的Validate()和GetStatistics()方法
- proxy包:清理Factory和Global中的所有未使用函数
- ProgressManager:移除未使用的进度条方法和字段
- globals:清理未使用的status变量

技术改进:
- 使用deadcode和golangci-lint工具系统性检测
- 保持代码结构清晰,添加清理注释
- 修复相关依赖引用问题
- 确保编译通过和功能正常

代码减少:移除约40个死代码函数和多个未使用字段
2025-08-06 08:14:00 +08:00

255 lines
5.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package output
import (
"fmt"
"os"
"path/filepath"
"sync"
"time"
)
// Manager 输出管理器
type Manager struct {
mu sync.RWMutex
config *ManagerConfig
writer OutputWriter
reader OutputReader
statistics *Statistics
buffer []*ScanResult
bufferMutex sync.Mutex
flushTicker *time.Ticker
stopChan chan struct{}
initialized bool
closed bool
}
// NewManager 创建新的输出管理器
func NewManager(config *ManagerConfig) (*Manager, error) {
if config == nil {
return nil, fmt.Errorf("配置不能为空")
}
// 验证输出格式
if err := validateFormat(config.Format); err != nil {
return nil, err
}
// 创建输出目录
if err := createOutputDir(config.OutputPath); err != nil {
return nil, err
}
manager := &Manager{
config: config,
statistics: NewStatistics(),
stopChan: make(chan struct{}),
}
// 初始化写入器
if err := manager.initializeWriter(); err != nil {
return nil, err
}
// 初始化读取器
manager.initializeReader()
// 如果启用缓冲,初始化缓冲区
if config.EnableBuffer {
manager.buffer = make([]*ScanResult, 0, config.BufferSize)
// 如果启用自动刷新,启动定时器
if config.AutoFlush {
manager.startAutoFlush()
}
}
manager.initialized = true
return manager, nil
}
// validateFormat 验证输出格式
func validateFormat(format OutputFormat) error {
switch format {
case FormatTXT, FormatJSON, FormatCSV:
return nil
default:
return fmt.Errorf("不支持的输出格式: %s", format)
}
}
// createOutputDir 创建输出目录
func createOutputDir(outputPath string) error {
dir := filepath.Dir(outputPath)
return os.MkdirAll(dir, 0755)
}
// initializeWriter 初始化写入器
func (m *Manager) initializeWriter() error {
var writer OutputWriter
var err error
switch m.config.Format {
case FormatTXT:
writer, err = NewTXTWriter(m.config.OutputPath)
case FormatJSON:
writer, err = NewJSONWriter(m.config.OutputPath)
case FormatCSV:
writer, err = NewCSVWriter(m.config.OutputPath)
default:
return fmt.Errorf("不支持的输出格式: %s", m.config.Format)
}
if err != nil {
return fmt.Errorf("初始化写入器失败: %v", err)
}
m.writer = writer
// 写入头部(如果需要)
return m.writer.WriteHeader()
}
// initializeReader 初始化读取器
func (m *Manager) initializeReader() {
// 目前只有CSV格式支持读取
if m.config.Format == FormatCSV {
m.reader = NewCSVReader(m.config.OutputPath)
}
}
// startAutoFlush 启动自动刷新
func (m *Manager) startAutoFlush() {
m.flushTicker = time.NewTicker(m.config.FlushInterval)
go func() {
for {
select {
case <-m.flushTicker.C:
m.flushBuffer()
case <-m.stopChan:
return
}
}
}()
}
// SaveResult 保存扫描结果
func (m *Manager) SaveResult(result *ScanResult) error {
m.mu.RLock()
defer m.mu.RUnlock()
if !m.initialized {
return fmt.Errorf("输出管理器未初始化")
}
if m.closed {
return fmt.Errorf("输出管理器已关闭")
}
// 更新统计信息
m.statistics.AddResult(result.Type)
// 如果启用缓冲,先添加到缓冲区
if m.config.EnableBuffer {
return m.addToBuffer(result)
}
// 直接写入
return m.writer.Write(result)
}
// addToBuffer 添加结果到缓冲区
func (m *Manager) addToBuffer(result *ScanResult) error {
m.bufferMutex.Lock()
defer m.bufferMutex.Unlock()
m.buffer = append(m.buffer, result)
// 如果缓冲区已满,立即刷新
if len(m.buffer) >= m.config.BufferSize {
return m.flushBufferUnsafe()
}
return nil
}
// flushBuffer 刷新缓冲区(加锁版本)
func (m *Manager) flushBuffer() error {
m.bufferMutex.Lock()
defer m.bufferMutex.Unlock()
return m.flushBufferUnsafe()
}
// flushBufferUnsafe 刷新缓冲区(无锁版本,内部使用)
func (m *Manager) flushBufferUnsafe() error {
if len(m.buffer) == 0 {
return nil
}
// 批量写入
for _, result := range m.buffer {
if err := m.writer.Write(result); err != nil {
return fmt.Errorf("写入结果失败: %v", err)
}
}
// 刷新写入器
if err := m.writer.Flush(); err != nil {
return fmt.Errorf("刷新写入器失败: %v", err)
}
// 清空缓冲区
m.buffer = m.buffer[:0]
return nil
}
// =============================================================================================
// 已删除的死代码(未使用):
// GetResults, GetResultsWithFilter, GetStatistics, Flush 方法
// =============================================================================================
// Close 关闭输出管理器
func (m *Manager) Close() error {
m.mu.Lock()
defer m.mu.Unlock()
if m.closed {
return nil
}
// 停止自动刷新
if m.flushTicker != nil {
m.flushTicker.Stop()
close(m.stopChan)
}
// 最后一次刷新缓冲区
if m.config.EnableBuffer {
m.flushBufferUnsafe()
}
// 关闭写入器
var err error
if m.writer != nil {
err = m.writer.Close()
}
// 关闭读取器
if m.reader != nil {
if closeErr := m.reader.Close(); closeErr != nil && err == nil {
err = closeErr
}
}
m.closed = true
return err
}
// =============================================================================================
// 已删除的死代码(未使用):
// IsInitialized, IsClosed, GetConfig, UpdateConfig 方法
// =============================================================================================
// =============================================================================================
// 已删除的死代码未使用globalManager 全局变量及 SetGlobalManager 函数
// =============================================================================================