Как объединить строки из двух текстовых файлов с помощью Java StreamsJAVA

Программисты JAVA общаются здесь
Ответить Пред. темаСлед. тема
Anonymous
 Как объединить строки из двух текстовых файлов с помощью Java Streams

Сообщение Anonymous »

У меня есть следующее требование (работа с большими текстовыми файлами):
Для данных sourceFile1 и sourceFile2 для каждой строки в обоих файлах объедините значения (построчно) и поместите их в targetFile.
Например: вызов FileMergerImpl.merge(sourceFile1,sourceFile2,targetFile, String::concat); на

Код: Выделить всё

sourceFile1:
Line1
Line2
Line3

sourceFile2:
A
B
Должно получиться:

Код: Выделить всё

targetFile:
Line1A
Line2B
Line3
Вопрос: можно ли достичь исключительно с использованием потоков Java (и, в частности, с использованием java.nio.file.files () )?
Я подумал о вызове FlatMap() в Stream.of(Files.lines(sourceFilename1), Files.lines(sourceFilename2)). Проблема в том, что я не знаю, как объединить записи из каждого потока в один поток.
Вот мое решение для кода, не использующее Java Streams. :

Код: Выделить всё

package com.example.codingTest;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.function.BinaryOperator;

public class FileMergerImpl {

public void merge(Path sourceFilename1, Path sourceFilename2, Path targetFilename, BinaryOperator lineCombiner) {

try (BufferedReader file1Reader = Files.newBufferedReader(sourceFilename1);
BufferedReader file2Reader = Files.newBufferedReader(sourceFilename2);
BufferedWriter targetFileWriter = Files.newBufferedWriter(targetFilename)) {

boolean areThereLinesLeftToRead = true;
while (areThereLinesLeftToRead) {
String file1Line = file1Reader.readLine();
String file2Line = file2Reader.readLine();

if (file1Line != null &&  file2Line != null) {
targetFileWriter.write(lineCombiner.apply(file1Line, file2Line));
} else if (file1Line != null) {
targetFileWriter.write(file1Line);
} else if (file2Line != null) {
targetFileWriter.write(file2Line);
} else {
areThereLinesLeftToRead = false;
}
targetFileWriter.newLine();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
Вот код модульного теста для тех, кто хочет быстро его выполнить:

Код: Выделить всё

package com.example.codingTest;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.beans.factory.annotation.Autowired;

import java.nio.file.Path;

import static com.example.codingTest.TestUtil.*;
import static org.junit.jupiter.api.Assertions.assertEquals;

@ExtendWith(MockitoExtension.class)
public class FileMergerTest {

@Autowired
@InjectMocks
private FileMergerImpl fileMerger;

/**
* Given File1 content:
* Line1
* Line2
* Line3
* and file2 content:
* A
* B
* Expect content to be
* Line1A
* Line2B
* Line3
*/
@Test
public void givenTwoFilesAndThatFirstFileIsLongerThanSecondOneThenMergeContentIntoTarget(){
Path sourceFile1= createPopulatedFile1(true);
Path sourceFile2= createPopulatedFile2(false);
Path targetFile = createEmptyFile();

fileMerger.merge(sourceFile1,sourceFile2,targetFile, String::concat);

assertEquals("Line1A", getContentFrom(targetFile).get(0));
assertEquals("Line2B", getContentFrom(targetFile).get(1));
assertEquals("Line3", getContentFrom(targetFile).get(2));

deleteTemporaryFile(sourceFile1);
deleteTemporaryFile(sourceFile2);
deleteTemporaryFile(targetFile);
}
}

package com.example.codingTest;

import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;

public class TestUtil {

public static Path createPopulatedFile1(boolean isAddExtraLine)  {
Path file1;
BufferedWriter writer = null;
try{
file1 = Files.createTempFile(Path.of("./src/test/resources"),"tempfile_1", ".tmp");
writer = Files.newBufferedWriter(file1);
writer.write("Line1");
writer.newLine();
writer.write("Line2");
writer.newLine();
if(isAddExtraLine) {
writer.write("Line3");
writer.newLine();
}
writer.close();

} catch (IOException e) {
throw new RuntimeException(e);
}
return file1;
}

public static Path createPopulatedFile2(boolean isAddExtraLine)  {
Path file2;
BufferedWriter writer = null;
try{
file2 = Files.createTempFile(Path.of("./src/test/resources"),"tempfile_1", ".tmp");
writer = Files.newBufferedWriter(file2);
writer.write("A");
writer.newLine();
writer.write("B");
writer.newLine();
if(isAddExtraLine) {
writer.write("C");
writer.newLine();
}
writer.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
return file2;
}

public static void deleteTemporaryFile(Path path){
try {
Files.delete(path);
} catch (IOException e) {
throw new RuntimeException(e);
}
}

public static Path createEmptyFile(){
Path tempEmptyFile;
try{
tempEmptyFile = Files.createTempFile(Path.of("./src/test/resources"),"tempEmptyFile",  ".tmp");
} catch (IOException e) {
throw new RuntimeException(e);
}
return tempEmptyFile;
}

public static List getContentFrom(Path targetFile){
try {
return Files.readAllLines(targetFile);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
Заранее спасибо


Подробнее здесь: https://stackoverflow.com/questions/784 ... va-streams
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «JAVA»