Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/140.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
实施;尾部-f“;在C++; 我想在C++中创建一个与“Tal-F”功能相同的小代码:在文本文件中观察新的行并在标准输出中显示它们。_C++_Tail - Fatal编程技术网

实施;尾部-f“;在C++; 我想在C++中创建一个与“Tal-F”功能相同的小代码:在文本文件中观察新的行并在标准输出中显示它们。

实施;尾部-f“;在C++; 我想在C++中创建一个与“Tal-F”功能相同的小代码:在文本文件中观察新的行并在标准输出中显示它们。,c++,tail,C++,Tail,这个想法是有一个线程来监视文件 有没有一种不需要每次打开和关闭文件的简单方法?只需继续阅读文件即可。如果读取失败,则不执行任何操作。没有必要反复打开和关闭它。但是,如果您的操作系统提供了特定于操作系统的功能,您会发现使用这些功能来监视文件更为有效。看看Linux或Mac OS上的kqueue。 是Linux内核子系统,它允许您订阅文件上的事件,并在文件上发生事件时向您的应用程序报告。我在中阅读了这篇文章,但它很容易翻译成标准C,而标准C又可以翻译成istreams seek FILEHAN

这个想法是有一个线程来监视文件


有没有一种不需要每次打开和关闭文件的简单方法?

只需继续阅读文件即可。如果读取失败,则不执行任何操作。没有必要反复打开和关闭它。但是,如果您的操作系统提供了特定于操作系统的功能,您会发现使用这些功能来监视文件更为有效。

看看Linux或Mac OS上的kqueue。

是Linux内核子系统,它允许您订阅文件上的事件,并在文件上发生事件时向您的应用程序报告。

我在中阅读了这篇文章,但它很容易翻译成标准C,而标准C又可以翻译成
istream
s

   seek FILEHANDLE,POSITION,WHENCE
      Sets FILEHANDLE's position, just like the "fseek" call of
      "stdio".  
       <...>
       A WHENCE of 1 ("SEEK_CUR") is useful for not moving the file 
       position:

           seek(TEST,0,1);

       This is also useful for applications emulating "tail -f".  Once
       you hit EOF on your read, and then sleep for a while, you might
       have to stick in a seek() to reset things.  The "seek" doesn't
       change the current position, but it does clear the end-of-file
       condition on the handle, so that the next "<FILE>" makes Perl
       try again to read something.  We hope.
查找文件句柄、位置、位置
设置FILEHANDLE的位置,就像调用
“stdio”。
其中1(“SEEK_CUR”)对于不移动文件很有用
职位:
搜索(测试,0,1);
这对于模拟“tail-f”的应用程序也很有用。一旦
你在阅读时点击EOF,然后睡一会儿,你可能会
必须坚持使用seek()来重置内容。“寻找”没有
更改当前位置,但会清除文件结尾
条件,以便下一个“”生成Perl
再次尝试阅读一些东西。我们希望如此。
就我所记得的,
fseek
被调用。因此,您应该基本上执行相同的操作:查找文件的结尾,然后使用
ios_base::cur
标志睡眠并再次查找,以更新文件的结尾并读取更多数据


您可以按照中的建议使用inotify(实际上是在读取模拟文件时阻塞)完全休眠,而不是
sleep
ing,直到文件更新/关闭。但这是Linux特有的,不是标准的C++。

我也需要实现这一点,我只是在标准C++中写了一个快速破解。黑客在文件中搜索最后一个0x0A(换行符),并在最后一个换行符值变大时输出该换行符后面的所有数据。代码如下:

#include <iostream>
#include <string>
#include <fstream>

using namespace std;


int find_last_linefeed(ifstream &infile) {

  infile.seekg(0,ios::end);
  int filesize = infile.tellg();

  for(int n=1;n<filesize;n++) {
    infile.seekg(filesize-n-1,ios::beg);

    char c;
    infile.get(c);

    if(c == 0x0A) return infile.tellg();
  }
}


