Giriş
Şu satırı dahil
ederiz.
#include <boost/filesystem.hpp>
Linklemek için şöyle
yaparız.
g++ .... -lboost_filesystem
Eğer depricate edilmiş metodları istemezsek şöyle
yaparız.
#define BOOST_FILESYSTEM_NO_DEPRECATED
#include <boost/filesystem.hpp>
Kullanılan isim alanı uzunsa şöyle yapabiliriz.
namespace fs = boost::filesystem;
Ya da tüm sınıfları dahil etmek için şöyle
yaparız.
using namespace boost::filesystem;
C++17 ile filesystem C++ standardına
girecek.
Dosya ve Dizin Metodları - Operational Functions
Metodlar arasında dosya sahipliği ile ilgili - chown gibi - metodlar
yoktur.
absolute metodu
Şöyle
yaparız. "\\T4 2.0\\Data" gibi çözümlenen dizini "C:\\T4 2.0\\Data" haline
getirir. Yani path'i kök dizinden başlayacak hale getirir.
boost::filesystem::path from = ...;
from = boost::filesystem::absolute (from);
absolute metodu sonucunda path içinde halen "." veya ".." gibi karakterler olabilir. Bunlardan kurtulmak için canonical metodu
kullanılır.
canonical metodu
Açıklaması
şöyle.
canonical converts path p to a canonical absolute path, i.e. an absolute path that has no dot, dot-dot elements or symbolic links.
Since canonical must also dereference the symbolic links contained in the path it can only accept paths of existing files or directories.
Path içindeki "." veya ".." gibi karakterleri
siler.
Örnek 1
Şöyle
yaparız.
fs::path parentPath = fs::current_path() / "..";
std::cout << parentPath << " → " << fs::canonical(parentPath) << std::endl;
Örnek 2
Current Path şu olsun
"D:\test\build"
Bir üst dizine çıktığım ve .. karakterini sildiğim için çıktı olarak şunu alırım. Windows'ta dizin ayracı da ters çevrilir.
"D:/test"
Linux'ta ise şu çıktıyı
alırım.
"/home/myuser/build/.." → "/home/myuser"
Örnek 3
Eğer yolumuz bir dosya veya dizine çıkmıyorsa exception fırlatır. Örnek std::experimental::filesystem ile olsa da boost için de aynı şey geçerli. Şöyle
yaparız.
#include <string>
#include <iostream>
#include <experimental/filesystem>
namespace fs = std::experimental::filesystem;
int main()
{
fs::path p("/usr/include/c++/../sys/*");
p = fs::canonical(p);
}
Fırlatılan exception şu
olabilir.
boost::filesystem::current_path: No such file or directory
copy metodu - path + path
Bu metod çok iyi
çalışmıyor. Exception fırlatması gerekirken
fırlatmayabiliyor.
try
{
boost::filesystem::copy("./test.h", "./copied.cpp"); // works
boost::filesystem::copy("./test.h", "./copied.cpp"); // should throw
}
catch (...)
{
std::cout << "Caught" << std::endl; // never reached...
}
Bu metod yerine error_code alan türevi veya copy_file()
kullanılabilir.
copy_directory metodu - path + path
Şöyle
yaparız.
// test throwing upon copy_directory because source folder does not exist:
try
{
boost::filesystem::copy_directory("s", "b");
}
catch (...)
{
std::cout << "Caught" << std::endl; // works OK
}
create_directory metodu - path
Açıklaması
şöyle. Mevcut dizini bir daha yaratmak hata değil.
Creation failure because p resolves to an existing directory shall not be treated as an error.
Şöyle yaparız.
bfs::path p("...");
bfs::create_directory (p);
Aynı şeyi Windows'ta yapmak için mkdir (deprecated) veya _mkdir
kullanılabilir.
create_directory metodu - path + error_code
Şöyle
yaparız.
boost::system::error_code ec;
if (!bfs::create_directory(p, ec)) {
std::cerr << "couldn't create directory\n";
std::cerr << ec.message() << "\n";
}
create_directories metodu
Açıklaması
şöyle. Altta create_directory() metodunu çağırır.
Effect: Establishes the postcondition by calling create_directory() for any element of p that does not exist.
Postcondition: is_directory(p)
Şöyle
yaparız.
try {
bfs::path dirPath("I:\\Documents\\Directory\\SubDir\\SubSubDir\\MyFile.txt");
bfs::create_directories(dirPath.parent_path());
}
catch(const bfs::filesystem_error& err) {
std::cerr << err.what() << std::endl;
}
current_path metodu - getter
Açıklaması
şöyle
This may or may not be the location of the executable because it depends on the directory from which the program was run and whether or not the working directory has been changed by the program
Current working directory yolunu döner. Şöyle
yaparız.
bfs::path cwd (boost::filesystem::current_path());
Bu dizini yazdırmak için şöyle
yaparız.
std::cout << "Current path is " << fs::current_path() << '\n'
Çıktı olarak şunu alırım
"D:\test\build"
Aynı şeyi şöyle de
yapabilirim.
std::string cwd = getcwd (NULL, 0);
boost::filesystem::path p (cwd);
current-path - setter
Şöyle
yaparız.
try
{
boost::filesystem::current_path("/public/tst");
std::cout << "Worked" << std::endl; // works OK
}
catch (...)
{
...
}
exists metodu - path
Açıklaması
şöyle. Eğer dosyayı okuma izni yoksa exception
fırlatabilir.
bool exists(file_status s) noexcept
Returns: status_known(s) && s.type() != file_not_found
bool status_known(file_status s) noexcept
Returns: s.type() != status_error
Şöyle
yaparız.
const bfs::path filePath ("/tmp/hello.log" );
if (bfs::exists (filePath)) {...}
exists metodu - path + error_code
İmzası
şöyle. Exception fırlatmaz.
bool exists(const path& p, system::error_code& ec) noexcept;
Şöyle yaparız.
const bfs::path filePath = ...;
boost::system::error_code ec;
if(bfs::exists(filePath, ec)) {
bfs::remove(filePath);
}
file_size metodu - path
Dosyanın büyüklüğünü bulmak için kullanılır. Parametre olarak path alır. Ancak path sınıfının bir sürü explicit olmayan constructor metodu olduğu için farklı parametre tipleriyle rahatça kullanabiliriz.
char *
Şöyle
yaparız.
char* str = ...;
file_size (str);
std::string
Şöyle
yaparız.
string filename("c:\\test.zip");
long long fileSize = bfs::file_size(filename);
path
Şöyle
yaparız.
recursive_directory_iterator it = ...;
size_t size = file_size (*it);
is_directory metodu
Örnek
const path dirPath=...
if ( bfs::is_directory (dirPath) ) {...}
is_regular_file metodu - Depricated
Metodun içi
şöyle
inline bool is_regular_file(file_status f) BOOST_NOEXCEPT {
return f.type() == regular_file;
}
is_regular metodu
Metodun içi
şöyle. is_regular_file metodu ile aynı'dır. Sadece isim değiştirmiştir.
inline bool is_regular(file_status f) BOOST_NOEXCEPT {
return f.type() == regular_file;
}
is_symlink metodu
Şöyle
yaparız.
const path p = ...;if (bfs::is_symlink (p) ) {...}
last_write_time metodu - getter
Örnek
Şöyle
yaparız.
path filePath("path/to/the/file.ext");
std::cout << last_write_time(filePath) << "\n"; // Getting write/modified time
Örnek
Bu metod UTC döner. Yerel zaman çevirmek için şöyle
yaparız.
#include <boost/filesystem.hpp>
#include <boost/date_time/posix_time/posix_time_io.hpp>
#include <boost/date_time/posix_time/conversion.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/date_time/c_local_time_adjustor.hpp>
void PrintTime(boost::filesystem::path _file) {
using boost::posix_time::ptime;
using adj = boost::date_time::c_local_adjustor<ptime>;
time_t const sys_time = last_write_time(_file);
ptime const utc = boost::posix_time::from_time_t(sys_time);
ptime const local = adj::utc_to_local(utc);
std::cout << "utc: " << utc << "\n";
std::cout << "local: " << local << "\n";
{
long h{ local.time_of_day().hours() };
long m{ local.time_of_day().minutes() };
long s{ local.time_of_day().seconds() };
//...print h, m, s.
std::cout << h << ":" << m << ":" << s << '\n';
}
}
Çıktı olarak şunu
alırız.
utc: 2018-Feb-27 15:19:45
local: 2018-Feb-27 16:19:45
16:19:45
Örnek
Eğer creation time gerekiyorsa boost bunu sağlamaz. Windows'ta şöyle
yaparız.
WIN32_FIND_DATA GetFileInfo(char const *path) {
WIN32_FIND_DATA data;
HANDLE h;
h = FindFirstFile(path, &data);
FindClose(h);
return data;
}
last_write_time metodu - setter
Birinci parametre path tipindendir. İkinci parametre time_t
tipindendir.
native metodu
Açıklaması
şöyle
A name_check function returns true if its argument is valid as a directory and regular file name for a particular operating or file system. A number of these functions are provided. ...
Full path için değil, sadece dosya ismi veya dizin ismi gibi ayraç içermeyen şeyler için kullanılır. Şu kullanım
yanlıştır.
std::string p = "D:\\Programing Projects\\Debug";
if (!boost::filesystem::native(p))
{
...
}
permission metodu
Şöyle
yaparız.
bfs::path p = "...";
bfs::permissions (p, add_perms|owner_write|group_write|others_write);
read_symlink metodu
Şöyle
yaparız.
bfs::path symlink = "c:\\T4 2.0\\ApplicationSymlinks\\T4";
bfs::path path_linked_to = bfs::read_symlink (symlink);
relative metodu
Bir yoldan diğeri gitmek için geçilmesi gereken yolu verir. Şöyle
yaparız.
#include <boost/filesystem.hpp>
#include<iostream>
namespace bfs = boost::filesystem;
int main()
{
bfs::path parentPath("/home/user1/");
bfs::path childPath("/home/user1/Downloads/Books");
bfs::path relativePath = bfs::relative(childPath, parentPath);
std::cout << relativePath << std::endl;
}
remove metodu
Belirtilen dosyayı siler. İşlem başarısız olursa 'boost::filesystem::remove Access denied' gibi bir exception fırlatılır
remove_all metodu
İmzası
şöyle
boost::filesystem::remove_all(dir_to_remove)
Verilen dizin ve altındaki diğer dizin ve dosyalar silinirler. Şöyle
yaparız. İşlem başarısız olursa exception
fırlatılır
namespace bfs = boost::filesystem;
namespace bs = boost::system;
bs::error_code c;
bfs::path p("...");
if (bfs::exists(p)) {
try {
bfs::remove_all (p, c);
} catch (const boost::filesystem::filesystem_error &e) {
...
}
}
space metodu
Şöyle
yaparız.
fs::path p = ...;
fs::space_info sp = space(p);
cout<<"\n filesystem capacity is: "<< sp.capacity;
cout<<"\n filesystem free is: "<< sp.free;
cout<<"\n filesystem available is: "<< sp.available;'
status metodu
Şöyle
yaparız.
bfs::path p = ...;
bfs::file_status s = bfs::status(p);
printf("%o\n",s.permissions());
file_status sınıfının permissions metodunun imzası
şöyle
perms permissions() const noexcept;
//Returns: The value of
//permissions() specified by the postconditions of the most recent call
//to a constructor, operator=, or permissions(perms) function.
temp_directory_path
Windows'ta şöyle bir çıktı alırız.
"C:\Users\acelya\AppData\Local\Temp"
temp dizin + dosya ismi için şöyle
yaparız.
boost::filesystem::path getTemporaryFilePath()
{
auto ss = std::stringstream{};
ss << "MMap_test_" << boost::uuids::random_generator{}();
return boost::filesystem::temp_directory_path() / ss.str();
}
unique_path - default model
Bu metod güvenlik gerekçesiyle C++17'ye dahil edilmedi. Açıklaması
şöyle
unique_path was removed because it was a potential attack vector for malware. There is a window of opportunity between calling unique_path and opening a file at that location during which some other process could create the same file. Depending on what the user does with the file, this may or may not constitute a security vulnerability. A similar issue exists with the POSIX function tmpnam.
As noted in this discussion, this issue will be dealt with in the next iteration of the Filesystem library. Until then, you can either continue using Boost.Filesystem, use the std::tmpnam function provided in <cstdio>, or use safer platform-specific alternatives like mkstemp.
Bu metod temp file ismi üretir. POSIX'teki
mkstemp hem dosya ismi üretir hem de dosyayı yaratır ve file descriptor olarak döndürür. unique_path ise daha çok
std::tmpnam gibi sadece dosya ismi üretiyor. Bu metodun ismi aslında generate_random_filename() gibi bir şey olmalıydı. Eğer dosyayı da açmak istersek bu metodu şöyle kullanmak
gerekir.
for(;;) {
name = create_likley_unique_name();
file = open(name, O_EXCL | O_CREAT, mode);
if(valid(file)) {
return file;
}
}
Örnek
Şöyle
yaparız. Windows'ta şöyle bir çıktı alırız
"xxxx-xxxx-xxxx-xxxx-xxxx"
// Boost.Filesystem VERSION 3 required
#include <string>
#include <boost/filesystem.hpp>
bfs::path temp = bfs::unique_path();
const std::string tempstr = temp.native(); // optional
Dizin + dosya için şöyle
yaparız.
boost::filesystem::path filename;
filename /= boost::filesystem::temp_directory_path();
filename /= boost::filesystem::unique_path();
unique_path - model
Modeli vermek için şöyle
yaparız.
auto filename = boost::filesystem::unique_path("%%%%-%%%%-%%%%-%%%%");