使用boost :: filesystem将文件路径从Windows转换回linux并再次返回

时间:2013-04-05 18:12:36

标签: c++ linux windows path boost-filesystem

是我,还是boost :: filesystem :: path :: make_preferred不将“\”转换为“/”?

  

davidan @ kempt:〜/ Documents / prog / work!$ ../practice/./path_info c:\ pitou foo / bar \ baa.txt
  组成路径:
   cout<< -------------:“c:pitou / foo / bar \ baa.txt”
   make_preferred()----------:“c:pitou / foo / bar \ baa.txt”

我非常希望

  

C:\鼻头\ FOO \条\ baa.txt

在Windows和

  

/pitou/foo/bar/baa.txt

POSIX

上的

(或接近的东西)

来源位于:boost::filesystem tutorial

3 个答案:

答案 0 :(得分:2)

在Linux上没有处理它的原因在这里很好地解释了:

http://theboostcpplibraries.com/boost.filesystem-paths

引用:

  

如果在Linux上执行例35.5,则返回值为   不同。大多数成员函数返回一个空字符串,除了   relative_path()和filename(),返回" C:\ Windows \ System"。这个   表示字符串“C:\ Windows \ System”被解释为文件   在Linux上的名称,这是可以理解的,因为它既不是   路径的可移植编码或依赖于平台的编码   Linux操作系统。因此,Boost.Filesystem别无选择,只能解释它   作为文件名。

答案 1 :(得分:1)

结束这样做:

string f = filename;
#       ifdef BOOST_POSIX_API   //workaround for user-input files
            std::replace(f.begin(), f.end(), '\\', '/');        
#       endif

必须有一个原因,为什么这还没有处理......?

答案 2 :(得分:0)

这不使用boost,但是我手动实现了两个转换方向。

FileSystemPathUtils.hpp

#pragma once

#include <string>

static const char *const WSL_FILE_PATH_HEADER = "/mnt";
static const char WINDOWS_FILE_PATH_SEPARATOR = '\\';
static const char UNIX_FILE_PATH_SEPARATOR = '/';

std::string windows_to_unix_file_path(std::string file_path, bool is_wsl = true);

std::string unix_to_windows_file_path(std::string file_path, bool is_wsl = true);

std::string windows_path_to_host_operating_system_path(std::string file_path, bool is_wsl = true);

FileSystemPathUtils.cpp

#include "FileSystemPathUtils.hpp"

#include <string>
#include <algorithm>
#include <sstream>
#include <utility>
#include <cstring>

std::string windows_to_unix_file_path(std::string file_path, bool is_wsl) {
    // Replace the slashes
    std::replace(file_path.begin(), file_path.end(), WINDOWS_FILE_PATH_SEPARATOR, UNIX_FILE_PATH_SEPARATOR);

    // Convert the drive letter to lowercase
    std::transform(file_path.begin(), file_path.begin() + 1, file_path.begin(),
                   [](unsigned char character) {
                       return std::tolower(character);
                   });

    // Remove the colon
    const auto drive_letter = file_path.substr(0, 1);
    const auto remaining_path = file_path.substr(2, file_path.size() - 2);
    file_path = drive_letter + remaining_path;

    std::stringstream stringstream;

    if (is_wsl) {
        stringstream << WSL_FILE_PATH_HEADER;
    }

    stringstream << "/";
    stringstream << file_path;

    return stringstream.str();
}

std::string unix_to_windows_file_path(std::string file_path, bool is_wsl) {
    if (is_wsl) {
        file_path = file_path.erase(0, strlen(WSL_FILE_PATH_HEADER));
    }

    // Delete the leading forward slash
    file_path.erase(0, 1);

    // Convert the drive letter to uppercase
    std::transform(file_path.begin(), file_path.begin() + 1, file_path.begin(),
                   [](unsigned char character) {
                       return std::toupper(character);
                   });

    // Replace the slashes
    std::replace(file_path.begin(), file_path.end(), UNIX_FILE_PATH_SEPARATOR,
                 WINDOWS_FILE_PATH_SEPARATOR);

    std::stringstream stringstream;
    stringstream << file_path.at(0);
    stringstream << ":";
    stringstream << file_path.substr(1, file_path.size() - 1);

    return stringstream.str();
}

std::string windows_path_to_host_operating_system_path(std::string file_path, bool is_wsl) {
#ifdef _WIN32
    return file_path;

#else
    return windows_to_unix_file_path(std::move(file_path), is_wsl);

#endif
}