📄 file_unix.cpp
字号:
//// File_UNIX.cpp//// $Id: //poco/1.2/Foundation/src/File_UNIX.cpp#1 $//// Library: Foundation// Package: Filesystem// Module: File//// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.// and Contributors.//// Permission is hereby granted, free of charge, to any person or organization// obtaining a copy of the software and accompanying documentation covered by// this license (the "Software") to use, reproduce, display, distribute,// execute, and transmit the Software, and to prepare derivative works of the// Software, and to permit third-parties to whom the Software is furnished to// do so, all subject to the following:// // The copyright notices in the Software and this entire statement, including// the above license grant, this restriction and the following disclaimer,// must be included in all copies of the Software, in whole or in part, and// all derivative works of the Software, unless such copies or derivative// works are solely in the form of machine-executable object code generated by// a source language processor.// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER// DEALINGS IN THE SOFTWARE.//#include "Poco/File_UNIX.h"#include "Poco/Buffer.h"#include "Poco/Exception.h"#include <algorithm>#include <sys/stat.h>#include <sys/types.h>#include <fcntl.h>#include <errno.h>#include <unistd.h>#include <stdio.h>#include <utime.h>#include <string.h>namespace Poco {FileImpl::FileImpl(){}FileImpl::FileImpl(const std::string& path): _path(path){ std::string::size_type n = _path.size(); if (n > 0 && _path[n - 1] == '/') _path.resize(n - 1);}FileImpl::~FileImpl(){}void FileImpl::swapImpl(FileImpl& file){ std::swap(_path, file._path);}void FileImpl::setPathImpl(const std::string& path){ _path = path;}bool FileImpl::existsImpl() const{ poco_assert (!_path.empty()); struct stat st; return stat(_path.c_str(), &st) == 0;}bool FileImpl::canReadImpl() const{ poco_assert (!_path.empty()); struct stat st; if (stat(_path.c_str(), &st) == 0) { if (st.st_uid == geteuid()) return (st.st_mode & S_IRUSR) != 0; else if (st.st_gid == getegid()) return (st.st_mode & S_IRGRP) != 0; else return (st.st_mode & S_IROTH) != 0; } else handleError(_path); return false;}bool FileImpl::canWriteImpl() const{ poco_assert (!_path.empty()); struct stat st; if (stat(_path.c_str(), &st) == 0) { if (st.st_uid == geteuid()) return (st.st_mode & S_IWUSR) != 0; else if (st.st_gid == getegid()) return (st.st_mode & S_IWGRP) != 0; else return (st.st_mode & S_IWOTH) != 0; } else handleError(_path); return false;}bool FileImpl::isFileImpl() const{ poco_assert (!_path.empty()); struct stat st; if (stat(_path.c_str(), &st) == 0) return S_ISREG(st.st_mode); else handleError(_path); return false;}bool FileImpl::isDirectoryImpl() const{ poco_assert (!_path.empty()); struct stat st; if (stat(_path.c_str(), &st) == 0) return S_ISDIR(st.st_mode); else handleError(_path); return false;}bool FileImpl::isLinkImpl() const{ poco_assert (!_path.empty()); struct stat st; if (lstat(_path.c_str(), &st) == 0) return S_ISLNK(st.st_mode); else handleError(_path); return false;}Timestamp FileImpl::createdImpl() const{ poco_assert (!_path.empty()); struct stat st; if (stat(_path.c_str(), &st) == 0) return Timestamp::fromEpochTime(st.st_mtime); else handleError(_path); return 0;}Timestamp FileImpl::getLastModifiedImpl() const{ poco_assert (!_path.empty()); struct stat st; if (stat(_path.c_str(), &st) == 0) return Timestamp::fromEpochTime(st.st_mtime); else handleError(_path); return 0;}void FileImpl::setLastModifiedImpl(const Timestamp& ts){ poco_assert (!_path.empty()); struct utimbuf tb; tb.actime = ts.epochTime(); tb.modtime = ts.epochTime(); if (utime(_path.c_str(), &tb) != 0) handleError(_path);}FileImpl::FileSizeImpl FileImpl::getSizeImpl() const{ poco_assert (!_path.empty()); struct stat st; if (stat(_path.c_str(), &st) == 0) return st.st_size; else handleError(_path); return 0;}void FileImpl::setSizeImpl(FileSizeImpl size){ poco_assert (!_path.empty()); if (truncate(_path.c_str(), size) != 0) handleError(_path);}void FileImpl::setWriteableImpl(bool flag){ poco_assert (!_path.empty()); struct stat st; if (stat(_path.c_str(), &st) != 0) handleError(_path); mode_t mode; if (flag) { mode = st.st_mode | S_IWUSR; } else { mode_t wmask = S_IWUSR | S_IWGRP | S_IWOTH; mode = st.st_mode & ~wmask; } if (chmod(_path.c_str(), mode) != 0) handleError(_path);}void FileImpl::copyToImpl(const std::string& path) const{ poco_assert (!_path.empty()); int sd = open(_path.c_str(), O_RDONLY); if (sd == -1) handleError(_path); struct stat st; if (fstat(sd, &st) != 0) { close(sd); handleError(_path); } const long blockSize = st.st_blksize; int dd = open(path.c_str(), O_CREAT | O_TRUNC | O_WRONLY, st.st_mode & S_IRWXU); if (dd == -1) { close(sd); handleError(path); } Buffer<char> buffer(blockSize); try { int n; while ((n = read(sd, buffer.begin(), blockSize)) > 0) { if (write(dd, buffer.begin(), n) != n) handleError(path); } if (n < 0) handleError(_path); } catch (...) { close(sd); close(dd); throw; } close(sd); if (fsync(dd) != 0) { close(dd); handleError(path); } if (close(dd) != 0) handleError(path);}void FileImpl::renameToImpl(const std::string& path){ poco_assert (!_path.empty()); if (rename(_path.c_str(), path.c_str()) != 0) handleError(_path);}void FileImpl::removeImpl(){ poco_assert (!_path.empty()); int rc; if (!isLinkImpl() && isDirectoryImpl()) rc = rmdir(_path.c_str()); else rc = unlink(_path.c_str()); if (rc) handleError(_path);}bool FileImpl::createFileImpl(){ poco_assert (!_path.empty()); int n = open(_path.c_str(), O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR); if (n != -1) { close(n); return true; } if (n == -1 && errno == EEXIST) return false; else handleError(_path); return false;}bool FileImpl::createDirectoryImpl(){ poco_assert (!_path.empty()); if (existsImpl() && isDirectoryImpl()) return false; if (mkdir(_path.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) != 0) handleError(_path); return true;}void FileImpl::handleError(const std::string& path){ switch (errno) { case EIO: throw IOException(path); case EPERM: throw FileAccessDeniedException("insufficient permissions", path); case EACCES: throw FileAccessDeniedException(path); case ENOENT: throw FileNotFoundException(path); case ENOTDIR: throw OpenFileException("not a directory", path); case EISDIR: throw OpenFileException("not a file", path); case EROFS: throw FileReadOnlyException(path); case EEXIST: throw FileExistsException(path); case ENOSPC: throw FileException("no space left on device", path); case EDQUOT: throw FileException("disk quota exceeded", path); case ENOTEMPTY: throw FileException("directory not empty", path); case ENAMETOOLONG: throw PathSyntaxException(path); default: throw FileException(strerror(errno), path); }}} // namespace Poco
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -