Как читать файл построчно, не читая весь файл в ОЗУ - PullRequest
0 голосов
/ 15 февраля 2019

Я пытаюсь найти наиболее эффективный метод для чтения больших файлов, манипулирования данными и выполнения некоторых внешних функций на выходе в Java / Groovy.Из того, что я прочитал, можно сделать это с помощью BufferedReader, Scanner, FileIterator или с помощью Stream, но в каждом тестовом примере пока что моя куча переполняется.Я не уверен, что выполняю последовательность шагов неправильно или это нормальное поведение.Будем весьма благодарны за любую помощь в определении того, что я сделал что-то не так с моим кодом или пропустил какой-то другой метод.Исходный файл - это просто CSV-файл объемом 1 ГБ с именем test.csv.

package test;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.LineIterator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import sftp.SftpConnector;
import sftp.SftpHandler;
import sftp.fileInfo;
import java.io.*;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.Collection;
import java.util.Date;
import java.util.Properties;
import java.util.Scanner;
import java.util.logging.Logger;
import java.nio.file.Files;
import java.util.stream.Stream;

@RestController
public class TestController {


private SftpConnector connector;

@Autowired
public TestController(){
    try{
        this.connector = new SftpConnector(this.getProperties());
    }catch(Exception ex){
        System.out.println(ex.getMessage());
    }
}

public Properties getProperties(){
    Properties prop = new Properties();
    try{
        File propfile = new File("C:\\tmp\\connection2.properties");
        prop.load(new FileInputStream(propfile));
    }catch(FileNotFoundException fnf){
        System.out.println("Could not find the connection.properties prop file.");
    }catch(IOException IO){
        System.out.println("Could not open the connection.properties file.");
    }
    return prop;
}

@GetMapping(value="/test")
@ResponseBody
public String testConnection(){
    String response = "";
    try{
        this.connector.openSFTPConnection();
        response = "Connection has been opened";
    }catch(Exception ex){
        response = ex.getMessage();
    }finally{
        if( this.connector.getSession().isConnected()){
            try{
                this.connector.closeSFTPConnection();
            }catch(Exception ex){
                response = response + ex.getMessage();
            }
        }
    }
    return response;
}

@GetMapping(value="/testLogger")
@ResponseBody
public String testLogger(){
    String response = "";
    Logger LOG = Logger.getLogger(Logger.getGlobal().getName());
    try{
        SftpHandler handler = new SftpHandler(this.getProperties());
        LOG.addHandler(handler);
    }catch(Exception ex){
        response = ex.getMessage();
    }
    try{
        LOG.info("Opening the SFTP Channel");
        this.connector.openSFTPConnection();
        LOG.info("Channel is opened.  Getting the list of XML's");
        Collection<fileInfo> files = this.connector.ls("/IB_Test", "*.xml");
        LOG.info("List retrieved.  Downloading each xml file");
        for(fileInfo file: files){
            LOG.info("Downloading " + file.getName());
            this.connector.get("/IB_Test/" + file.getName(), "C:\\tmp\\");
            LOG.info("Downloaded");
        }
        LOG.info("All XML's have been downloaded.");
        response = "All files have been downloaded";
    }catch(Exception ex){
        LOG.severe("Exception thrown:" + ex.getMessage());
        response = ex.getMessage();
    }finally{
        if(this.connector.getSession().isConnected()){
            try{
                LOG.info("Attempting to close the SFTP connection");
                this.connector.closeSFTPConnection();
            }catch(Exception ex){
                LOG.severe("Exception thrown: " + ex.getMessage());
                response = response + ex.getMessage();
            }
        }
    }
    return response;
}

@GetMapping(value="/testScanner")
@ResponseBody public String testScanner(){
    InputStream input = null;
    try{
        input = new FileInputStream(new File("C:\\tmp\\test.csv"));
        Scanner sc = new Scanner(input);
        while(sc.hasNextLine()){
            String line = sc.nextLine();
            System.out.println(line);
        }
    }catch(Exception fnf){
        System.out.println(fnf.getMessage());
    }
    return "File has completed upload line by line...";
}

@GetMapping(value="/testFilesNIO")
@ResponseBody public String testFilesNIO(){
    String output = "";
    try{
        Stream<String> lines = Files.lines(Paths.get("C:\\tmp\\test.csv"));
        lines.forEach(
                line ->
                        System.out.println(line)
        );
    }catch( Exception ex){
        output = ex.getMessage();
    }
    return output;
}

@GetMapping(value="/testFilesNIOwBufferedReader")
@ResponseBody public String testFilesNIOwBufferedReader(){
    String output = "";
    try{
        BufferedReader reader = Files.newBufferedReader(Paths.get("C:\\tmp\\test.csv"));
        reader.lines().skip(1).forEach(
                line -> System.out.println(line)
        );
    }catch( Exception ex){
        output = ex.getMessage();
    }
    return output;
}

@GetMapping(value="/trueBufferedReader")
@ResponseBody public String trueBufferedReader(){
    String output = "";
    try{
        BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(new File("C:\\tmp\\test.csv"))),10000000);
        String line ;
        while( (line = reader.readLine()) != null){
            System.out.println(line);
        }
    }catch(Exception ex){
        output = ex.getMessage();
    }
    return output;
}

@GetMapping(value="/lineIterator")
@ResponseBody public String lineIterator(){
    String output = "";
    try{
        LineIterator it = FileUtils.lineIterator(new File("C:\\tmp\\test.csv"));
        try{
            while( it.hasNext()){
                System.out.println(it.nextLine());
            }

        }finally{
            LineIterator.closeQuietly(it);
        }
    }catch(Exception ex){
        output = ex.getMessage();
    }
    return output;
}
}

Ожидаемый результат - увидеть каждую строку CSV-файла, выведенную на консоль.

Ответы [ 4 ]

0 голосов
/ 15 февраля 2019

Это была опечатка в моем CSV-файле, из-за которой в конце не было перевода строки.Таким образом, был готов весь документ в 1 строку.

0 голосов
/ 15 февраля 2019

Или в Groovy:

yourFile.withReader('UTF-8') { r ->
    r.eachLine { line ->
        println line
    }
}
0 голосов
/ 15 февраля 2019

во всех ваших тестах вы читаете файл построчно, чтобы передать его в System.out

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

yourFile.withInputStream{stream->
    System.out << stream
}

Обратите внимание, что System.out довольно медленно ...

0 голосов
/ 15 февраля 2019
Charset yourCharset = Charset.forName("UTF-8");
try (BufferedReader br = Files.newBufferedReader(your_file, yourCharset )) {
    String singleLine = null;
    while ((singleLine = br.readLine()) != null) {
        System.out.println(singleLine );
    }
} catch (IOException ex) {
    // handle exception
}
...