簡體   English   中英

當read()時,寫入文件描述符的write()消失

[英]Write() to file descriptor disappearing when read()

因此,我現在正在程序的服務器端工作,我想執行以下操作:

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()的工作原理,但是如果有人可以幫助我向我解釋為什么這沒有按預期進行,那將不勝感激。 在過去的一周中,我一直在為此苦苦掙扎,而我目前為尋找解決方案而打開的選項卡數量非常可悲。

調用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$ 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM