【问题标题】:Write vector of unsigned char to binary file c++将无符号字符向量写入二进制文件c++
【发布时间】:2017-07-31 18:15:18
【问题描述】:

我正在将二进制文件 cmd.exe 读入无符号字符数组。读入 bytes_read 的总字节数为 153。我将其转换为 base64 字符串,然后将此字符串解码回(来自第二个答案 base64 decode snippet in c++ 的代码)为向量。这里 BYTE 是无符号字符。 decodedData.size() 也是 153。但是当我以二进制模式将此向量写入文件以再次获取我的 cmd.exe 文件时,我只得到 1 KB 文件。我错过了什么?

// Reading size of file
    FILE * file = fopen("cmd.exe", "r+");
    if (file == NULL) return 1;
    fseek(file, 0, SEEK_END);
    long int size = ftell(file);
    fclose(file);
// Reading data to array of unsigned chars
    file = fopen("cmd.exe", "r+");
    unsigned char * myData = (unsigned char *)malloc(size);
    int bytes_read = fread(myData, sizeof(unsigned char), size, file);
    fclose(file);

    std::string encodedData = base64_encode(&myData[0], bytes_read);
    std::vector<BYTE> decodedData = base64_decode(encodedData);

////write data to file
    ofstream outfile("cmd.exe", ios::out | ios::binary);
    outfile.write((const char *)decodedData.data(), decodedData.size());

更新: 感谢@chux 建议 "r+" --> "rb+" 问题已解决。

【问题讨论】:

  • 1 kb 可能是最小的非空文件...你看过文件了吗?
  • 为什么在 c++ 代码中使用 fopen?
  • 如果cmd.exe是二进制的,也应该以二进制方式读取。
  • 比在 C++ 中使用 fopenfread 还要糟糕,为什么在 C++ 代码中使用 malloc
  • 建议"r+" --> "rb+"

标签: c++ file io


【解决方案1】:

您将此标记为 C++。

这是一种使用 fstream 读取二进制文件的 C++ 方法。为了简化这个例子,我创建了一个比需要的更大的 m_buff。从 cmets 看来,您的 fopen("cmd.exe", "r+") 是错误的,所以我只提供 C++ 二进制读取。

方法 tReader() a) 以二进制模式打开文件,b) 将数据读入 m_buff,c) 捕获 gCount 用于显示。

它还演示了一种可能使用 chrono 来测量持续时间的方法。

#include <chrono>
// 'compressed' chrono access --------------vvvvvvv
typedef std::chrono::high_resolution_clock  HRClk_t; 
typedef HRClk_t::time_point                 Time_t;  
typedef std::chrono::microseconds           US_t;    
using   namespace std::chrono_literals;  // suffixes 100ms, 2s, 30us

#include <iostream>
#include <fstream>
#include <cassert>

class T516_t
{
   enum BuffConstraints : uint32_t {
      Meg           = (1024 * 1024),
      END_BuffConstraints
   };

   char*   m_buff;
   int64_t m_gCount;

public:

   T516_t()
      : m_buff (nullptr)
      , m_gCount (0)
      {
         m_buff = new char[Meg];
      }

   ~T516_t() = default;

   int exec()
      {
         tReader();
         return(0);
      }

private: // methods

   void tReader()
      {
         std::string pfn = "/home/dmoen/.wine/drive_c/windows/system32/cmd.exe";
         // open file in binary mode
         std::ifstream sIn (pfn, std::ios_base::binary);

         if (!sIn.is_open()) {
            std::cerr << "UNREACHABLE:  unable to open sIn " << pfn
                      << " priviledges? media offline?";
            return;
         }

         Time_t start_us = HRClk_t::now();
         do
         {
            // perform read
            sIn.read (m_buff, Meg);
            // If the input sequence runs out of characters to extract (i.e., the
            // end-of-file is reached) before n characters have been successfully
            // read, buff contains all the characters read until that point, and
            // both eofbit and failbit flags are set

            m_gCount = sIn.gcount();

            if(sIn.eof()) { break; } // exit when no more data

            if(sIn.failbit ) {
               std::cerr << "sIn.faileBit() set" << std::endl;
            }

         }while(1);
         auto  duration_us = std::chrono::duration_cast<US_t>(HRClk_t::now() - start_us);

         sIn.close();

         std::cout << "\n  " << pfn
                   << "   " << m_gCount << " bytes"
                   << "   " << duration_us.count() << " us"
                   << std::endl;

      } // int64_t tReader()

}; // class T516_t

int main(int , char**)
{
   Time_t start_us = HRClk_t::now();

   int retVal = -1;
   {
      T516_t   t516;
      retVal = t516.exec();
   }
   auto  duration_us = std::chrono::duration_cast<US_t>(HRClk_t::now() - start_us);

   std::cout << "  FINI   " << duration_us.count() << " us" << std::endl;
   return(retVal);
}

我系统上的一个典型输出如下所示:

/home/dmoen/.wine/drive_c/windows/system32/cmd.exe   722260 bytes  1180 us   
FINI   1417 us

您的结果会有所不同。

您的 ofstream 使用看起来不错(因此没有复制)。

【讨论】:

    猜你喜欢
    • 2019-12-18
    • 2011-10-23
    • 1970-01-01
    • 2014-05-20
    • 2019-04-27
    • 1970-01-01
    • 2017-06-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多