⚡文件信息管理模块⚡

目录

🌳.文件信息管理模块介绍

🌳.FileInfo类的设计

🌳. FileInfoManger类的设计(文件信息管理类)

 🍎.FileInfoManger类的成员变量

🍎.成员函数


🌳.文件信息管理模块介绍

  1. 在云备份服务器上,每一个文件都有一个FileInfo的类对象管理该文件的信息,包括文件压缩标志,文件大小,最近访问时间,修改时间,压缩路径,备份路径。
  2. 备份在云服务器的所有文件信息用json字符串的形式备份在一个backfileinfo文件持久化存储。
  3. 当服务器在启动的时候,文件信息管理模块会将backfileinfo文件中的所有的文件信息读取上来,将
  4. 所有的文件信息以备份路径-FileInfo的形式进行映射在哈希表中,方便服务器查询文件信息。

🌳.FileInfo类的设计

FileInfo类的变量:

  • 压缩标志:用来判断文件是否被压缩
  • 备份路径:文件存储在热点的目录的路径,一般为/packdir/test.txt
  • 压缩路径:文件存储在非热点目录的路径,一般为/backdir/test.txt
  • url:文件下载请求的路径,一般为/download/test.txt
  • 文件大小
  • 最后一次访问的时间
  • 最后一次修改的时间

FileInfo类的构造函数,使用配置模块和文件工具类初始化FileInfo中的成员变量

 #include"Config.hpp"   
  class FileInfo{                         
      public:                                 
        bool pack_sign;    
        size_t file_size;                               
        time_t access_time;    
        time_t modify_time;       
        std::string back_path;    
        std::string pack_path;                      
        std::string url;                     
      public:                     
        FileInfo(const std::string& backpath){                     
          AddFileInfo(backpath);                                   
        }                                                         
        FileInfo(){}                                              
        bool AddFileInfo(const std::string& backpath){         
          sjp::FileUtil fu(backpath.c_str());                   
          file_size=fu.GetFileSize();                  
          pack_sign=false;       
          access_time=fu.GetFileAccessTime();    
          modify_time=fu.GetFileModfityTime();    
          back_path=sjp::Config::GetInstant()->GetBackDir();    
          back_path+=fu.GetFilename();    
          pack_path=sjp::Config::GetInstant()->GetPackDir();    
          pack_path+=fu.GetFilename();    
          pack_path+=sjp::Config::GetInstant()->GetPackFileSuffix();    
          url="/download/";    
          url+=fu.GetFilename();    
          return true;                                  
        }                               
    };    

🌳. FileInfoManger类的设计(文件信息管理类)

 🍎.FileInfoManger类的成员变量

  • file_info_path:backfileinfo文件路径,方便加载文件信息。
  • _table:哈希表,将文件的备份路径与文件信息映射起来,方便服务器能够查找文件信息。
  • _rwlock:读写锁,保证信息管理模块在访问和修改哈希表的过程中线程安全的。

🍎.成员函数

InitLoad函数

InitLoad函数的功能加载backfileinfo文件中的所有的文件信息加载到FileInfoManger对象里面。

        //将文件上的信息加载到内存中
        bool InitLoad(){
          /*
           * 1.打开备份文件的存储信息
             2.将存储信息读取到body中
             3.将body进行反序列化为root;
             4.将各个文件信息加载到table中
          */
          sjp::FileUtil fu(file_info_path.c_str()); 
          std::string body;
          fu.GetContent(body);
          Json::Value root;
          sjp::JsonUtil::UnSerialize(root,body);
W>        for(int i=0;i<root.size();i++){
            FileInfo fileinfo;
            fileinfo.access_time=root[i]["AccessTime"].asInt();
            fileinfo.modify_time=root[i]["ModifyTime"].asInt();
            fileinfo.back_path=root[i]["BackPath"].asString();
            fileinfo.pack_path=root[i]["PackPath"].asString();
            fileinfo.file_size=root[i]["FileSize"].asInt();
            fileinfo.pack_sign=root[i]["PackSign"].asBool();
            fileinfo.url=root[i]["Url"].asString();
            Insert(fileinfo);
          }
        
          return true;
        }
  

UpdateFileInfo函数 

UpdateFileInfo的功能是查看backdir下的文件信息是否全都存储在backfileinfo,如果某些文件没有存储,则将该文件的信息存储进backfileinfo里面。

