كيف يمكنني استخدام وظيفة Linux's splice () لنسخ ملف إلى ملف آخر؟

StackOverflow https://stackoverflow.com/questions/1580923

سؤال

إليك سؤال آخر حول SPLICE (). آمل أن أستخدمها لنسخ الملفات ، وأحاول استخدام مكالمتين لصقتين ينضم إليهما أنبوب مثل المثال على صفحة Wikipedia الخاصة بـ Splice. كتبت حالة اختبار بسيطة تحاول فقط قراءة أول 32 كيلو بايت من ملف واكتبها إلى آخر:

#define _GNU_SOURCE
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

int main(int argc, char **argv) {
    int pipefd[2];
    int result;
    FILE *in_file;
    FILE *out_file;

    result = pipe(pipefd);

    in_file = fopen(argv[1], "rb");
    out_file = fopen(argv[2], "wb");

    result = splice(fileno(in_file), 0, pipefd[1], NULL, 32768, SPLICE_F_MORE | SPLICE_F_MOVE);
    printf("%d\n", result);

    result = splice(pipefd[0], NULL, fileno(out_file), 0, 32768, SPLICE_F_MORE | SPLICE_F_MOVE);
    printf("%d\n", result);

    if (result == -1)
        printf("%d - %s\n", errno, strerror(errno));

    close(pipefd[0]);
    close(pipefd[1]);
    fclose(in_file);
    fclose(out_file);

    return 0;
}

عندما أقوم بتشغيل هذا ، يبدو أن ملف الإدخال يتم قراءته بشكل صحيح ، لكن مكالمة لصق ثانية تفشل مع Einval. أي شخص يعرف ما أفعله خطأ هنا؟

شكرًا!

هل كانت مفيدة؟

المحلول

ما نوع نظام (أنظمة) الملفات التي تقوم بنسخها إلى/من؟

يعمل مثالك على نظامي عندما يكون كلا الملفين على Ext3 ولكنه يفشل عندما أستخدم محرك أقراص خارجي (أنسى خارجها إذا كان DOS أو NTFS). أظن أن واحدًا أو كلا من ملفاتك موجودة على نظام ملفات لا يدعمها.

نصائح أخرى

من لصق القنابل:

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

نحن نعلم أن أحد الواصفات هو أنبوب ، والملف غير مفتوح في وضع إلحاق. نحن نعلم أيضًا أنه لا يتم إعطاء أي تعويض (0 يعادل NULL - هل تقصد أن تمر في مؤشر إلى إزاحة صفر؟) ، لذلك ليست هذه هي المشكلة. لذلك ، لا يدعم نظام الملفات الذي تستخدمه الربط إلى الملفات.

ال splice(2) استدعاء النظام هو للنسخ بين الملفات والأنابيب وليس بين الملفات ، بحيث لا يمكن استخدامها لنسخها بين الملفات ، كما أشارت الإجابات الأخرى.

اعتبارًا من Linux 4.5 ولكن جديد copy_file_range(2) استدعاء النظام متاح يمكن أن نسخ بين الملفات. في حالة NFS يمكن أن يتسبب حتى في نسخ جانب الخادم.

تحتوي صفحة الرجل المرتبط على برنامج مثال كامل.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top