int main() {


  int last_position=-1;
  for(;;) {

    ifstream infile("testfile");
    int position = find_last_linefeed(infile);

    if(position > last_position) {
      infile.seekg(position,ios::beg);
      string in;
      infile >> in;
      cout << in << endl;
    }
    last_position=position;

    sleep(1);
  }

}
#包括
#包括
#包括
使用名称空间std;
int find_last_linefeed(ifstream&infle){
填充seekg(0,ios::end);
int filesize=infle.tellg();
用于(int n=1;n最后位置){
填充seekg(位置,ios::beg);
串入;
填充>>中;
cout与中相同,只是下面的代码使用getline而不是getc,并且不跳过新行

#include <iostream>
#include <string>
#include <fstream>
#include <sstream>

using namespace std;

static int last_position=0;
// read file untill new line
// save position

int find_new_text(ifstream &infile) {

   infile.seekg(0,ios::end);
   int filesize = infile.tellg();

   // check if the new file started
   if(filesize < last_position){
      last_position=0;
   }  
   // read file from last position  untill new line is found 

   for(int n=last_position;n<filesize;n++) {

      infile.seekg( last_position,ios::beg);
      char  test[256]; 
      infile.getline(test, 256);
      last_position = infile.tellg();
      cout << "Char: "  << test <<"Last position " << last_position<<  endl;
      // end of file 
      if(filesize == last_position){
        return filesize;
      } 

  }

  return 0;
}


int main() {

  for(;;) {
    std::ifstream infile("filename");
    int current_position = find_new_text(infile);
    sleep(1);
  } 

} 
#包括
#包括
#包括
#包括
使用名称空间std;
静态int最后位置=0;
//读取文件直到换行
//保存位置
int查找新文本(ifstream和infle){
填充seekg(0,ios::end);
int filesize=infle.tellg();
//检查新文件是否已启动
如果(文件大小<最后位置){
最后位置=0;
}  
//从最后一个位置读取文件,直到找到新行
对于(int n=最后一个位置;n
#包括
#包括
#包括
#包括
#包括
#包括
#定义调试0
MyTail类
{
私人:
std::列表mLastNLine;
康斯坦因特姆努弗林斯;
std::ifstream mIn;
公众:
显式MyTail(int pNoOfLines):mNoOfLines(pNoOfLines){}
const int getNoOfLines(){return mNoOfLines;}
void getlastnline();
void printLastNLines();
void tailF(常量字符*文件名);
};
void MyTail::getLastNLines()
{

如果(调试)STD::CUT在纯C++中可能会很难做到这一点。您必须使用特定于平台的API。(对于初学者,我认为您不可以在C++中非专用地打开文件。)“SBI我认为C++标准在排他性方面没有什么可说的。有什么原因不能使用尾-f?”尼尔:不,它没有。这就是为什么我知道的FSCORT实现似乎只打开文件。@ SBI -可以打开C++中各种共享模式的文件句柄。+ 1:尝试从WHER读取文件的末尾。到目前为止(对于一个合理长度的文件),每秒读一次在实践中是非常便宜的。你只需读到最后,然后睡一会儿,然后再试一次。(如果你在Windows上,小心打开正确的共享标志,这样你就不会锁定其他作者。这可能意味着使用本地IO调用而不是C++标准的……)喜欢“我们希望”关闭。还有许多其他perl典型的自攻击实现…@Stefano-好吧,这里很好,因为它涉及到perl的行方式文件读取实现(
),而不是关于
fseek
如何工作。我希望。Windows有一个等效的API,用于在文件更改时发送通知。filesize#include <iostream> #include <fstream> #include <string> #include <list> #include <sys/stat.h> #include <stdlib.h> #define debug 0 class MyTail { private: std::list<std::string> mLastNLine; const int mNoOfLines; std::ifstream mIn; public: explicit MyTail(int pNoOfLines):mNoOfLines(pNoOfLines) {} const int getNoOfLines() {return mNoOfLines; } void getLastNLines(); void printLastNLines(); void tailF(const char* filename); }; void MyTail::getLastNLines() { if (debug) std::cout << "In: getLastNLines()" << std::endl; mIn.seekg(-1,std::ios::end); int pos=mIn.tellg(); int count = 1; //Get file pointer to point to bottom up mNoOfLines. for(int i=0;i<pos;i++) { if (mIn.get() == '\n') if (count++ > mNoOfLines) break; mIn.seekg(-2,std::ios::cur); } //Start copying bottom mNoOfLines string into list to avoid I/O calls to print lines std::string line; while(getline(mIn,line)) { int data_Size = mLastNLine.size(); if(data_Size >= mNoOfLines) { mLastNLine.pop_front(); } mLastNLine.push_back(line); } if (debug) std::cout << "Out: getLastNLines()" << std::endl; } void MyTail::printLastNLines() { for (std::list<std::string>::iterator i = mLastNLine.begin(); i != mLastNLine.end(); ++i) std::cout << *i << std::endl; } void MyTail::tailF(const char* filename) { if (debug) std::cout << "In: TailF()" << std::endl; int date = 0; while (true) { struct stat st; stat (filename, &st); int newdate = st.st_mtime; if (newdate != date){ system("@cls||clear"); std::cout << "Print last " << getNoOfLines() << " Lines: \n"; mIn.open(filename); date = newdate; getLastNLines(); mIn.close(); printLastNLines(); } } if (debug) std::cout << "Out: TailF()" << std::endl; } int main(int argc, char **argv) { if(argc==1) { std::cout << "No Extra Command Line Argument Passed Other Than Program Name\n"; return 0; } if(argc>=2) { MyTail t1(10); t1.tailF(argv[1]); } return 0; }