c++ 获取文件大小

0 filesystem

#include <iostream>
#include <filesystem>

unsigned long long getFileSize(std::filesystem::path path) {
  if (std::filesystem::status(path).type() != std::filesystem::file_type::regular) return -1;
  return std::filesystem::file_size(path);
}

int main (int argc, char *argv[]) {
  if (argc != 2) {
    printf("getFileSize.exe <filePath>\n");
    return 0;
  }
  std::filesystem::path path(argv[1]);
  unsigned long long fileSize = getFileSize(path);
  printf("%llu\n", fileSize);
  return 0;
}

1 指针移动

#include <iostream>
#include <stdio.h>
#include <iconv.h>
#include <string>
#include <string.h>
#include <fstream>
#include <sstream>

using namespace std;

unsigned long long UTF8ToGBK(char* input, size_t charInPutLen, char* output, size_t charOutPutLen)
{
    unsigned long long  ret=0;
    iconv_t cd;
    cd = iconv_open("GBK","utf-8");
    ret = iconv(cd, &input, &charInPutLen, &output, &charOutPutLen);
    iconv_close(cd);
    return ret;
}

unsigned long long UTF8ToGBK(const string& input, string& output)
{
    unsigned long long ret=0;
    char *t_output, *t_output_copy;
    int t_output_size = input.size()*2;
    t_output = (char *) malloc(t_output_size);
    t_output_copy = t_output;
    memset(t_output, 0, t_output_size);
    ret = UTF8ToGBK((char *)input.c_str(), input.size(), t_output, t_output_size);
    output = t_output;
    // iconv会改变t_output
    free(t_output_copy);
    return ret;
}

unsigned long long GBKToUTF8(char* input, size_t charInPutLen, char* output, size_t charOutPutLen)
{
    unsigned long long ret = 0;
    iconv_t cd;
    cd = iconv_open("utf-8", "GBK");
    ret = iconv(cd, &input, &charInPutLen, &output, &charOutPutLen);
    iconv_close(cd);
    return ret;
}

unsigned long long GBKToUTF8(const string& input, string& output)
{
    unsigned long long ret=0;
    char *t_output, *t_output_copy;
    int t_output_size = input.size()*2;
    t_output = (char *) malloc(t_output_size);
    t_output_copy = t_output;
    memset(t_output, 0, t_output_size);
    ret = GBKToUTF8((char *)input.c_str(), input.size(), t_output, t_output_size);
    output = t_output;
    // iconv会改变t_output
    free(t_output_copy);
    return ret;
}

long get_file_size(string path)
{
    long file_size = 0;
    const int max_path_len = 1000;
    if(path.size()>=1000)return file_size;
    char path1[max_path_len], path2[max_path_len];
    memset(path1, 0, sizeof(path1));
    memset(path2, 0, sizeof(path2));
    memcpy(path1, path.c_str(), path.size());
    UTF8ToGBK(path1, max_path_len, path2, max_path_len);

    fstream infile;
    infile.open(path2, ios::in|ios::binary);
    if(infile.is_open())
    {
        infile.seekg(0, ios::end);
        file_size = infile.tellg();
    }
    infile.close();
    return file_size;
}

long get_file_size2(string path)
{
    long file_size = 0;
    const int max_path_len = 1000;
    if(path.size()>=1000)return file_size;
    char path1[max_path_len], path2[max_path_len];
    memset(path1, 0, sizeof(path1));
    memset(path2, 0, sizeof(path2));
    memcpy(path1, path.c_str(), path.size());
    UTF8ToGBK(path1, max_path_len, path2, max_path_len);

    FILE *fp = fopen(path2, "rb");
    if(fp!= nullptr)
    {
        fseek(fp, 0, SEEK_END);
        file_size = ftell(fp);
    }
    fclose(fp);
    return file_size;
}

long get_file_size3(string path)
{
    long file_size = 0;
    UTF8ToGBK(path, path);
    cout<<path<<endl;
    fstream infile;
    infile.open(path, ios::in|ios::binary);
    if(infile.is_open())
    {
        infile.seekg(0, ios::end);
        file_size = infile.tellg();
    }
    infile.close();
    return file_size;
}

int main()
{
//    string path = "图片";
    string path = "C:\\Users\\Amazing\\Pictures\\图片\\201001110256-3_1.jpg";
//    long size = get_file_size3(path);
//    cout<<size<<endl;
    cout<<path<<endl;
    unsigned long long ret =UTF8ToGBK(path, path);
    cout<<(ret==(unsigned long long)(-1))<<endl;
    cout<<path<<endl;
    ret =UTF8ToGBK(path, path);
    cout<<(ret==(unsigned long long)(-1))<<endl;
    cout<<path<<endl;
    return 0;
}

