Как преобразовать объект Hadoop Path в объект Java-файла
Есть ли способ изменить действительный и существующий объект Hadoop Path в полезный объект Java File. Есть хороший способ сделать это, или мне нужно, чтобы дубинкой кодировать в представлении? Более очевидные подходы не работают, и кажется, что это будет обычная часть кода
void func(Path p) {
if (p.isAbsolute()) {
File f = new File(p.toURI());
}
}
Это не работает, потому что Path::toURI() возвращает идентификатор "hdfs", а конструктор Java File(URI uri) распознает только идентификатор "file".
Есть ли способ заставить Path и File работать вместе?
**
Хорошо, как насчет конкретного ограниченного примера.
Path[] paths = DistributedCache.getLocalCacheFiles(job);
Предполагается, что DistributedCache предоставляет локализованную копию файла, но возвращает путь. Я предполагаю, что DistributedCache создает локальную копию файла, где они находятся на одном диске. Учитывая этот ограниченный пример, где, как мы надеемся, hdfs не входит в уравнение, есть ли способ для меня надежно преобразовать Path в файл?
**
3 ответа
Не то, чтобы я знал.
Насколько я понимаю, Path
в Hadoop представляет идентификатор для узла в их распределенной файловой системе. Это отличная абстракция от java.io.File
, который представляет собой узел в локальной файловой системе. Вряд ли Path
может даже иметь File
представление, которое будет вести себя эквивалентно, потому что базовые модели принципиально отличаются.
Отсюда и отсутствие перевода. Я полагаю, ваше утверждение, что File
объекты "[более] полезны", вам нужен объект этого класса, чтобы использовать существующие методы библиотеки? По указанным выше причинам это не будет работать очень хорошо. Если это ваша собственная библиотека, вы можете переписать ее для чистой работы с путями Hadoop, а затем преобразовать любые файлы в объекты пути (это направление работает, поскольку пути являются строгим надмножеством файлов). Если это сторонняя библиотека, то вам не повезло; авторы этого метода не приняли во внимание влияние распределенной файловой системы и только написали этот метод для работы с простыми старыми локальными файлами.
У меня недавно был тот же вопрос, и действительно есть способ получить файл по пути, но он требует временной загрузки файла. Очевидно, что это не подойдет для многих задач, но если вам не нужно время и пространство, а вам просто нужно что-то для работы с файлами из Hadoop, сделайте что-то вроде следующего:
import java.io.File;
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
public final class PathToFileConverter {
public static File makeFileFromPath(Path some_path, Configuration conf) throws IOException {
FileSystem fs = FileSystem.get(some_path.toUri(), conf);
File temp_data_file = File.createTempFile(some_path.getName(), "");
temp_data_file.deleteOnExit();
fs.copyToLocalFile(some_path, new Path(temp_data_file.getAbsolutePath()));
return temp_data_file;
}
}
Если вы получаете LocalFileSystem
final LocalFileSystem localFileSystem = FileSystem.getLocal(configuration);
Вы можете передать свой объект Path hadoop в localFileSystem.pathToFile
final File localFile = localFileSystem.pathToFile(<your hadoop Path>);