【问题标题】:How to write int to file using write system call and read them exactly as written?如何使用 write 系统调用将 int 写入文件并完全按照写入的方式读取它们?
【发布时间】:2013-03-22 17:40:21
【问题描述】:

如何使用 UNIX 的 write 系统调用将 int、float 或其他类型写入文件? 我想这样做而不使用任何 lib 函数,如 fprintffwrite

我想使用文件描述符而不是FILE*

再次打开后,文件必须完全按照写入的方式读取,无需知道要读取的大小。

【问题讨论】:

  • 打开一个文件描述符,创建一个缓冲区并调用write。你有什么问题?
  • @squiguy 没有简单的方法吗?
  • @SAM:你认为还有比这更简单的方法吗??
  • @SAM:要编写人类可读的intfloat,您必须将其转换为数字,然后写入该数字的字符。对于float,如果内部表示使用与数字(例如十进制)不同的基数(例如二进制),那么这需要大量工作才能正确完成。

标签: c unix file-io system-calls printf


【解决方案1】:

这很简单(请注意,stdio.h 仅包含在 printf 中;没有它,读/写也可以工作):

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

int main()
{
    // Open file with write permission (create if doesn't exist).
    int fd = open("float.txt", O_CREAT | O_WRONLY);
    float val = 1.5f;
    if (fd != -1) {
        write(fd, &val, sizeof(val));
        close(fd);
    }

    // Test read.
    fd = open("float.txt", O_RDONLY);
    float new_val;
    if (fd != -1) {
        read(fd, &new_val, sizeof(new_val));
        printf("new_val = %f\n", new_val);
        close(fd);
    }
    return 0;
}

【讨论】:

  • 我敢肯定,我们可以假设您至少忽略了对readwrite 的系统调用的错误检查,以便于阅读,不是吗? ;-)
【解决方案2】:
int foo;

write (fd, &foo, sizeof foo);

【讨论】:

    【解决方案3】:

    正如在 cmets 中确定的那样,问题更多是将数字转换为十进制数字,而不是使用 write 调用。

    要编写人类可读的 int 或 float,您必须将其转换为数字,然后写入该数字的字符。对于浮点数,如果内部表示使用与数字(例如十进制)不同的基数(例如二进制),那么这需要大量工作才能正确完成。我建议使用现有的开源代码或有关该主题的科学论文。

    int 转换为十进制数字的代码相当简单:

    #include <stdlib.h> //  For size_t.
    
    
    /*  IntToString converts the int x to a decimal numeral, which is written to s.
        No terminal null character is written.  The number of characters written is
        returned.  s MUST point to space with enough room for the numeral,
        including a leading '-' if x is negative.
    */
    size_t IntToString(char *s, int x)
    {
        //  Set pointer to current position.
        char *p = s;
    
        //  Set t to absolute value of x.
        unsigned t = x;
        if (x < 0) t = -t;
    
        //  Write digits.
        do
        {
            *p++ = '0' + t % 10;
            t /= 10;
        } while (t);
    
        //  If x is negative, write sign.
        if (x < 0)
            *p++ = '-';
    
        //  Remember the return value, the number of characters written.
        size_t r = p-s;
    
        //  Since we wrote the characters in reverse order, reverse them.
        while (s < --p)
        {
            char t = *s;
            *s++ = *p;
            *p = t;
        }
    
        return r;
    }
    
    
    #include <stdio.h>  //  For printf.
    
    
    //  Demonstrate IntToString.
    static void Demonstrate(int x)
    {
        char buf[100];
        size_t n = IntToString(buf, x);
        printf("IntToString(%d) = %.*s.\n", x, (int) n, buf);
    }
    
    
    #include <limits.h> //  For INT_MIN and INT_MAX.
    
    
    int main(void)
    {
        Demonstrate(0);
        Demonstrate(1);
        Demonstrate(9);
        Demonstrate(10);
        Demonstrate(INT_MAX-1);
        Demonstrate(INT_MAX);
        Demonstrate(-1);
        Demonstrate(-9);
        Demonstrate(-10);
        Demonstrate(INT_MIN+1);
        Demonstrate(INT_MIN);
    
        return 0;
    }
    

    【讨论】:

    • @Eric 问题是谷歌的人来这里搜索如何使用系统调用写入文件。
    猜你喜欢
    • 1970-01-01
    • 2016-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-15
    • 2015-06-26
    相关资源
    最近更新 更多