实现思路:

  • 获取backdir下的所有文件,将所有的文件与_table进行比对。
  • 如果某个文件在_table中没有找到,说明该文件信息没有持久化进backfileinfo文件里,创建该文件信息,将该文件的信息插入到_table,最后在将更新backfileinfo中的数据。
        bool UpdateFileInfo(){
          std::string path=sjp::Config::GetInstant()->GetBackDir();
          sjp::FileUtil fu(path);
          std::vector<std::string> arry;
          fu.GetPathInDir(arry);
  
W>        for(int i=0;i<arry.size();i++){
            auto it=_table.find(arry[i]);
            if(it==_table.end()){
              //>
              //没有将该文件信息存储到信息系统中
              sjp::FileInfo fileinfo(arry[i]); 
              Insert(fileinfo);
            }
          }
          Storage();
W>      }

 Storage函数 

 Storage函数的功能将_table中的所有信息持久化存储到backfileinfo文件里面。

实现思路:

  • 将_table上的所有的文件信息都存储在Json::Value root中,在将root序列化为Json字符串,最后再通过文件工具类打开backfileinfo文件,将Json字符串写入到backfile文件中。
        //将table上的所有信息存储持久化到文件上
        bool Storage(){
          //将文件的备份信息反序列化字符并组织到body上
          std::string filebody;
            Json::Value root; 
           std::string body;
           auto it=_table.begin();
           int i=0;
          while(it!=_table.end())
          {
           root[i]["AccessTime"]=(Json::Int)it->second.access_time;    
           root[i]["ModifyTime"]=(Json::Int)it->second.modify_time;    
           root[i]["FileSize"]=(Json::Int)it->second.file_size;    
           root[i]["Url"]=it->second.url;    
           root[i]["PackSign"]=it->second.pack_sign;                                                                                                                                        
           root[i]["BackPath"]=it->second.back_path;    
           root[i]["PackPath"]=it->second.pack_path;
           i++;
           it++;
          }
          sjp::JsonUtil::Serialize(root,body);
          sjp::FileUtil fu(file_info_path.c_str());
          if(!fu.SetContent(body))
          {
            return false;
          }
          return true;
        }
  

UpdatePackSign函数

UpdatePackSign函数的功能是将packdir中的下文件信息中的压缩标志为false,则更改为true,表示该文件已经被压缩。

        bool UpdatePackSign(){
          cout<<"Updatepacksign"<<endl;
          auto it=_table.begin();
          while(it!=_table.end()){
            sjp::FileUtil fu(it->second.pack_path);
            if(fu.Exist()){
              it->second.pack_sign=true;
              Insert(it->second);
            }
            it++;
          }
          Storage();
W>      }

 构造函数

  • 云备份服务器启动时,需要先使用InitLoad函数将backfileinfo中的文件加载到_table中。
  • 利用UpdateFileInfo函数更新backdir目录下的文件没有存放进backfileinfo文件信息。
  • 利用 UpdatePackSign函数将packdir目录下文件的文件信息的压缩标志是false修改为true;
        FileInfoManger(){
          file_info_path=Config::GetInstant()->GetBackFileInfo();
          pthread_rwlock_init(&_rwlock,NULL);
          InitLoad(); 
          UpdateFileInfo();
          UpdatePackSign();
        }
  

