【问题标题】:Invalid argument when calling linux splice()调用 linux splice() 时参数无效
【发布时间】:2011-02-04 12:59:57
【问题描述】:

我想试试 splice 系统调用。我有这个功能 - 它应该将一个文件的内容复制到另一个文件:

static void test_splice( int in, int out ) {

        int i = 0, rcvd = 0;
        int filedes[2];
        off_t off = 0;

        if ( pipe( filedes ) < 0 ) {
                perror( "Kicha pipe" );
                exit( EXIT_FAILURE );
        }

        for ( i = 0; i < NUMLOOPS; ++i ) {

                if ( ( rcvd = splice( in, NULL, filedes[1], NULL, BUFSIZE, SPLICE_F_MORE | SPLICE_F_MOVE ) ) < 0 ) {
                        perror( "splice" );
                        exit( EXIT_FAILURE );
                }

                if ( splice( filedes[0], NULL, out, NULL, rcvd, SPLICE_F_MORE | SPLICE_F_MOVE ) < 0 ) {
                        perror( "splice" );
                        exit( EXIT_FAILURE );
                }
        }
}

在第一次迭代中对 splice 的第二次调用每次都返回 EINVAL(来自 perror 的无效参数) - 可能是什么原因?

【问题讨论】:

  • 您的文件在哪种文件系统上?
  • 都是 ext3,但我也尝试从 /dev/zero 读取并写入 /dev/null 时出现相同的错误。
  • 我刚刚解决了这个问题 - 我使用 fopen 以“a+”模式打开文件 - 当更改为“w”时 - 它有效。

标签: c linux system-calls splice


【解决方案1】:

来自splice(2)

ERRORS
       ...    
       EINVAL Target  filesystem  doesn't  support  splicing;  target  file is
              opened in append mode; neither of the file descriptors refers to
              a pipe; or offset given for nonseekable device.
       ...    

OP 的评论表明他以追加模式打开文件。

【讨论】:

    【解决方案2】:

    我不知道这是否是最好的方法,但这对我有用:

    http://vectrex.org.uk/mark/splicecopy.cpp

    它创建一个线程来读取和另一个线程来写入。这可能是不必要的。编写线程似乎只需要一次 splice() 调用,但阅读器在我的系统上大约每 64k 执行一次。

    以上内容在 Fedora 13 x86_64 上进行了测试,似乎能够复制大(ish)文件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-02
      • 1970-01-01
      • 2012-08-28
      • 2014-06-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多