#c #fclose
#c #fclose
Вопрос:
Я создал файловый класс, который является своего рода оболочкой типа ФАЙЛА, и добавил некоторые методы.
Это код моего класса file :
#include <Fs/File.h>
File::File(Pathamp; p):
m_path(p),
m_openned(false)
{
}
int File::open(const stringamp; 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, amp;file_status) < 0)
{
return -1;
}
return file_status.st_size;
}
FileMode File::getMode()
{
struct stat file_status;
if (stat(m_path, amp;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(FileModeamp; mode)
{
return chmod(m_path, mode);
}
int File::renameTo(Fileamp; f)
{
if (f.exists() || !this->exists())
return -1;
return rename( m_path , f.getPath());
}
int File::copyTo(Fileamp; 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.
Кто-нибудь может мне помочь?
Заранее благодарю вас.
Ben
Комментарии:
1. Всегда есть Boost. Файловая система, предлагаемая для C TR2.
2. В
copyTo
случаеthis->close()
сбоя вы никогда не вызываетеto.close()
. Однако, вероятно, это не причина вашей проблемы.3. Вы уверены, что всегда достигаете
close
incopyTo
? Кажется, что там многоreturn
операторов.
Ответ №1:
В File::copyTo
:
if (ch == -1)
return 0;
вы выходите из функции без надлежащего закрытия файлов. Когда целевой файл не закрыт, его содержимое, вероятно, не отправляется в ОС, которая позже сообщает о поддельном размере файла.
Ответ №2:
fclose
сбрасывает поток. Я предполагаю, что без закрытия файла поток не был полностью записан, поэтому размеры разные. Подумайте о добавлении fflush(to);
в конце вашего copyTo
метода, чтобы убедиться, что все было написано.
Ответ №3:
У вас есть несколько выходов из функции CopyTo, которая не гарантирует, что вы действительно закроете файл. Мне кажется, что вы, возможно, рано выходите из функции CopyTo и что предполагаемое закрытие не выполняется
while (!this->eof())
{
ch = this->readc();
if (ch == -1)
return 0;
if (!to.eof())
to.writec(ch);
}
когда вы нажмете на конец файла, вы получите значение EOF, которое в моей ОС (Windows) равно -1, что приведет к тому, что вы вернете здесь 0 и пропустите вызов закрытия.