Добавить данные в существующий файл в HDFS Java

У меня возникли проблемы с добавлением данных в существующий файл в HDFS. Я хочу, чтобы, если файл существует, добавьте строку, если нет, создайте новый файл с указанным именем.

Здесь мой метод записи в HDFS.

if (!file.exists(path)){
   file.createNewFile(path);
}

FSDataOutputStream fileOutputStream = file.append(path); 
BufferedWriter br = new BufferedWriter(new OutputStreamWriter(fileOutputStream));
br.append("Content: " + content + "\n");
br.close();

На самом деле этот метод записывается в HDFS и создает файл, но, как я уже упоминал, не добавляется.

Вот как я тестирую свой метод:

RunTimeCalculationHdfsWrite.hdfsWriteFile("RunTimeParserLoaderMapperTest2", "Error message test 2.2", context, null);

Первый параметр - это имя файла, второе - сообщение и два других параметра не важны.

У кого-нибудь есть представление о том, что мне не хватает или что-то не так?

Ответы

Ответ 1

На самом деле вы можете добавить файл HDFS:

С точки зрения клиента, операция добавления сначала вызывает добавление DistributedFileSystem, эта операция вернет объект потока FSDataOutputStream. Если клиенту необходимо добавить данные в этот файл, он может вызвать out.write для записи и вызывает out.close для закрытия.

Я проверил источники HDFS, есть метод DistributedFileSystem#append:

 FSDataOutputStream append(Path f, final int bufferSize, final Progressable progress) throws IOException

Подробнее см. презентация.

Также вы можете добавить через командную строку:

hdfs dfs -appendToFile <localsrc> ... <dst>

Добавьте строки непосредственно из stdin:

echo "Line-to-add" | hdfs dfs -appendToFile - <dst>

Ответ 2

Решено.. !!

Добавить поддерживается в HDFS.

Вам просто нужно выполнить некоторые настройки и простой код, как показано ниже:

Шаг 1: установите для dfs.support.append значение true в hdfs-site.xml:

<property>
   <name>dfs.support.append</name>
   <value>true</value>
</property>

Остановите все ваши сервисы-демоны с помощью stop-all.sh и перезапустите его снова с помощью start-all.sh

Шаг 2 (необязательно): только если у вас есть кластер с одним синглодом, поэтому вы должны установить коэффициент репликации на 1, как показано ниже:

Через командную строку:

./hdfs dfs -setrep -R 1 filepath/directory

Или вы можете сделать то же самое во время выполнения с помощью кода Java:

fsShell.setrepr((short) 1, filePath);  

Шаг 3: код для создания/добавления данных в файл:

public void createAppendHDFS() throws IOException {
    Configuration hadoopConfig = new Configuration();
    hadoopConfig.set("fs.defaultFS", hdfsuri);
    FileSystem fileSystem = FileSystem.get(hadoopConfig);
    String filePath = "/test/doc.txt";
    Path hdfsPath = new Path(filePath);
    fShell.setrepr((short) 1, filePath); 
    FSDataOutputStream fileOutputStream = null;
    try {
        if (fileSystem.exists(hdfsPath)) {
            fileOutputStream = fileSystem.append(hdfsPath);
            fileOutputStream.writeBytes("appending into file. \n");
        } else {
            fileOutputStream = fileSystem.create(hdfsPath);
            fileOutputStream.writeBytes("creating and writing into file\n");
        }
    } finally {
        if (fileSystem != null) {
            fileSystem.close();
        }
        if (fileOutputStream != null) {
            fileOutputStream.close();
        }
    }
}

Пожалуйста, дайте мне знать для любой другой помощи.

Приветствия. !!

Ответ 3

HDFS не позволяет выполнять операции append. Один из способов реализации такой же функциональности, как и добавление:

  • Проверьте, существует ли файл.
  • Если файл не существует, создайте новый файл и напишите в новый файл
  • Если файл существует, создайте временный файл.
  • Прочитать строку из исходного файла и записать эту же строку во временный файл (не забудьте о новой строке)
  • Запишите строки, которые вы хотите добавить во временный файл.
  • Наконец, удалите исходный файл и переместите (переименуйте) временный файл в исходный файл.