2文件信息结构体

参考博客:https://blog.csdn.net/cpp_learner/article/details/123018360

struct stat 参考链接:https://blog.csdn.net/chen1415886044/article/details/102887154

struct stat {
    mode_t     st_mode;       //文件对应的模式,文件,目录等
    ino_t      st_ino;       //inode节点号
    dev_t      st_dev;        //设备号码
    dev_t      st_rdev;       //特殊设备号码
    nlink_t    st_nlink;      //文件的连接数
    uid_t      st_uid;        //文件所有者
    gid_t      st_gid;        //文件所有者对应的组
    off_t      st_size;       //普通文件,对应的文件字节数
    time_t     st_atime;      //文件最后被访问的时间
    time_t     st_mtime;      //文件内容最后被修改的时间
    time_t     st_ctime;      //文件状态改变时间
    blksize_t st_blksize;    //文件内容对应的块大小
    blkcnt_t   st_blocks;     //伟建内容对应的块数量
};

#include<iostream>
#include <fstream>
#include <string>
#include <sys/stat.h> // struct stat

using namespace std;


// 通过stat结构体 获得文件大小,单位字节
size_t getFileSize1(const char *fileName) {

    if (fileName == NULL) {
        return 0;
    }

    // 这是一个存储文件(夹)信息的结构体,其中有文件大小和创建时间、访问时间、修改时间等
    struct stat statbuf;

    // 提供文件名字符串,获得文件属性结构体
    stat(fileName, &statbuf);

    // 获取文件大小
    size_t filesize = statbuf.st_size;

    return filesize;
}

// 通过打开文件 获得文件大小,单位字节
long long getFileSize2(const char *fileName) {
    /* 
        解释这里为什么用_fseeki64而不用fseek:
            _fseeki64可以兼容x64项目和x86项目
            fseek只能兼容x86项目

        这里说的兼容并不是能不能用的问题,而是准不准确的问题!
        在x64项目使用fseek,返回的数据可能会不准确!
    */

    if (fileName == NULL) {
        return -1;
    }

    FILE *fp = NULL;
    long long fileSize = 0;

    // 打开文件
    errno_t err = fopen_s(&fp, fileName, "r");
    if (err != 0) { // 不等0,打开文件失败
        printf("Open file %s fail, code %d \n", fileName, err);
        return -1;
    }

    // 将文件光标位置从末尾处移动0个位置 -->也可以这样说:(将文件光标从开头位置移动到末尾位置)
    int errer = _fseeki64(fp, 0, SEEK_END);
    if (err != 0) { // 不等0,移动文件光标失败
        printf("Failed to move cursor!(SEEK_END)\n");
        return -1;
    }

    // 获得当前文件指针位置,也就是间接获得文件大小
    fileSize = _ftelli64(fp);

    /* 如果只是单纯的获取文件大小,后续没有对文件有其他操作,下面将文件指针移动回来的代码可以忽略 */
    // 将文件光标位置从开头处移动0个位置 -->也可以这样说:(将文件光标从末尾位置移动到开头位置)
    errer = _fseeki64(fp, 0, SEEK_SET);
    if (err != 0) { // 不等0,移动文件光标失败
        printf("Failed to move cursor!(SEEK_SET)\n");
        return -1;
    }

    // 关闭文件
    fclose(fp);

    return fileSize;
}

std::streampos getFileSize3(std::string fileName) {
    std::ifstream inFile;

    // 打开文件
    inFile.open(fileName, std::ios::in);
    if (inFile.is_open() == false) {    // 文件打开失败
        std::cout << "Open file " << fileName << " fail!" << std::endl;
        return -1;
    }

    // 文件指针移动到末尾位置
    inFile.seekg(0, std::ios_base::end);

    // 获取当前文件指针位置,也就是获得文件大小
    std::streampos fileSize = inFile.tellg();

    // 文件指针移动到开头文件
    inFile.seekg(0, std::ios_base::beg);

    // 关闭文件
    inFile.close();

    return fileSize;
}

int main()
{
    string file_path = "C:/Users/Amazing/Desktop/todo.txt";
    int size = getFileSize1(file_path.c_str());
    cout<<size<<endl;
    return 0;
}

文章目录