我想将一个文件从目录复制到另一个文件,但我的程序总是因为某些原因而中止.有没有人这样做之前可以告诉我出了什么问题?我怎么能抓住异常被抛出copy_file,我检查了boost网站,但我找不到任何有关异常的相关信息.
path user_path( "C:\\My Folder" );
boost::filesystem::create_directory( user_path );
path file( "C:\\Another\\file.txt" );
boost::filesystem::copy_file( file, user_path );
Run Code Online (Sandbox Code Playgroud)
谢谢,
我使用以下方法递归遍历目录中的所有文件:
try
{
for ( bf::recursive_directory_iterator end, dir("./");
dir != end; ++dir )
{
const bf::path &p = dir->path();
if(bf::is_regular_file(p))
{
std::cout << "File found: " << p.string() << std::endl;
}
}
} catch (const bf::filesystem_error& ex) {
std::cerr << ex.what() << '\n';
}
Run Code Online (Sandbox Code Playgroud)
但这包括隐藏文件和隐藏目录中的文件.
如何过滤掉这些文件?如果需要,我可以将自己限制在隐藏文件和目录以'.'开头的平台上.字符.
我用boost::filesystem::directory_iterator它来获取给定文件夹中所有可用文件的列表.
问题是我认为这种方法会按字母顺序给我文件,而结果似乎很随机.
是否有按字母顺序排序的奇特方式?
我目前的代码:
if(boost::filesystem::is_directory(myFolder)){
// Iterate existing files
boost::filesystem::directory_iterator end_iter;
for(boost::filesystem::directory_iterator dir_itr(myFolder);
dir_itr!=end_iter; dir_itr++){
boost::filesystem::path filePath;
// Check if it is a file
if(boost::filesystem::is_regular_file(dir_itr->status())){
std::cout << "Reading file " << dir_itr->path().string() << std::cout;
}
}
}
Run Code Online (Sandbox Code Playgroud) 使用boost :: filesystem :: exists时,我遇到了一些奇怪的情况.如果您尝试检查未准备好的驱动器上的文件是否存在或者没有介质,则会抛出basic_filesystem_error.至于我对bfs :: exists的大部分用法都很关注,如果驱动器没有准备好,则意味着该文件不存在.
我可以用try-catch包装我的调用以正确处理这个条件,但是它变得有点麻烦并且使代码有点笨拙.更糟糕的是,这意味着我正在使用basic_filesystem_error的特殊情况进行流控制,这意味着如果出现该异常的不同原因,我将不再适当地处理它.
出现这种情况的一般情况是,如果我尝试检查CD或DVD驱动器上是否存在文件.我以前的代码是:
if( bfs::exists( myFilePath ) )
{
...
}
Run Code Online (Sandbox Code Playgroud)
变为:
bool fileExists( false );
try
{
fileExists = bfs::exists( myFilePath );
}
catch( bfs::basic_filesystem_error<bfs::path> e )
{
fileExists = false;
}
if( fileExists )
{
...
}
Run Code Online (Sandbox Code Playgroud)
我并不太喜欢在我现有的代码库中进行这种改变的想法.
我正在考虑在某个地方创建一个单独的函数来包装try-catch并用它替换我的bfs :: exist调用,但我仍然不满意以这种方式使用try-catch是一个好主意.似乎我正在打开错过更重要和相关的特殊条件的大门.
我知道你可以为非抛出版本的函数重新编译boost,但我认为这并不能真正避免我的异常处理问题.
有没有人在使用可移动媒体驱动器之前遇到这个问题,如果是这样,你是如何克服它的?
我想创建一个目录path = "$HOME/somedir".
我尝试过使用boost::filesystem::create_directory(path),但它失败了 - 显然该功能不会扩展系统变量.
我怎么能以最简单的方式做到这一点?
(注意:在我的情况下,字符串path是常量,我不确定它是否包含变量)
编辑:我正在Linux上工作(虽然我计划在不久的将来将我的应用程序移植到Windows).
我正在尝试使用增强路径执行几乎任何操作,从而获得一致的段错误.
(编辑:似乎所有segfaulting函数都与之相关current_path())
Sample program:
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
#include <iostream>
using namespace std;
using namespace boost::filesystem;
using namespace boost::system;
int main(int argc, const char * argv[])
{
error_code err;
auto p = path("hello/../world");
cout << p.string() << endl;
path c = canonical(p, err);
cout << c.string() << endl;
}
Run Code Online (Sandbox Code Playgroud)
以上只是一个例子,以下也是段错:
auto p = current_path(err);
和:
auto p = initial_path(err);
编译:
g++-4.9 -lboost_filesystem -lboost_system -std=c++11 main.cpp -o ./path-test
输出:
hello/../world
Segmentation fault: 11
Run Code Online (Sandbox Code Playgroud)
通过Homebrew安装GCC和Boost . …
来自boost/filesystem/path.hpp:
# ifdef BOOST_WINDOWS_API
const std::string string() const
{
[...]
}
# else // BOOST_POSIX_API
// string_type is std::string, so there is no conversion
const std::string& string() const { return m_pathname; }
[...]
# endif
Run Code Online (Sandbox Code Playgroud)
对于wstring(),它恰恰相反 - 在Windows上通过引用返回,在POSIX上通过值返回.有一个有趣的原因吗?
std::string file="C:\\folder1\\folder2\\folder3.txt";
fs::path file_path(file);
fs::path file_dir=file_path.parent_path();// "C:\\folder1\\folder2";
std::string str_path=file_path.string();
std::string str_dir=file_dir.string();
std:string str_folder=str_path.erase(0,str_dir()+1);// return folder2
Run Code Online (Sandbox Code Playgroud)
这是我使用的方法。它对我有用,但看起来很难看。所以我更喜欢寻找 boost::filesystems 或其他优雅的代码。注意:这个问题不重复,与提出的问题Get a directory name from a filename略有不同 。我的兴趣是找到文件名而不是整个目录路径。
我们将路径表示为boost::filesystem::path,但在某些情况下,其他API期望它们const char *(例如,使用SQLite打开DB文件).
从文档中,path::value_type是一个wchar_tWindows下.据我所知,Windows wchar_t是2字节,UTF-16编码.
有一个string()原生观察者返回一个std::string,同时说明:
如果string_type是与String不同的类型,则转换由cvt执行.
cvt被初始化为默认构造codecvt.这个默认构造的codecvt的行为是什么?
有这个论坛条目,建议使用一个实例utf8_codecvt_facet作为cvt值可移植转换为UTF-8.但似乎这个codecvt实际上是在UTF-8和UCS-4之间转换,而不是UTF-16.
什么是最好的方式(如果可能的话,便携式)获得a的std::string表示path,确保wchar_t在必要时从正确的编码转换?
我正在将一些代码转换boost::filesystem为std::filesystem.使用的先前代码boost::filesystem::last_write_time()返回time_t与time_t我已经持有的对象如此直接的比较是微不足道的.顺便说一下,这个time_t我持有的文件内容很久以前就已经存在了,所以我坚持使用这个"自unix epoch以来的时间"类型.
std::filesystem::last_write_time返回一个std::filesystem::file_time_type.是否有可移植的方式将a转换file_time_type为a time_t或以其他方式可比较两个对象?
#include <ctime>
#include <filesystem>
std::time_t GetATimeInSecondsSince1970Epoch()
{
return 1207609200; // Some time in April 2008 (just an example!)
}
int main()
{
const std::time_t time = GetATimeInSecondsSince1970Epoch();
const auto lastWriteTime = std::filesystem::last_write_time("c:\\file.txt");
// How to portably compare time and lastWriteTime?
}
Run Code Online (Sandbox Code Playgroud)
编辑:请注意cppreference.comlast_write_time上的示例代码表示它假设时钟是std::chrono::system_clock实现该to_time_t功能的状态.这个假设并不总是如此,并不在我的平台上(VS2017).
boost-filesystem ×10
c++ ×10
boost ×7
c++-chrono ×1
directory ×1
encoding ×1
gcc ×1
hidden-files ×1
macos ×1
utf-8 ×1