c中写入/读取二进制/文本之间的差异

Col*_*ton 3 c sockets binaryfiles

我正在开发客户端发送/接收文件的客户端/服务器程序。这些文件可以是文本文件或二进制文件。但是,我不确定需要进行哪些更改(如果有)以适应任一文件类型。基本上我希望在服务器端读取/写入文件而不关心它是什么类型的文件,我希望能够在不检查它是什么类型的文件的情况下这样做。这样的代码会起作用吗?为什么或者为什么不?

服务器片段:

//CREATING/WRITING TO A FILE
//we are ready to begin reading data from the client, and storing it 
int fd = open(pathname, O_CREAT | O_WRONLY | O_EXCL, S_IRUSR | S_IWUSR);
while(nbytes < bytes)
{
    //only read the neccessary # of bytes: the remaining bytes vs max buffer size
    int min_buffer = (bytes - nbytes) < BUFFER_SIZE ? (bytes - nbytes) : BUFFER_SIZE;
    length = recv( client->client_socket, contents, min_buffer, 0);

    if(fd < 0) //the fd is bad, but we need to continue reading bytes anyway
    {
        nbytes += length;
        continue;
    }

    if(length <= 0)
        break;//string empty or error occurred...this error means the client closed?

    if(write(fd, contents, min_buffer) != min_buffer)
    {
        //printf("There was an error writing to the file.\n");
    }
    else
    {       
        nbytes += length;
    }
}


//READING A STORED FILE AND SENDING THE DATA TO CLIENT
int fd = open(pathname, O_RDWR, S_IRUSR | S_IWUSR);
if(fd >= 0)
{
    while(bytes > 0)
    {
        bytes = read(fd, buffer,  BUFFER_SIZE );

        if(bytes > 0)//we have read some bytes
        {
            //send the client the data
            write(client->client_socket, buffer, bytes);
        }
        else if(bytes < 0)
        {
            //some error occured
            write( client->client_socket, "ERROR: Could not read\n", 22);   
            return;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

因此,如果客户端发送二进制文件与文本文件,此代码会导致问题吗?(我们可以假设客户端知道期望的文件类型。)

注意:关于此的另一个令人困惑的细节是,在 c 中编写/读取二进制文件的教程似乎与常规文件没有任何真正的区别,这就是让我来到这里的原因。

dev*_*fan 5

只需使用“二进制”文件即可完成所有操作。Linux在操作系统级别的文件中没有“文本”和“二进制”之间的区别,只有其中包含字节的文件。IE。期望文件包含所有可能的字节值,并且不要为不同类型的内容编写不同的代码。

Windows 中存在差异:Windows 中的文本模式意味着在写入/读取文件时\n程序中的换行符 ( ) 被转换为/从\r\n。以二进制模式读取的写入文本文件将包含这两个字节而不是原始字节,\n反之亦然。(此外,MS 在文档中并不是很清楚这是唯一的区别,它很容易混淆初学者。)

如果您使用标准 Cfopenfclose不是特定于 Linux 的open等,您可以指定以二进制或文本模式打开文件(在 Linux 上也是如此)。这是因为带有 fopen 的代码应该可以在 Windows 和 Linux 上运行,而无需进行任何特定于操作系统的更改;但是在 Linux 上运行时,您在 fopen 中选择的内容并不重要(可以通过阅读 fopen 等的源代码进行验证)

关于套接字:
Linux:没有区别(再次)
Windows:也没有区别。只有字节,没有奇怪的换行符转换。