web-dev-qa-db-fra.com

Ajouter des données à un fichier existant dans HDFS Java

Je ne parviens pas à ajouter des données à un fichier existant dans HDFS. Je veux que si le fichier existe, ajoutez une ligne, sinon, créez un nouveau fichier avec le nom indiqué.

Voici ma méthode pour écrire dans 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();

En fait, cette méthode écrit dans HDFS et crée un fichier mais, comme je le dis, n’ajoute rien.

Voici comment je teste ma méthode:

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

Le premier paramètre est le nom du fichier, le second le message et les deux autres paramètres ne sont pas importants.

Donc, quiconque a une idée de ce que je manque ou que je fais mal?

19
kennechu

En fait, vous pouvez ajouter à un fichier HDFS:

Du point de vue du client, l'opération d'ajout appelle tout d'abord l'ajout de DistributedFileSystem. Cette opération renvoie un objet de flux FSDataOutputStream out. Si le client doit ajouter des données à ce fichier, il peut appeler out.write pour écrire et appeler out.close pour fermer.

J'ai vérifié les sources HDFS, il existe une méthode DistributedFileSystem#append:

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

Pour plus de détails, voir présentation .

Aussi, vous pouvez ajouter en ligne de commande:

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

Ajoutez des lignes directement à partir de stdin:

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

HDFS n'autorise pas les opérations append. Une façon d'implémenter la même fonctionnalité que l'ajout est:

  • Vérifiez si le fichier existe. 
  • Si le fichier n'existe pas, créer un nouveau fichier et écrire dans un nouveau fichier
  • Si le fichier existe, créez un fichier temporaire. 
  • Lire la ligne du fichier original et écrire cette même ligne dans un fichier temporaire (n'oubliez pas la nouvelle ligne)
  • Ecrivez les lignes que vous souhaitez ajouter au fichier temporaire.
  • Enfin, supprimez le fichier d'origine et déplacez (renommez) le fichier temporaire dans le fichier d'origine.
3
Chaos

Résolu .. !!

Append est pris en charge dans HDFS.

Il vous suffit de faire quelques configurations et un code simple comme indiqué ci-dessous:

Étape 1 : définissez dfs.support.append sur true dans hdfs-site.xml:

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

Arrêtez tous vos services démon en utilisant stop-all.sh et redémarrez-le en utilisant start-all.sh 

Étape 2 (facultatif) : uniquement Si vous avez un cluster à code unique, vous devez donc définir le facteur de réplication sur 1 comme indiqué ci-dessous:

En ligne de commande: 

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

Ou vous pouvez faire la même chose au moment de l'exécution avec le code Java: 

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

Étape 3 : Code pour la création/l'ajout de données dans le fichier:

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();
        }
    }
}

Faites-le moi savoir pour toute autre aide.

À votre santé.!!

2