Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

import java.io.*;
import java.io.FileNotFoundException;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.CodingErrorAction;
import java.nio.charset.StandardCharsets;
Expand Down Expand Up @@ -146,46 +147,37 @@ public static void cd(final String changDirectory) throws FileSystemException {
}

/**
* 파일을 읽는다.
* 파일을 플랫폼 기본 문자셋({@link Charset#defaultCharset()})으로 읽는다.
* 인코딩을 지정하려면 {@link #readFile(File, String)}을 사용한다.
*/
public static String readFile(File file) throws IOException {
BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));
String sResult = "";

try {
try (BufferedInputStream in = new BufferedInputStream(new FileInputStream(file))) {
sResult = readFileContent(in);
} catch (IllegalArgumentException e) {
LOGGER.debug("[{}] EogvFileUtil : {}", e.getClass().getName(), e.getMessage());
} finally {
in.close();
}

return sResult;
}

/**
* String 형으로 파일의 내용을 읽는다.
* String 형으로 스트림 전체를 읽어 플랫폼 기본 문자셋으로 디코딩한다.
*/
public static String readFileContent(InputStream in) throws IOException {
StringBuilder buf = new StringBuilder();
for (int i = in.read(); i != -1; i = in.read()) {
buf.append((char) i);
}
return buf.toString();
return new String(in.readAllBytes(), Charset.defaultCharset());
}

/**
* String 영으로 파일의 내용을 읽는다.
* String 형으로 파일 전체를 읽어 지정한 인코딩으로 디코딩한다. 원본의 개행은 그대로 보존된다.
* encoding이 null이면 플랫폼 기본 문자셋을 사용한다.
*/
public static String readFile(File file, String encoding) throws IOException {
StringBuilder sb = new StringBuilder();
List<String> lines = readTextLines(file, encoding);

for (Iterator<String> it = lines.iterator(); it.hasNext(); ) {
sb.append(it.next());
Charset charset = encoding == null ? Charset.defaultCharset() : Charset.forName(encoding);
try (InputStream in = new FileInputStream(file)) {
return new String(in.readAllBytes(), charset);
}

return sb.toString();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@

import java.io.*;
import java.net.URL;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.Iterator;
import java.util.List;

Expand Down Expand Up @@ -235,13 +237,126 @@ public void testReadEmptyFile() throws IOException {
}

/**
* 여러 줄 파일 읽기 테스트. 줄들이 종전과 동일하게 연결되어야 한다.
* 여러 줄 파일 읽기 테스트. 원본의 개행이 보존되어야 한다.
*/
@Test
public void testReadMultiLineFile() throws IOException {
public void testReadMultiLineFilePreservesLineSeparator() throws IOException {
String multiPath = tmppath + "/multiline.txt";
EgovFileUtil.writeFile(multiPath, "line1\nline2\nline3", "UTF-8");
assertEquals("line1line2line3", EgovFileUtil.readFile(new File(multiPath), "UTF-8"));
assertEquals("line1\nline2\nline3", EgovFileUtil.readFile(new File(multiPath), "UTF-8"));
}

/**
* 파일 읽기 테스트. 플랫폼 기본 문자셋으로 쓴 한글은 그대로 읽혀야 한다.
*/
@Test
public void testReadFileKoreanWithDefaultCharset() throws IOException {
File file = new File(EgovFileUtil.getTmpDirectory() + "/read-default-korean.txt");
String content = "행정안전부 표준프레임워크";

try {
Files.write(file.toPath(), content.getBytes(Charset.defaultCharset()));

assertEquals(content, EgovFileUtil.readFile(file));
} finally {
if (file.exists()) {
EgovFileUtil.delete(file);
}
}
}

/**
* 빈 파일 읽기 테스트. 내용이 없는 파일은 두 오버로드 모두 빈 문자열을 반환해야 한다.
*/
@Test
public void testReadEmptyFileWithDefaultCharsetAndEncoding() throws IOException {
File file = new File(EgovFileUtil.getTmpDirectory() + "/read-empty.txt");

try {
Files.write(file.toPath(), new byte[0]);

assertEquals("", EgovFileUtil.readFile(file));
assertEquals("", EgovFileUtil.readFile(file, "UTF-8"));
} finally {
if (file.exists()) {
EgovFileUtil.delete(file);
}
}
}

/**
* 파일 읽기 테스트. 지정 인코딩으로 읽을 때 LF 개행은 보존되어야 한다.
*/
@Test
public void testReadFileWithEncodingPreservesLf() throws IOException {
File file = new File(EgovFileUtil.getTmpDirectory() + "/read-utf8-lf.txt");
String content = "첫째 줄\n둘째 줄\n셋째 줄\n";

try {
Files.write(file.toPath(), content.getBytes(StandardCharsets.UTF_8));

assertEquals(content, EgovFileUtil.readFile(file, "UTF-8"));
} finally {
if (file.exists()) {
EgovFileUtil.delete(file);
}
}
}

/**
* 파일 읽기 테스트. 지정 인코딩으로 읽을 때 CRLF 개행은 보존되어야 한다.
*/
@Test
public void testReadFileWithEncodingPreservesCrLf() throws IOException {
File file = new File(EgovFileUtil.getTmpDirectory() + "/read-utf8-crlf.txt");
String content = "a\r\nb\r\n";

try {
Files.write(file.toPath(), content.getBytes(StandardCharsets.UTF_8));

assertEquals(content, EgovFileUtil.readFile(file, "UTF-8"));
} finally {
if (file.exists()) {
EgovFileUtil.delete(file);
}
}
}

/**
* 파일 읽기 테스트. EUC-KR로 쓴 파일은 지정 인코딩으로 그대로 읽혀야 한다.
*/
@Test
public void testReadFileWithEucKrEncoding() throws IOException {
File file = new File(EgovFileUtil.getTmpDirectory() + "/read-euc-kr.txt");
String content = "한글\nEUC-KR\n";

try {
Files.write(file.toPath(), content.getBytes(Charset.forName("EUC-KR")));

assertEquals(content, EgovFileUtil.readFile(file, "EUC-KR"));
} finally {
if (file.exists()) {
EgovFileUtil.delete(file);
}
}
}

/**
* 파일 읽기 테스트. 잘못된 UTF-8 바이트 시퀀스는 종전과 같이 대체 문자로 처리되어야 한다.
*/
@Test
public void testReadFileWithInvalidUtf8BytesReplacesMalformedInput() throws IOException {
File file = new File(EgovFileUtil.getTmpDirectory() + "/read-invalid-utf8.txt");

try {
Files.write(file.toPath(), new byte[]{(byte) 0xC3, (byte) 0x28});

assertEquals("�(", EgovFileUtil.readFile(file, "UTF-8"));
} finally {
if (file.exists()) {
EgovFileUtil.delete(file);
}
}
}

/**
Expand Down