【问题标题】:Convert the Linux open, read, write, close functions to work on Windows将 Linux 的打开、读取、写入、关闭功能转换为在 Windows 上工作
【发布时间】:2018-08-06 15:59:30
【问题描述】:

下面的代码是为 Linux 编写的,使用 open、read、write 和 close。我正在使用通常使用 fopen、fgets、fputs、fclose 的 Windows 计算机上工作。现在,我在打开、读取、写入和关闭时收到无原型错误。是否有我可以包含的头文件以使其在 Windows 计算机上工作,或者我是否需要转换代码?您能否展示如何转换它以使其在 Windows 上运行相同,或者至少将我指向显示如何转换它的在线文档?

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#ifdef unix
#include <unistd.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#ifndef O_BINARY
#define O_BINARY 0
#endif

#define NB 8192
char buff[NB];

int
main(argc,argv)
int argc;
char **argv;
{
int fdi, fdo, i, n, m;
char *p, *q;
char c;


if( argc > 0 )
    printf( "%s:  Reverse bytes in 8-byte values \n", argv[0] );
if( argc > 1 )
    strcpy( buff, argv[1] );
else
    {
    printf( "Input file name ? " );
    gets( buff );
    }
fdi = open( buff, O_BINARY | O_RDONLY, S_IREAD );

if( fdi <= 0 )
    {
    printf( "Can't open <%s>\n", buff );
    exit(2);
    }

if( argc > 2 )
    strcpy( buff, argv[2] );
else
    {
    printf( "Output file name ? " );
    gets( buff );
    }
fdo = open( buff, O_BINARY | O_RDWR | O_CREAT | O_TRUNC,
      S_IREAD | S_IWRITE );
if( fdo <= 0 )
    {
    printf( "Can't open <%s>\n", buff );
    exit(2);
    }

while( (n = read( fdi, buff, NB )) > 0 )
    {
    m = n / 8;
    p = buff;
    q = buff+7;
    for( i=0; i<m; i++ )
        {
        c = *p;
        *p++ = *q;
        *q-- = c;
        c = *p;
        *p++ = *q;
        *q-- = c;
        c = *p;
        *p++ = *q;
        *q-- = c;
        c = *p;
        *p++ = *q;
        *q-- = c;
        p += 4;
        q += 12;
        }
    write( fdo, buff, n );
    }
close( fdo );
close( fdi );
exit(0);
}

【问题讨论】:

  • 是的,转换代码。或者更好的是,在一开始就编写可移植的代码。随心所欲地去做。 / 请注意,要求场外资源的问题与 StackOverflow 无关。
  • 我很确定我已经在 Windows 中使用过这些功能。只是包含正确的头文件的问题吗?
  • 有各种适用于 Windows 的 unistd.h 实现,这是您唯一真正的问题。它基本上只是一些#includes 和一些#defines。

标签: c++ c windows posix c++builder


【解决方案1】:

Windows 中的相应函数使用相同的名称,但名称前带有下划线 (_)。

open -> _open
close -> _close

等等

它们在头文件 io.h 中声明。请参阅https://msdn.microsoft.com/en-us/library/z0kc8e3z.aspx 了解所有支持的功能列表。

【讨论】:

  • Microsoft 近年来一直非常一致地将不属于标准的函数重命名为具有前导下划线。大概是为了防止与用户功能发生名称冲突。不过,获得 Linux 互操作性有点痛苦。
  • 我很高兴他们支持低级功能。它们使编写跨平台应用程序成为可能,只需一点#ifdef/#else/#endif
  • Windows 中的相应函数使用相同的名称,但名称前加下划线 (_)。 不需要。 Microsoft supports open(), for example,尽管带有误导性的“已弃用”标签,微软似乎适用于任何可能导致编写可移植代码的函数。
  • @AndrewHenle,感谢您提供的额外信息。我只使用过这些函数的 _ 变体。
【解决方案2】:

微软直接支持open()read()write()close()等POSIX风格的低级IO调用;尽管似乎具有误导性的“已弃用”特征。

所需的标头是&lt;io.h&gt;

调用对应于以前导下划线命名的函数,因此open() 映射到_open()

The full list of supported "low-level" IO functions Microsoft supports are:

低级 I/O

Low-Level I/O Functions

Function                                Use
_close                                  Close file
_commit                                 Flush file to disk
_creat, _wcreat                         Create file
_dup                                    Return next available file descriptor for given file
_dup2                                   Create second descriptor for given file
_eof                                    Test for end of file
_lseek, _lseeki64                       Reposition file pointer to given location
_open, _wopen                           Open file
_read                                   Read data from file
_sopen, _wsopen, _sopen_s, _wsopen_s    Open file for file sharing
_tell, _telli64                         Get current file-pointer position
_umask, _umask_s                        Set file-permission mask
_write                                  Write data to file

一些低级函数可能没有非下划线、POSIX 样式的等效名称。

【讨论】:

    【解决方案3】:

    Borland C++ Builder将二进制文件访问函数封装成:

    FileOpen
    FileCreate
    FileRead
    FileWrite
    FileSeek
    FileClose
    

    这里是加载文本文件的简单示例:

    BYTE *txt=NULL; int hnd=-1,siz=0;
    hnd = FileOpen("textfile.txt",fmOpenRead);
    if (hnd!=-1)
     {
     siz=FileSeek(hnd,0,2);     // position to end of file (0 bytes from end) and store the offset to siz which means size of file
         FileSeek(hnd,0,0);     // position to start of file (0 bytes from start)
     txt = new BYTE[siz];
         FileRead(hnd,txt,siz); // read siz bytes to txt buffer
         FileClose(hnd);
     }
    if (txt!=NULL)
     {
     // here do your stuff with txt[siz] I save it to another file
     hnd = FileCreate("output.txt");
     if (hnd!=-1)
      {
      FileWrite(hnd,txt,siz);   // write siz bytes to txt buffer
      FileClose(hnd);
      }
     delete[] txt;
     }
    

    IIRC 所有这些都是 VCL 的一部分,因此如果您使用控制台,则需要在项目创建期间设置 VCL 包含检查或手动包含它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-10
      相关资源
      最近更新 更多