其它函数

  #pragma once                                                                                                                                                                              
  #include"Config.hpp"      
  #include<unordered_map>    
  #include<pthread.h>                    
  namespace sjp{                         
    class FileInfoManger{                                                                                                                                                                   
      private:
        std::string file_info_path;//存储文件信息的持久化文件
        std::unordered_map<std::string,FileInfo> _table; //backpath-info
        pthread_rwlock_t _rwlock;//读写锁
      private:
        static FileInfoManger* instant;
        static std::mutex lock;
      private:

        FileInfoManger(FileInfoManger&)=delete;
      public:

        static FileInfoManger* GetInstant(){    
            if(instant==nullptr){    
              lock.lock();    
              if(instant==nullptr){    
                instant=new FileInfoManger();    
              }    
              lock.unlock();    
            }    
            return instant;    
          }     

              //插入信息
        bool Insert(const FileInfo& info){
           pthread_rwlock_wrlock(&_rwlock);
           _table[info.back_path]=info;
           pthread_rwlock_unlock(&_rwlock);
           return true;
        }
        //更新信息
        bool update(const FileInfo& info){
           pthread_rwlock_wrlock(&_rwlock);
           _table[info.back_path]=info;
           pthread_rwlock_unlock(&_rwlock);
           return true;
        }         

        //通过backpath判断该文件是否存在
        bool Exist(const std::string& backpath)
        {
          auto it=_table.find(backpath);
          if(it!=_table.end()){
            return true;
          }
          return false;
        }
  
        //通过url获取文件信息
        bool GetoneByURL(const std::string& url,FileInfo& info){
          sjp::FileUtil fu(url);        
          std::string backpath=sjp::Config::GetInstant()->GetBackDir();
          backpath+=fu.GetFilename();
          return  GetOneByRealPath(backpath,info);
        }
  
        //通过相对路径获取文件信息
        bool GetOneByRealPath(const std::string& backpath,FileInfo& info){
          auto it=_table.find(backpath);
          if(it!=_table.end()){
            info=it->second;
            return true;
          }
           return false;
        }
                                  
       //获取所有备份文件的文件信息
        bool GetAllInfo( std::vector<FileInfo>& arry){
          pthread_rwlock_wrlock(&_rwlock);
          auto it=_table.begin();
          while(it!=_table.end())
          {
            arry.push_back(it->second);
            it++;
          }
          pthread_rwlock_unlock(&_rwlock);
          return true;
        }

        ~FileInfoManger(){
          Storage();
        }
    };
    FileInfoManger* FileInfoManger::instant=nullptr;
    std::mutex FileInfoManger::lock;
  }                                          
                                                     

