Nano Hash - криптовалюты, майнинг, программирование

Bufferreader и Bufferwriter для чтения и записи файлов hdfs

Я пытаюсь читать из файла hdfs построчно, а затем создавать файл hdfs и писать в него построчно. Код, который я использую, выглядит так:

            Path FileToRead=new Path(inputPath);
        FileSystem hdfs = FileToRead.getFileSystem(new Configuration());            
        FSDataInputStream fis = hdfs.open(FileToRead);
        BufferedReader reader = new BufferedReader(new InputStreamReader(fis));

        String line;
            line = reader.readLine(); 
            while (line != null){

                String[] lineElem = line.split(",");
                for(int i=0;i<10;i++){

                    MyMatrix[i][Integer.valueOf(lineElem[0])-1] = Double.valueOf(lineElem[i+1]);
                }

                line=reader.readLine();
        } 

        reader.close();
        fis.close();


        Path FileToWrite = new Path(outputPath+"/V"); 
        FileSystem fs = FileSystem.get(new Configuration());
        FSDataOutputStream fileOut = fs.create(FileToWrite);
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(fileOut));
        writer.write("check");
        writer.close();
        fileOut.close();

Когда я запускаю этот код в моем файле outputPath, V не создается. Но если я заменю часть для чтения частью для записи, файл будет создан, и в него будет записана проверка. Может ли кто-нибудь помочь мне понять, как правильно их использовать, чтобы иметь возможность сначала прочитать весь файл, а затем записать в файл построчно?

Я также пробовал другой код для чтения из одного файла и записи в другой, но файл будет создан, но в него ничего не записывается!

Я использую что-то вроде этого:

  hadoop jar main.jar program2.Main input output

