我是 Vala 的新手,所以这可能是一个愚蠢的问题。
根据 gimpnet 上的#vala,无法使用Glib.File.copy递归复制目录。目前我正在使用:
Posix.system("cp -r absolutesource absolutedestination")
有没有更好的方法来做到这一点?
正如我在 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。
我遇到了这个问题,使用 GLib/GIO 在 C 中寻找类似的东西。
这是我尝试将上面的 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;
}