<think>我们正在使用ADB抓取手机充电模块的日志。根据之前的引用[1]和[2],我们知道ADB是一个强大的调试工具,可以抓取日志。引用[3]提到adb logcat和adb bugreport可以获取日志,其中bugreport包含更全面的信息,但logcat更适合实时抓取特定模块的日志。 用户需求:抓取手机充电模块的日志。 步骤: 1. 连接手机并确保ADB可用(参考之前的准备步骤)。 2. 使用logcat命令,并过滤与充电相关的标签或关键字。 充电模块在Android系统中通常与电池服务相关,常见的日志标签包括: - "BatteryService" - "battery" - "healthd"(电池健康守护进程) - 可能还有电源管理相关的标签,如"PowerManagerService" 我们可以使用以下命令抓取充电日志: ```bash # 清除旧日志,避免干扰 adb logcat -c # 开始抓取充电相关日志,并保存到文件 adb logcat -v time | grep -E "BatteryService|batteryd|battery|healthd|PowerManagerService" > charge.log ``` 注意: - 在Windows中,`grep`命令不可用,可以使用`findstr`代替: ```bash adb logcat -v time | findstr "BatteryService batteryd battery healthd PowerManagerService" > charge.log ``` - 如果只想抓取错误级别的日志,可以加上优先级过滤: ```bash adb logcat -v time *:E | findstr "BatteryService|batteryd|battery|healthd|PowerManagerService" > charge_error.log ``` 另外,引用[3]提到可以使用`adb bugreport`获取更全面的日志,但bugreport不是实时抓取的,而是在命令执行时生成一个包含多个日志文件的压缩包。如果需要更详细的信息(包括系统状态、内核日志等),可以在复现问题后立即执行: ```bash adb bugreport ``` 然后从生成的bugreport压缩包中查找电池相关的日志(通常在`bugreport-<设备名>-<时间>.zip`中解压后,查看FS文件夹下的`batterystats`等文件,或者查看main_log.txt等日志文件)。 但是,由于用户明确要求使用ADB抓取充电模块日志,且希望实时抓取,因此推荐使用logcat命令。 操作步骤总结: 1. 确保手机通过USB连接电脑,并已授权USB调试。 2. 打开命令提示符(CMD)或终端,进入ADB所在目录。 3. 清除旧日志:`adb logcat -c` 4. 开始抓取充电日志(使用findstr过滤): ```cmd adb logcat -v time | findstr "BatteryService batteryd battery healthd PowerManagerService" > charge.log ``` 5. 此时在手机上操作,比如插拔充电器,让问题复现。 6. 操作完成后,按Ctrl+C停止抓取。 7. 打开charge.log文件分析。 注意:如果过滤的关键字过多导致抓不到日志,可以尝试减少关键字,或者先不进行过滤,抓取全部日志后再搜索。但这样文件会很大。 如果充电问题涉及内核层,还可以尝试抓取内核日志: ```cmd adb shell dmesg | findstr "battery" > dmesg.log ``` 最后,在分析日志时,可以关注以下信息: - 电池状态(充电中、放电中、满电等) - 电池温度 - 充电电流和电压 - 充电状态变化(比如从交流充电切换到USB充电) - 异常信息(如过温保护、过流保护等) 例如,在日志中可能会看到类似这样的条目: ``` 06-25 10:15:32.123 I/BatteryService: Charging status changed: 2 (Charging) 06-25 10:15:32.456 I/BatteryService: Charger type: AC 06-25 10:15:32.789 E/BatteryService: Over temperature! stop charging. ``` 这样,我们就完成了充电模块日志的抓取。</think>### 使用ADB抓取手机充电模块日志的详细步骤 #### 🔋 1. 准备工作 - 确保手机已开启**开发者选项**和**USB调试**模式(设置→关于手机→连点版本号7次) - 安装最新版ADB工具([下载地址](https://developer.android.com/studio/releases/platform-tools)) - 使用原装数据线连接手机与电脑 #### 2. 抓取充电日志的核心命令 ```bash # 清除旧日志 adb logcat -c # 抓取充电相关日志(带时间戳) adb logcat -v time | findstr "battery|charger|power" > charge_log.txt ``` #### 🔍 3. 关键过滤参数说明 | 过滤标签 | 作用 | 示例 | |---------|------|------| | `battery` | 电池状态变化 | `BatteryService` | | `charger` | 充电器连接事件 | `ChargerConnection` | | `power` | 电源管理事件 | `PowerManagerService` | | `healthd` | 电池健康守护进程 | `healthd: battery l=50` | | `qc_` | 高通充电协议 | `qc_battery_charger` | #### 📊 4. 高级日志抓取技巧 ```bash # 仅抓取错误级别充电日志 adb logcat *:E | findstr "battery" > charge_error.log # 实时监控充电状态变化 adb logcat -v time | findstr "BatteryService" # 获取内核级充电信息(需root) adb shell dmesg | findstr "charger" > kernel_charge.log ``` #### 🔬 5. 日志关键信息解析 充电日志中需关注的核心参数: ```log 07-10 14:30:22.511 I/BatteryService: [充电状态] status=2 (充电中) 07-10 14:30:23.142 I/BatteryService: [电池信息] level=85% voltage=4350mV temp=32°C 07-10 14:30:25.811 D/QC-Power: [充电协议] type=PD current=3000mA 07-10 14:31:10.225 E/BatteryService: [异常] CHARGE_FAILED → 温度保护触发 (temp=48°C) ``` - **status值含义**: - `1`:未充电 - `2`:充电中 - `4`:放电中 - `5`:满电 - **常见错误码**: - `CHARGE_FAILED`:充电失败 - `OVERHEAT`:过热保护 - `OVER_VOLTAGE`:过压保护 #### 🛠 6. 增强型日志收集 ```bash # 获取完整电池诊断报告(Android 7.0+) adb shell dumpsys battery > battery_stats.txt # 收集充电历史记录 adb shell dumpsys batterystats --charged > charge_history.txt # 生成完整BUG报告(包含内核日志) adb bugreport ``` > 生成的`bugreport.zip`需解压后查看`FS/data/system/batterystats`目录 #### 📌 注意事项 1. 抓取时复现充电问题(如插拔充电器、充电中断等) 2. 安卓9+需授权存储权限: `adb shell appops set android LOG_TO_STORAGE allow` 3. 使用`Ctrl+C`停止日志记录 4. 敏感数据脱敏:`adb logcat -P "xxx"` #### 🔎 日志分析工具推荐 1. **Battery Historian**:谷歌官方电池分析工具 `python historian.py -a battery_stats.txt > report.html` 2. **Logcat Extreme**(Android):实时过滤充电日志 3. **GrepWin**(Windows):快速搜索日志关键词 > 示例:分析充电慢问题 > ```bash > adb logcat -v time | findstr "BatteryService current" > slow_charge.log > ``` > 查看输出中的`current=`值是否低于充电器标称值 --- ### 充电日志分析流程图 ```mermaid graph TD A[开始抓取日志] --> B{问题复现} B -->|充电中断| C[过滤“CHARGE_FAILED”] B -->|充电慢| D[检查“current=”值] B -->|过热保护| E[分析“temp=”曲线] C --> F[检查错误码和温度] D --> G[对比充电器标称电流] E --> H[检查环境温度] F --> I[生成诊断报告] G --> I H --> I I --> J[解决方案] ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值