我是Vala的新手,所以这可能是一个愚蠢的问题。
根据gimpnet上的#vala,无法使用 Glib.File.copy 递归复制目录。目前我正在使用:
Posix.system("cp -r absolutesource absolutedestination")
有更好的方法吗?
答案 0 :(得分:3)
正如我在IRC中告诉你的那样,你可以通过为要复制的每个文件调用GLib.File.copy
来自己编写一个函数。这是一个基本的例子:
public bool copy_recursive (GLib.File src, GLib.File dest, GLib.FileCopyFlags flags = GLib.FileCopyFlags.NONE, GLib.Cancellable? cancellable = null) throws GLib.Error {
GLib.FileType src_type = src.query_file_type (GLib.FileQueryInfoFlags.NONE, cancellable);
if ( src_type == GLib.FileType.DIRECTORY ) {
dest.make_directory (cancellable);
src.copy_attributes (dest, flags, cancellable);
string src_path = src.get_path ();
string dest_path = dest.get_path ();
GLib.FileEnumerator enumerator = src.enumerate_children (GLib.FileAttribute.STANDARD_NAME, GLib.FileQueryInfoFlags.NONE, cancellable);
for ( GLib.FileInfo? info = enumerator.next_file (cancellable) ; info != null ; info = enumerator.next_file (cancellable) ) {
copy_recursive (
GLib.File.new_for_path (GLib.Path.build_filename (src_path, info.get_name ())),
GLib.File.new_for_path (GLib.Path.build_filename (dest_path, info.get_name ())),
flags,
cancellable);
}
} else if ( src_type == GLib.FileType.REGULAR ) {
src.copy (dest, flags, cancellable);
}
return true;
}
另外,值得注意的是,您可能希望使用GLib.Process中的一个函数而不是Posix.system。
答案 1 :(得分:0)
我遇到了这个问题,在 C 中使用 GLib/GIO 寻找类似的东西。
这是我尝试将上面的 C++ 代码转换为 C
gboolean
copy_recursive(GFile *src, GFile *dest, GFileCopyFlags flags, GCancellable *cancellable, GError **error) {
GFileType src_type = g_file_query_file_type(src, G_FILE_QUERY_INFO_NONE, cancellable);
if (src_type == G_FILE_TYPE_DIRECTORY) {
g_file_make_directory(dest, cancellable, error);
g_file_copy_attributes(src, dest, flags, cancellable, error);
GFileEnumerator *enumerator = g_file_enumerate_children(src, G_FILE_ATTRIBUTE_STANDARD_NAME, G_FILE_QUERY_INFO_NONE, cancellable, error);
for (GFileInfo *info = g_file_enumerator_next_file(enumerator, cancellable, error); info != NULL; info = g_file_enumerator_next_file(enumerator, cancellable, error)) {
const char *relative_path = g_file_info_get_name(info);
copy_recursive(
g_file_resolve_relative_path(src, relative_path),
g_file_resolve_relative_path(dest, relative_path),
flags, cancellable, error);
}
} else if (src_type == G_FILE_TYPE_REGULAR) {
g_file_copy(src, dest, flags, cancellable, NULL, NULL, error);
}
return TRUE;
}
作为奖励,这里有一个递归删除目录的函数
gboolean
delete_recursive(GFile *file, GCancellable *cancellable, GError **error) {
GFileType file_type = g_file_query_file_type(file, G_FILE_QUERY_INFO_NONE, cancellable);
if (file_type == G_FILE_TYPE_DIRECTORY) {
GFileEnumerator *enumerator = g_file_enumerate_children(file, G_FILE_ATTRIBUTE_STANDARD_NAME, G_FILE_QUERY_INFO_NONE, cancellable, error);
for (GFileInfo *info = g_file_enumerator_next_file(enumerator, cancellable, error); info != NULL; info = g_file_enumerator_next_file(enumerator, cancellable, error)) {
delete_recursive(
g_file_resolve_relative_path(file, g_file_info_get_name(info)),
cancellable, error);
}
g_file_delete(file, cancellable, error);
} else if (file_type == G_FILE_TYPE_REGULAR) {
g_file_delete(file, cancellable, error);
}
return TRUE;
}