2014-04-10 5 views
15

Ich habe Probleme, Daten an eine vorhandene Datei in HDFS anzufügen. Ich möchte, dass, wenn die Datei existiert, dann eine Zeile anhängen, wenn nicht, erstellen Sie eine neue Datei mit dem angegebenen Namen.Daten an vorhandene Datei in HDFS Java anfügen

Hier ist meine Methode zum Schreiben in HDFS.

Eigentlich schreibt diese Methode in HDFS und erstellt eine Datei, aber wie ich erwähne hängt nicht an.

Dies ist, wie ich meine Methode testen:

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

Der erste param ist der Name der Datei, die zweite ist die Nachricht und die beiden anderen params sind nicht wichtig.

Also hat jemand eine Idee, was ich vermisse oder falsch mache?

+0

Das erste, was Sie wissen müssen, dass hdfs einmal schreiben Dateisystem ist. Wir können nicht an hdfs anhängen oder überschreiben. Wir können jedoch so oft wie möglich lesen. Bitte gehen Sie dazu durch das Buch "Hadoop: Das definitive Handbuch". –

+0

Was ist der Typ der Variablen 'Datei'? – Chaos

+0

Check out http://www.slideshare.net/dataera/inside-hdfs-append – matanster

Antwort

2

HDFS lässt append Operationen nicht zu. Eine Möglichkeit, dieselbe Funktionalität wie das Anhängen zu implementieren, ist:

  • Überprüfen Sie, ob die Datei vorhanden ist.
  • Wenn die Datei nicht existiert, erstellen Sie eine neue Datei. & In neue Datei schreiben
  • Wenn die Datei existiert, erstellen Sie eine temporäre Datei.
  • Zeile von Originaldatei lesen & dieselbe Zeile in temporäre Datei schreiben (Newline nicht vergessen)
  • Schreiben Sie die Zeilen, die Sie an die temporäre Datei anhängen möchten.
  • Schließlich löschen Sie die ursprüngliche Datei & verschieben (umbenennen) die temporäre Datei in die ursprüngliche Datei.
+5

Ok, eigentlich modifiziere ich die hdfs-site.xml add tow Eigenschaften und es funktioniert für mich, das sind die zwei Eigenschaften, die ich verwendet habe: dfs.replication dfs.support.append wahr kennechu

+0

gerade getestet das andere Antwort, und Ihre war gebunden, so musste ich testen und sicherstellen, dass -appendToFile tatsächlich funktioniert – Marcel

28

Eigentlich kann man auf eine HDFS Datei anhängen:

Aus Sicht der Client anhängen Betrieb zunächst Anfügen von Distributed File nennt, würde dieser Vorgang ein Stream-Objekt FSDataOutputStream Rückkehr aus. Wenn der Client Daten an diese Datei anhängen muss, kann er out.write aufrufen, um zu schreiben, und ruft out.close zum Schließen auf.

I HDFS Quellen überprüft, gibt es DistributedFileSystem#append Methode:

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

Einzelheiten finden Sie presentation.

Sie können auch über die Befehlszeile anhängen:

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

hinzufügen Linien direkt von stdin:

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

getestet und es funktioniert – Marcel

+0

Fantastische Antwort in der Tat. +1 für das Quellcode-Snippet. – Azim

1

Gelöst .. !!

Anhang wird in HDFS unterstützt.

Sie müssen nur einige Konfigurationen und einfachen Code zu tun, wie unten dargestellt:

Schritt 1: set dfs.support.append als wahr in hdfs-site.xml:

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

Stopp Alle Ihre Daemon-Dienste mit stop-all.sh und starten Sie es erneut mit start-all.sh

Schritt 2 (Optional): Nur Wenn Sie eine single-node-Cluster haben, so müssen Sie s et Replikationsfaktor auf 1 wie folgt:

Durch Befehlszeile:

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

Oder Sie können zur Laufzeit durch Java-Code das gleiche tun:

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

Schritt 3: Code für Erstellen/Anhängen von Daten in die Datei:

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

Bitte lassen Sie mich für jede andere Hilfe wissen.

Prost. !!