使用Glib库函数将文件从源复制到目标

时间:2010-12-10 04:59:24

标签: glibc

如何使用Glib库将文件从源复制到目标。

2 个答案:

答案 0 :(得分:2)

我们必须使用gio库。您可以从以下链接获取文档

http://library.gnome.org/devel/gio/stable/

答案 1 :(得分:0)

这是一个老问题,但这里有一些代码,我为自己的使用而快速编写。它使用mmap() / memcpy(),它是为64位平台编写的。随意使用它适合它。

gboolean
ak_common_copy_file (const gchar *src, const gchar *dst, gboolean overwrite)
{
    g_return_val_if_fail (src != NULL, FALSE);
    g_return_val_if_fail (dst != NULL, FALSE);

    if (sizeof (gpointer) != 8) {
        g_error (G_STRLOC ": Not a 64-bit platform.");
        return FALSE;
    }

    struct stat st;

    /* check source file */
    if (!g_file_test (src, G_FILE_TEST_EXISTS)) {
        g_critical (G_STRLOC ": File '%s' not found.", src);
        return FALSE;
    }
    else if (!g_file_test (src, G_FILE_TEST_IS_REGULAR)) {
        g_critical (G_STRLOC ": '%s' not a regular file.", src);
        return FALSE;
    }

    /* check the destination */
    if (g_file_test (dst, G_FILE_TEST_EXISTS)) {

        if (!overwrite) {
            g_critical (G_STRLOC ": Destination file '%s' exists and overwrite is disabled.", dst);
            return FALSE;
        }

        /* remove dest fileif overwrite is enabled */
        if (unlink (dst) != 0) {
            g_critical (G_STRLOC ": %s.", g_strerror (errno));
            return FALSE;
        }
    }

    /* open the input file */
    gint src_fd = open (src, O_RDONLY);
    if (src_fd < 0) {
        g_critical (G_STRLOC ": Unable to open '%s' for reading. %s.", src, g_strerror (errno));
        return FALSE;
    }


    gint dst_fd = -1;
    gpointer mm_in = NULL;
    gpointer mm_out = NULL;

    gboolean ret = FALSE;

    /***** do "goto done;" from here on any errors *****/

    if (fstat (src_fd, &st) != 0) {
        g_critical (G_STRLOC ": %s.", g_strerror (errno));
        goto done;
    }

    /* open the output file */
    dst_fd = open (dst, O_RDWR | O_TRUNC | O_CREAT, 0644);
    if (dst_fd < 0) {
        g_critical (G_STRLOC ": Unable to create '%s' for writing. %s.", dst, g_strerror (errno));
        goto done;
    }

    /* allocate space for the output file */
    if (posix_fallocate (dst_fd, 0, st.st_size)) {
        g_critical (G_STRLOC ": Unable to allocate space for the output file.");
        goto done;
    }

    /***** mmap files and do the copy *****/

    /* map file to memory */
    mm_in = mmap (NULL, st.st_size, PROT_READ, MAP_SHARED, src_fd, 0);
    if (mm_in == MAP_FAILED) {
        g_critical (G_STRLOC ": %s.", g_strerror (errno));
        goto done;
    }

    /* map file to memory */
    mm_out = mmap (NULL, st.st_size, PROT_WRITE, MAP_SHARED, dst_fd, 0);
    if (mm_out == MAP_FAILED) {
        g_critical (G_STRLOC ": %s.", g_strerror (errno));
        goto done;
    }

    /* write the content */
    memcpy (mm_out, mm_in, st.st_size);

    ret = TRUE;

done:

    /* cleanup */
    if (mm_in) {
        munmap (mm_in, st.st_size);
        mm_in = NULL;
    }

    if (mm_out) {
        munmap (mm_out, st.st_size);
        mm_out = NULL;
    }

    if (dst_fd >= 0) {
        close (dst_fd);
        dst_fd = -1;
    }

    if (src_fd >= 0) {
        close (src_fd);
        src_fd = -1;
    }

    return ret;
}