2014-04-10 16 views
15

Ho problemi ad aggiungere dati a un file esistente in HDFS. Voglio che se il file esiste allora aggiungi una riga, altrimenti, crea un nuovo file con il nome dato.Aggiunta di dati a file esistenti in HDFS Java

Ecco il mio metodo per scrivere in 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(); 

In realtà questo metodo scrive in HDFS e creare un file, ma come ho detto non è aggiungendo.

Questo è quanto ho testare il mio metodo:

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

Il primo param è il nome del file, la seconda il messaggio e gli altri due params non sono importanti.

Quindi qualcuno ha un'idea di ciò che mi manca o che non funziona?

+0

Per prima cosa è necessario sapere che hdfs è un file system di scrittura una tantum. Non possiamo aggiungere o sovrascrivere in hdf. Tuttavia, possiamo leggere tutte le volte che possiamo. Si prega di consultare il libro "Hadoop: The definitive Guide" per questo. –

+0

Qual è il tipo della variabile 'file'? – Chaos

+0

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

risposta

2

HDFS non consente operazioni append. Un modo per implementare la stessa funzionalità dell'appendice è:

  • Verificare se il file esiste.
  • Se il file non esiste, quindi creare il nuovo file & scrivere nel nuovo file
  • Se il file esiste, creare un file temporaneo.
  • Leggi riga dal file originale & scrivere stessa linea, per file temporaneo (non dimenticare il ritorno a capo)
  • scrivere i versi che si desidera aggiungere al file temporaneo.
  • Infine, eliminare il file originale & spostare (rinominare) il file temporaneo nel file originale.
+5

Ok, in realtà modifico il file hdfs-site.xml aggiungendo le proprietà tow e funziona per me, queste sono le due proprietà che ho usato: dfs.replication dfs.support.append vero kennechu

+0

appena testato la altra risposta, e la tua era legata, quindi ho dovuto testare e verificare che -appendToFile funzioni effettivamente – Marcel

28

In realtà, è possibile aggiungere un file HDFS:

Dal punto di vista del cliente, aggiungere operazione prevede in primo luogo di aggiunta di DistributedFileSystem, questa operazione potrebbe restituire un flusso FSDataOutputStream oggetto fuori. Se il Cliente deve aggiungere dati a questo file, può chiamare out.write per scrivere e chiama out.close per chiudere.

ho controllato fonti HDFS, c'è DistributedFileSystem#append metodo:

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

Per i dettagli, vedere presentation.

Inoltre è possibile aggiungere tramite riga di comando:

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

Aggiungere linee direttamente dallo standard input:

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

testato e funzioni – Marcel

+0

Risposta fantastica davvero. +1 per lo snippet del codice sorgente. – Azim

1

risolto .. !!

Append è supportato in HDFS.

Devi solo fare alcune configurazioni e il codice secondo la tabella riportata di seguito:

Fase 1: impostare dfs.support.append come vero in HDFS-site.xml:

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

arresto tutti i servizi che utilizzano demone stop-all.sh e riavviare di nuovo con start-all.sh

Fase 2 (opzionale): solo se si dispone di un cluster singlenode, in modo da avere a s fattore di replica et al 1 come di seguito:

attraverso la linea di comando:

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

Oppure si può fare lo stesso in fase di esecuzione tramite il codice java:

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

Fase 3: Codice per Creazione/aggiunta di dati nel file:

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

Gentilmente fammi sapere per qualsiasi altro aiuto.

Cheers. !!