如果关闭未执行两次,则无法确定大小
could not determine size if fclose not done twice
我创建了一个File类,它是File类型的一种包装器,并添加了一些方法。
这是我的文件类的代码: #include <Fs/File.h>
File::File(Path& p):
m_path(p),
m_openned(false)
{
}
int File::open(const string& mode)
{
m_f = new FILE;
fopen(m_path, mode.c_str());
if (m_f == NULL)
{
m_openned = false;
return -1;
}
m_openned = true;
return 0;
}
bool File::exists()
{
FILE* file;
if (file = fopen(m_path, "r"))
{
fclose(file);
return true;
}
fclose(file);
return false;
}
int File::flush(){
return fflush(m_f);
}
int File::remove()
{
return ::remove(m_path);
}
int File::close()
{
if (isOpenned())
{
m_openned = false;
return fclose(m_f);
}
return 0;
}
long File::getSize()
{
struct stat file_status;
if(!this->exists())
return -1;
if (stat(m_path, &file_status) < 0)
{
return -1;
}
return file_status.st_size;
}
FileMode File::getMode()
{
struct stat file_status;
if (stat(m_path, &file_status) < 0)
{
return FileMode(-1);
}
return FileMode(file_status.st_mode);
}
Path File::getPath()
{
return m_path;
}
bool File::isOpenned()
{
return m_openned;
}
int File::setMode(FileMode& mode)
{
return chmod(m_path, mode);
}
int File::renameTo(File& f)
{
if (f.exists() || !this->exists())
return -1;
return rename( m_path , f.getPath());
}
int File::copyTo(File& to)
{
char ch;
this->close();
this->open(FileTypes::READ);
to.close();
to.open(FileTypes::WRITE);
while (!this->eof())
{
ch = this->readc();
if (ch == -1)
return 0;
if (!to.eof())
to.writec(ch);
}
if (this->close() < 0)
{
return -1;
}
if (to.close() < 0)
{
return -1;
}
return 0;
}
int File::readc()
{
if (!isOpenned())
return FileTypes::ENDOFFILE;
char c = fgetc(m_f);
if (ferror(m_f))
{
return FileTypes::ENDOFFILE;
}
return c;
}
int File::writec(char c)
{
if (!isOpenned())
return -1;
fputc(c, m_f);
if (ferror(m_f))
{
return FileTypes::ENDOFFILE;
}
return 0;
}
bool File::eof()
{
if (!isOpenned())
return true;
return feof(m_f);
}
我做了一些测试,我有一个问题
Path p1("test.txt");
Path p2("temp.txt");
File f1(p1);
File f2(p2);
assert(f1.open(FileTypes::READ) == 0);
assert(f1.exists() == true);
assert(f1.close() == 0);
cout<<"Mode of f1 "<<f1.getMode().getStringMode()<<endl;
cout<<"Path of f1 "<<f1.getPath().getAbsolutePath()<<endl;
cout<<"Size of f1 "<<f1.getSize()<<endl;
assert(f2.exists() == false);
assert(f1.copyTo(f2) == 0);
//#####################################
// If I comment f2.close() the
// assert(f1.getSize() == f2.getSize()) test fails and
// f2.getSize() == 0
##########################################
f2.close();
assert(f2.exists() == true);
assert(f1.getSize() == f2.getSize());
我不明白为什么这个f2。close是必需的,因为我在copyTo方法中执行了close操作。有人能帮帮我吗?提前谢谢你。本
In File::copyTo
:
if (ch == -1)
return 0;
您没有正确关闭文件就跳出了函数。当目标文件未关闭时,它的内容可能没有发送到操作系统,操作系统随后会报告伪造的文件大小。
fclose
冲洗流。我的猜测是,在没有关闭文件的情况下,流还没有完全写入,所以大小不同。考虑在copyTo
方法的末尾添加fflush(to);
,以确保所有内容都已写入。
copyTo函数有多个出口,这并不能确保您实际关闭文件。在我看来,您可能提前退出了copyTo函数,并且预期的close没有执行
while (!this->eof())
{
ch = this->readc();
if (ch == -1)
return 0;
if (!to.eof())
to.writec(ch);
}
当您到达文件末尾时,您将获得EOF,在我的操作系统(windows)中它是-1,这将导致您在这里返回0,并跳过close call。
相关文章:
- g++的分段错误(在NaN上使用to_string两次时)
- 蛇在C++不会连续转两次
- 检查一个数组是否包含在另一个数组中,以相反的顺序,至少两次
- 从具有按值捕获的 lambda 移动构造 std::函数时,移动构造函数调用两次
- 我应该如何去缓解两次出现的cin?
- Realloc 两次无法在 Visual Studio 上运行
- 使用 getline(cin, var) 两次在进行字符串比较时会产生错误 (==)
- 为什么映射插入和 map.find() 的单次迭代比插入和 map.find() 的两次单独迭代慢得多
- C++析构函数调用两次,堆栈分配的复合对象
- 初始值设定项无法确定 C++ 中字符串的大小
- 为什么参数在构造 std::thread 时移动两次
- Qt插槽调用了两次
- 做 std::用相同的unique_ptr移动两次
- C++两次定义相同的函数会导致错误
- 为什么具有静态存储持续时间的同一内联变量在包含在 VS2017 编译的两个翻译单元中时会构造和销毁两次
- 对于优化级别为 0 的 std::vector,析构函数被调用两次
- 使用柯南打包时如何避免列出两次依赖?
- 基于 MFC 对话框的应用程序无法调用对话框两次
- 如果关闭未执行两次,则无法确定大小
- 两次派生的菱形继承-构造函数参数不同-指定虚拟继承时无法找到基