Затем в моей первой работе я читаю из arg[0] и записываю в файл в args[1]+"/NewV" с использованием классов уменьшения карты, и это работает. В моем другом классе (без уменьшения карты) я использую args[1]+"/NewV" в качестве входного пути и output+"/V_0" в качестве выходного пути (я передаю эти строки конструктору). вот код класса:

 public class Init_V {

String inputPath, outputPath;


public Init_V(String inputPath, String outputPath) throws Exception {

    this.inputPath = inputPath;
    this.outputPath = outputPath;


    try{            

        FileSystem fs = FileSystem.get(new Configuration());
        Path FileToWrite = new Path(outputPath+"/V.txt"); 
        Path FileToRead=new Path(inputPath);
        BufferedWriter output = new BufferedWriter
         (new OutputStreamWriter(fs.create(FileToWrite,
                 true)));  

        BufferedReader reader = new
            BufferedReader(new InputStreamReader(fs.open(FileToRead)));
                 String data;
                 data = reader.readLine();
                 while ( data != null ) 
                 {
                     output.write(data);
                     data = reader.readLine();
                 }
                 reader.close();                     
                 output.close(); }catch(Exception e){
}

}

}
12.05.2013

  • Существует ли файл по локальному пути? Возможно, либо вы передаете выходной путь с локальным контекстом (file:///path/to/file), либо файловая система по умолчанию является локальной. Можете ли вы поделиться строкой вызова, с которой вы запускаете программу, и значением fs.default.name из вашего $HADOOP_CONF/core-site.xml 13.05.2013
  • На самом деле файл, который я пытаюсь прочитать, — это файл, созданный другим заданием в HDFS. И он существует в выходном каталоге, расположенном в HDFS. После прочтения этого файла я могу создать файл, в который я хочу записать, в том же каталоге вывода (в HDFS). Я использую вывод вывода Hadoop fs -get, чтобы скопировать его на свой локальный компьютер, и когда я проверяю только что созданный файл, он пуст! 13.05.2013

Ответы:


1

Я думаю, вам нужно понять, как правильно работает хауп. В Hadoop многое делается системой, вы просто указываете путь ввода и вывода, затем они открываются и создаются Hadoop, если пути действительны. Проверьте следующий пример;

public int run (String[] args) throws Exception{

    if(args.length != 3){
        System.err.println("Usage: MapReduce <input path> <output path> ");
        ToolRunner.printGenericCommandUsage(System.err);
    }
    Job job = new Job();
    job.setJarByClass(MyClass.class);
    job.setNumReduceTasks(5);
    job.setJobName("myclass");
    FileInputFormat.addInputPath(job, new Path(args[0]) );
    FileOutputFormat.setOutputPath(job, new Path(args[1]));

    job.setMapperClass(MyMapper.class);
    job.setReducerClass(MyReducer.class);

    job.setOutputKeyClass(Text.class);
    job.setOutputValueClass(Text.class);

    return job.waitForCompletion(true) ? 0:1 ;
}


/* ----------------------main---------------------*/
public static void main(String[] args) throws Exception{    

    int exitCode = ToolRunner.run(new MyClass(), args);
    System.exit(exitCode);
}

Как вы видите здесь, вы инициализируете только необходимые переменные, а чтение и запись выполняется с помощью Hadoop.

Кроме того, в вашем классе Mapper вы говорите context.write(key, value) внутри карты, и аналогично в вашем классе Reduce вы делаете то же самое, он пишет за вас.

Если вы используете BufferedWriter/Reader, он будет записывать в вашу локальную файловую систему, а не в HDFS. Чтобы увидеть файлы в HDFS, вы должны написать hadoop fs -ls <path>, файлы, которые вы просматриваете командой ls, находятся в вашей локальной файловой системе.

EDIT: Чтобы использовать чтение/запись, вы должны знать следующее: Допустим, у вас есть N машин в вашей сети hadoop. Когда вы захотите читать, вы не будете знать, какой маппер читает, как и пишет. Таким образом, все мапперы и редукторы должны иметь эти пути, чтобы не создавать исключений.

Я не знаю, можете ли вы использовать какой-либо другой класс, но вы можете использовать два метода по вашей конкретной причине: startup и cleanup. Эти методы используются только один раз в каждой карте и уменьшают рабочий процесс. Поэтому, если вы хотите читать и писать, вы можете использовать эти файлы. Чтение и запись аналогичны обычному коду Java. Например, вы хотите увидеть что-то для каждого ключа и хотите записать это в txt. Вы можете сделать следующее:

//in reducer
BufferedReader bw ..;

void startup(...){
     bw  = new ....;
}

void reduce(...){
    while(iter.hasNext()){ ....;
    }
    bw.write(key, ...);
}
void cleanup(...){
    bw.close();
}
12.05.2013
  • Спасибо за ваш ответ. Но проблема в том, что я хочу работать с файлами hdfs в классе, но не обязательно отображать или уменьшать классы. Во втором коде выходной файл создается в hdfs, но в него записывается заметка! Есть ли способ читать и записывать файлы hdfs в классе, но отображать или уменьшать? 12.05.2013
  • рабочий стиль Hadoop: for each key(generally line) выполнить map операцию и for each key in reducer collect elements of the same key and write in to hdfs. Я не знаю, есть ли другой способ использования уменьшения карты, но таким образом вы автоматически сортируете данные по ключу. это еще одно преимущество MR. 13.05.2013
  • Я видимо не правильно задаю вопрос. На самом деле я пытаюсь читать из файла и записывать в файл, не используя классы Mapper или Reduce. Мне нужно один раз прочитать из файла и сохранить данные (я использую матрицу), а после обработки данных записать результат в другой файл. Но я хочу сделать все это в обычном классе, а не в Mapper или Reduce. Мне приходится работать с одним файлом и я хочу иметь доступ ко всем строкам одновременно, и я не уверен, что использование распределенного кеша решит мою проблему. Если я хочу использовать Mapper и Reduce, мне может понадобиться 2 задания, которые займут довольно много времени. 13.05.2013
  • Я отредактировал свой пост. читать только после EDIT, который должен быть вашим ответом, если я правильно понимаю 13.05.2013
  • Спасибо за ваше объяснение. Но боюсь и это не поможет. Позвольте мне объяснить, какую проблему я пытаюсь решить. Может, станет понятнее. У меня есть файл, который содержит идентификаторы и векторы признаков (каждая строка выглядит так: ID, 1, 3, 4). Мне нужно прочитать строку за строкой и рассчитать расстояние для этого идентификатора до других строк и найти минимальное расстояние для каждой из них. Затем я должен найти K максимальных расстояний среди этих минимумов и записать идентификаторы и векторы признаков с максимальным (минимальным расстоянием) в другой текстовый файл. Я хочу, чтобы мой ввод и вывод были в HDFS, а не локально. 13.05.2013
  • Я не знал, как это сделать с помощью Mapper и Reduce. Я могу найти минимумы и записать их в один файл, но для k Max понятия не имею. И маппер читает одну строку, а мне нужно иметь доступ ко всем строкам. А для нахождения k max мне нужно иметь доступ ко всем минимумам. Я знаю, как это сделать в обычном классе. Так что, если я смогу решить проблему чтения и записи файлов HDFS, проблема может быть решена! 13.05.2013
  • Вы имеете в виду все строки, начинающиеся с ID, или все строки в файле? Если это каждый идентификатор, то ваш ключ будет идентификатором, а сокращение соберет все строки, соответствующие идентификатору, и вы сделаете все, что захотите, в конце метода сокращения. Если вы имеете в виду все линии, то вам не нужно работать с хаупом, потому что он вам вообще не помогает. 13.05.2013
  • Да, я имею в виду все строки с разными идентификаторами. На самом деле это небольшая часть, которую я не буду использовать Mapper и Reduce. Они нужны мне для остальной части моей программы. 13.05.2013
  • Вы можете собрать все данные, связанные с идентификатором, в редюсере. в самом конце редуктора вы должны вызвать метод, скажем, Id_issue() этот метод будет делать все, что вы хотите. 13.05.2013
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..