2017-03-22 2 views
0

Ich lese eine Datei von HDFS. Ich verwende den folgenden Code, um dies zu erreichen.Java-Code nicht in der Lage, Datei von HDFS vollständig zu lesen

public class ClassMain { 

    public static void main(String[] args) throws IOException { 

    Configuration conf = new Configuration(); 
    FileSystem fs = FileSystem.get(conf); 
    Path inFile = new Path(args[1]); 
    Path outFile = new Path(args[2]); 
    FSDataInputStream in = fs.open(inFile); 
    FSDataOutputStream out = fs.create(outFile); 
    byte buffer[] = new byte[4096]; 
    try{ 
    int bytesRead = 0; 
    while ((bytesRead = in.read(buffer)) > 0) 
    { 
    out.write(buffer, 0, bytesRead); 
    } 
    } 
    catch (IOException e) 
    { 
    System.out.println("ERROR*****************"+e); 
    } 
    finally 
    { 
    in.close(); 
    out.close(); 
    } 

Es ist nicht in der Lage, meine Datei vollständig von HDFS zu lesen. Die Größe der Beispieldatei ist 1.004,9 K. Ich habe versucht, den Wert so hoch wie

byte buffer[] = new byte[12000000]; 

Erhöhung Aber es ist immer noch nicht in der Lage, die Datei vollständig zu lesen.

Gibt es alternative Möglichkeiten, dies zu tun? Dies ist nur eine kleine Beispielgröße von 1 MB in HDFS. Dateien wären so groß wie 3 bis 4 GB. Gibt es eine Möglichkeit, etwas wie zu verwenden: long buffer[] = new long[12000000];, so dass es größere Größe in Puffer aufnehmen kann.

+0

Müssen Sie wirklich die ganze Datei herunterladen? Wenn ja, warum hast du es in HDFS gesetzt? Können Sie beispielsweise Spark verwenden, um Teile der Datei zu bearbeiten? –

Antwort

1

Die Bedingung ist falsch, es ist durchaus möglich, dass ein Stream 0 Bytes über das Netzwerk liest. Nur -1 bestimmt das Ende des Streams.

dass Deshalb sollte das Problem für Sie beheben:

while ((bytesRead = in.read(buffer)) != -1) 

Wie Sie sich vorstellen können, gibt es bereits Bibliotheken für die, commons-io zum Beispiel kommt mit einem Verfahren copy dass Kopien ein Stream in einer anderen genannt.

Einfaches Beispiel in drei Linien:

try(FSDataInputStream in = fs.open(inFile)){ 
    try(FSDataOutputStream out = fs.create(outFile)){ 
     IOUtils.copy(in, out); 
    } 
} 
+0

while ((bytesRead = in.read (buffer))! = -1) hat nicht geholfen. Tatsächlich verlangsamte es die Performance auch bei einer kleineren Datei. Und es hat das Problem für große Dateien nicht gelöst. – earl

+0

Die zweite Option hat das gleiche für kleine und große Dateien getan. – earl

+0

Ich versuche, den Wert für neues Byte [] zu erhöhen und die Bedingung als in.read (buffer)! = -1 zu behalten. Bei kleineren Werten hat er einen kleinen Teil im Puffer gelesen und ich habe ihn weiter erhöht. Nach 517888 hat es keinen Effekt. Es ändert den über diesen Punkt gelesenen Teil nicht. Ich verstehe nicht, was das Problem mit meinem Code ist. – earl

0

diesen Code gefunden, der für mich arbeitet. Es kann auch größere Dateien lesen.

public class MainClass { 

public static void main(String[] args) throws IOException{ 

    Configuration conf = new Configuration(); 
    FileSystem fs = FileSystem.get(conf); 
    Path inFile = new Path(args[1]); 
    Path outFile = new Path(args[2]); 

    BufferedReader br=new BufferedReader(new InputStreamReader(fs.open(inFile))); 
    String line; 
    line=br.readLine(); 

    String concatAllLines = line; 
    while (line != null){ 
      //System.out.println("reading lines"); 
      line=br.readLine(); 
      System.out.println(line); 
      if(line != null) 
       concatAllLines += line; 
    } 

    System.out.println(concatAllLines); 
} 
Verwandte Themen