0

所以我现在正在我的程序的服务器端工作,我想做以下事情:

1)以读/写模式打开文件

2)在文件末尾附加一个单词(WORD)

3) [我相信我已经完成了所有这部分] 打开一个管道,创建一个子进程,让它直接从文件(文件描述符)中读取,执行一个命令,并将结果发送到管道。父进程从管道的读取/输入中读取,并将信息放入缓冲区以发送回客户端。

我遇到的问题是附加部分。我很确定它会附加到文件中(在现有文本和我的 WORD 之间有一个换行符),因为当我直接打开文本文件时它就在那里。但是当我尝试从缓冲区打印它时,它不存在。我尝试在写入并重新打开后关闭文件描述符,但它不存在。我试过 strcat 而不是写入文件描述符,但它不存在。

  #define WORD "WORD"
  #define BUFFERLENGTH 512
  char buffer[BUFFERLENGTH];

  int fileDesc = open (filePath, O_RDWR|O_APPEND, 0660);
  if (fileDesc <= 0){
    write(clientDesc, ERRORMSG, BUFFERLENGTH);
    exit(EXIT_FAILURE);
  }

  read(fileDesc,buffer,BUFFERLENGTH);

  long length  = lseek(fileDesc,0,SEEK_END);
  int status  = write(fileDesc,WORD,sizeof(WORD)-1);

  read(fileDesc, buffer, BUFFER_LEN+1);
  printf("new text: %s\n", buffer); //WORD does not show up at the end of file as intended

我真的有什么误解吗?

也许我不完全理解 open()、read()、write() 和 lseek() 是如何工作的,但是如果有人可以帮助向我解释为什么这不能按预期工作,那将不胜感激。在过去的一周里,我一直在为此苦苦挣扎,而我目前打开的用于寻找解决方案的选项卡数量是可悲的。

4

1 回答 1

2

通话后,您write()将位于文件的末尾,因此read()将无法读取任何内容。lseek()如果您希望能够从文件中读取任何内容,则需要在文件的前面一点。

您应该检查返回read()(以及几乎所有其他系统调用,就此而言)和使用perror()或类似的错误情况,这将有助于您了解当您看到您没有看到的行为时发生了什么预计。

修改你的程序:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>

#define WORD "WORD"
#define BUFFERLENGTH 512

int main(void)
{
    char * filePath = "testfile.txt";
    char buffer[BUFFERLENGTH] = {0};

    // Open file.

    int fd = open(filePath, O_RDWR | O_APPEND, 0660);
    if (fd < 0) {
        perror("couldn't open file");
        return EXIT_FAILURE;
    }

    // Write word to end.

    int status = write(fd, WORD, strlen(WORD));
    if ( status < 0 ) {
        perror("couldn't write");
        return EXIT_FAILURE;
    }

    // Seek to start of file.

    long length = lseek(fd, 0, SEEK_SET);
    if ( length < 0 ) {
        perror("couldn't lseek");
        return EXIT_FAILURE;
    }

    // Read contents of file.

    status = read(fd, buffer, BUFFERLENGTH - 1);
    if ( status < 0 ) {
        perror("couldn't read");
        return EXIT_FAILURE;
    }

    // Print buffer.

    printf("file contents: %s\n", buffer);

    return 0;
}

产量:

paul@mac:scratch$ touch testfile.txt
paul@mac:scratch$ ./file
file contents: WORD
paul@mac:scratch$ ./file
file contents: WORDWORD
paul@mac:scratch$ ./file
file contents: WORDWORDWORD
paul@mac:scratch$ ./file
file contents: WORDWORDWORDWORD
paul@mac:scratch$

如果您实际上只想查看新内容,那么您需要查看lseek()文件开头以外的某个点。由于成功write()将返回写入的字节数,因此您可以使用此值从文件末尾偏移:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>

#define BUFFERLENGTH 512

int main(int argc, char * argv[])
{
    if ( argc < 2 ) {
        fprintf(stderr, "you need to enter a word argument\n");
        return EXIT_FAILURE;
    }

    char * filePath = "testfile.txt";
    char buffer[BUFFERLENGTH] = {0};

    // Open file.

    int fd = open(filePath, O_RDWR | O_APPEND, 0660);
    if ( fd < 0 ) {
        perror("couldn't open file");
        return EXIT_FAILURE;
    }

    // Write word to end.

    int status = write(fd, argv[1], strlen(argv[1]));
    if ( status < 0 ) {
        perror("couldn't write");
        return EXIT_FAILURE;
    }

    // Seek to point before last write.

    long length = lseek(fd, -status, SEEK_END);
    if ( length < 0 ) {
        perror("couldn't lseek");
        return EXIT_FAILURE;
    }

    // Read from there to end of file.

    status = read(fd, buffer, BUFFERLENGTH - 1);
    if ( status < 0 ) {
        perror("couldn't read");
        return EXIT_FAILURE;
    }

    // Print buffer.

    printf("new text: %s\n", buffer);

    return 0;
}

产生:

paul@mac:scratch$ rm testfile.txt
paul@mac:scratch$ touch testfile.txt
paul@mac:scratch$ ./file2 these
new text: these
paul@mac:scratch$ ./file2 are
new text: are
paul@mac:scratch$ ./file2 some
new text: some
paul@mac:scratch$ ./file2 words
new text: words
paul@mac:scratch$ cat testfile.txt
thesearesomewordspaul@mac:scratch$ 
于 2018-11-10T02:26:11.840 回答