일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 안드로이드 유닛 테스트
- 2022 플러터 설치
- 서비스 쓰레드 차이
- 안드로이드 os 구조
- 안드로이드 유닛 테스트 예시
- 자바 다형성
- android retrofit login
- rxjava cold observable
- jvm이란
- rxjava disposable
- 서비스 vs 쓰레드
- android ar 개발
- 안드로이드 유닛테스트란
- 안드로이드 라이선스 종류
- 플러터 설치 2022
- rxjava hot observable
- 멤버변수
- 안드로이드 레트로핏 사용법
- 안드로이드 라이선스
- ANR이란
- 2022 플러터 안드로이드 스튜디오
- 스택 자바 코드
- 스택 큐 차이
- 클래스
- Rxjava Observable
- 객체
- 안드로이드 레트로핏 crud
- ar vr 차이
- jvm 작동 원리
- 큐 자바 코드
- Today
- Total
나만을 위한 블로그
[JAVA] 버퍼란? BufferedReader/Writer란? + 예제 본문
딱 봤을 때 Bufferd와 reader, writer를 합친 단어같다. 그럼 프로그래밍에서 Buffer(버퍼)의 뜻이 뭔지부터 알아야 할 것 같다.
버퍼의 사전적 정의는 아래와 같다.
buffer : 완충제, 완충 장치, 완화하다
완충제 : 일반적으로 급격한 외부 변화를 완화시키는 작용을 하는 물질
일상생활에서 완충제는 충격을 완화하는 물건이란 뜻이 있다고 알고 있다. 이게 프로그래밍에선 무슨 의미로 사용될까?
위키백과에선 버퍼를 아래와 같이 정의하고 있다.
https://ko.wikipedia.org/wiki/%EB%B2%84%ED%8D%BC_(%EC%BB%B4%ED%93%A8%ED%84%B0_%EA%B3%BC%ED%95%99)
버퍼는 데이터를 한 곳에서 다른 한 곳으로 전송하는 동안 일시적으로 그 데이터를 보관하는 메모리의 영역이다. 버퍼링(Buffering)이란 버퍼를 활용하는 방식 또는 버퍼를 채우는 동작을 말한다. 다른 말로 큐(Queue)라고도 표현한다.
버퍼는 컴퓨터 안의 프로세스 사이에서 데이터를 이동시킬 때 사용된다. 보통 데이터는 키보드와 같은 입력 장치로부터 받거나 프린터와 같은 출력 장치로 내보낼 때 버퍼 안에 저장된다. 이는 전자 통신의 버퍼와 비유할 수 있다. 버퍼는 하드웨어나 소프트웨어에 추가될 수 있지만 버퍼는 상당수가 소프트웨어에 추가된다. 버퍼는 보통 속도가 계속 바뀔 수 있으므로 데이터 수신, 처리 속도에 차이가 있다...(중략)
버퍼는 데이터 전송 시 사용되고, 데이터를 어디에 잠깐 보관하는 메모리 영역이란 것 같다. 영문 위키백과에선 버퍼를 롤러코스터에 비유하고 있다.
https://en.wikipedia.org/wiki/Data_buffer
롤러코스터 줄은 많은 유사점을 공유한다. 롤러코스터를 타는 사람들은 알려지지 않고 종종 가변적인 속도로 들어오지만 롤러코스터는 사람들을 순식간에 태울 수 있다. 대기줄 영역은 승차를 원하는 사람들이 승차가 가능할 때까지 기다리는 임시 공간인 완충제 역할을 한다
데이터를 담아서 한 번에 전달하는 놈이란 건 알겠다. 그런데 버퍼를 왜 써야 할까?
https://stackoverflow.com/questions/22436289/when-to-use-buffer-and-what-for
버퍼 I/O가 없으면 각 읽기 또는 쓰기 요청이 기본 OS에서 직접 처리됨을 의미한다. 이건 각각의 그러한 요청이 종종 디스크 액세스, 네트워크 활동 또는 상대적으로 비용이 많이 드는 기타 작업을 트리거하기 때문에 프로그램을 훨씬 덜 효율적으로 만들 수 있다. 이런 종류의 오버헤드를 줄이기 위해 자바 플랫폼은 버퍼링된 I/O 스트림을 구현한다. 버퍼링된 입력 스트림은 버퍼로 알려진 메모리 영역에서 데이터를 읽는다.
버퍼를 사용하지 않으면 특정 경우에서 프로그램이 덜 효율적으로 작동한다고 한다. 버퍼의 특징과 상관있는 말일까?
버퍼는 어떤 특징을 갖고 있는지 확인해봤다.
https://whatis.techtarget.com/definition/buffer
버퍼는 다른 속도로 또는 다른 우선순위 세트로 작동하는 하드웨어 장치 또는 프로그램 프로세스가 공유하는 데이터 영역이다. 버퍼를 쓰면 각 장치 또는 프로세스가 다른 장치에 의해 유지되지 않고 작동할 수 있다. 버퍼가 효과적이려면 버퍼 크기와 버퍼 안팎으로 데이터를 이동하는 알고리즘을 버퍼 설계자가 고려해야 한다.
캐시와 마찬가지로 버퍼는 "중간 지점 유지 장소"지만 개별 활동의 조정을 지원하기보다 활동의 속도를 가속화하기 위해 존재한다. 이 용어는 프로그래밍과 하드웨어 모두에서 사용된다
https://tcpschool.com/cpp/cpp_io_streamBuffer
버퍼를 써서 얻을 수 있는 장점은 2개다.
1. 문자를 묶어서 한 번에 전달하므로 전송시간이 적게 걸려 성능이 향상된다
2. 사용자가 문자를 잘못 입력했을 경우 수정할 수 있다.
하지만 입력 작업에 버퍼를 쓰는 게 반드시 좋은 건 아니다. 빠른 반응이 요구되는 게임 등 프로그램에선 키를 누르는 즉시 전달돼야 한다.
https://stackoverflow.com/questions/648309/what-does-it-mean-by-buffer
입력 속도와 출력 속도의 차이를 줄이기 위해 임시로 뭔가를 저장하는 곳이다. 생산자가 소비자보다 빠르지만 생산자는 출력을 버퍼에 계속 저장할 수 있다. 소비자가 접근하면 버퍼에서 읽을 수 있다. 버퍼는 중간에 간격을 메우기 위해 있다.
흙더미를 삽으로 퍼서 옮길 때 한 번씩 삽에 흙을 담고 옮기는 것보다 자루 같은 것에 담아서 옮기는 편이 작업 시간이 좀 더 단축된다. 여기서 자루가 버퍼의 역할을 하는 것 같다.
그럼 자바에서 버퍼는 어떻게 사용할 수 있는가? 제목에 적은 대로 자바에선 BufferedWriter와 BufferedReader라는 클래스를 제공한다.
https://docs.oracle.com/javase/7/docs/api/java/io/BufferedReader.html
문자 입력 스트림에서 텍스트를 읽고 문자, 배열, 행(lines)을 효율적으로 읽을 수 있게 문자를 버퍼링한다. 버퍼 크기를 지정하거나 기본 크기를 사용할 수 있다. 기본값은 대부분의 목적에 충분히 크다. 일반적으로 Reader의 각 읽기 요청은 기본 문자 또는 바이트 스트림에 대한 해당 읽기 요청을 발생시킨다. 따라서 FileReader 및 InputStreamReader와 같이 read() 작업에 비용이 많이 들 수 있는 Reader 주위에 BufferedReader를 아래처럼 래핑하는 게 좋다.
BufferedReader in = new BufferedReader(new FileReader("foo.in"))
이 코드는 지정된 파일의 입력을 버퍼링한다. 버퍼링이 없으면 read() 또는 readLine()을 호출할 때마다 파일에서 바이트를 읽고 문자로 변환한 다음 반환할 수 있으므로 매우 비효율적일 수 있다. 텍스트 입력에 DataInputStream을 쓰는 프로그램은 각 DataInputStream을 적절한 BufferedReader로 교체해 지역화할 수 있다.
https://docs.oracle.com/javase/7/docs/api/java/io/BufferedWriter.html
단일 문자, 배열, 문자열을 효율적으로 쓸 수 있도록 문자를 버퍼링해서 문자 출력 스트림에 텍스트를 쓴다. 버퍼 크기를 지정하거나 기본 크기를 쓸 수 있다. 기본값은 대부분의 목적에 충분히 크다. 시스템 속성 line.separator에 정의된 대로 플랫폼 고유의 줄 구분자 개념을 사용하는 newLine()이 제공된다. 모든 플랫폼이 줄 바꿈 문자(\n)를 써서 줄을 종료하는 건 아니다. 따라서 이 메서드를 호출해서 각 출력 라인을 종료하는 게 개행 문자를 직접 작성하는 것보다 선호된다. 일반적으로 Writer는 출력을 기본 문자 또는 바이트 스트림으로 즉시 내보낸다. 프롬프트 출력이 필요한 경우가 아니면 FileWriter 및 OutputStreamWriter와 같이 write() 작업에 비용이 많이 들 수 있는 모든 Writer 주위에 BufferedWriter를 아래처럼 래핑하는 것이 좋다.
PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("foo.out")))
PrintWriter의 출력을 파일로 버퍼링한다. 버퍼링이 없으면 print()를 호출할 때마다 문자가 바이트로 변환되어 파일에 즉시 기록되므로 매우 비효율적일 수 있다.
BufferedWriter의 간단한 예제는 아래와 같다. 바탕화면에 txt 파일을 만들고 그 안에 특정 문자열을 입력한 후 저장하는 예제다.
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
public class WriteFile
{
public static void main(String[] args)
{
BufferedWriter bw = null;
try
{
String content = "이 내용을 메모장 파일에 입력할 것";
File file = new File("C:\\Users\\Desktop\\임시파일.txt");
FileWriter fw = new FileWriter(file);
bw = new BufferedWriter(fw);
bw.write(content);
System.out.println("!!! 파일 작성이 완료됨");
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
try
{
if (bw != null)
{
bw.close();
}
}
catch (IOException e)
{
System.out.println("BufferedWriter를 종료할 때 에러 발생 : " + e);
}
}
}
}
바탕화면의 절대경로와 파일명.txt를 적어두고 이 코드를 실행하면 바탕화면에 메모장이 만들어지고 content 변수 안의 문자열들이 입력되어 있는 걸 볼 수 있다.
BufferedReader는 아래와 같이 사용할 수 있다.
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class ReadFile
{
public static void main(String[] args)
{
BufferedReader br = null;
BufferedReader br2 = null;
try
{
br = new BufferedReader(new FileReader("C:\\Users\\Desktop\\임시파일.txt"));
System.out.println("readLine() 써서 파일 내용 읽어오는 중...");
String contentLine = br.readLine();
while (contentLine != null)
{
System.out.println("contentLine : " + contentLine);
contentLine = br.readLine();
}
br2 = new BufferedReader(new FileReader("C:\\Users\\Desktop\\임시파일.txt"));
System.out.println("read() 써서 파일 내용 읽어오는 중...");
int num = 0;
char ch;
while ((num = br2.read()) != -1)
{
ch = (char) num;
System.out.println("ch : " + ch);
}
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
try
{
if (br != null)
{
br.close();
}
if (br2 != null)
{
br2.close();
}
}
catch (IOException e)
{
System.out.println("BufferedReader 종료 중 에러 발생");
}
}
}
}
위에서 만들어진 파일을 readLine()과 read()로 읽어와서 출력하는 예제다.
이걸 실행하면 아래와 같이 나온다.
readLine()의 경우 한 줄 통째로 읽어와서 보여주는 걸 볼 수 있고, read()의 경우 스페이스 바를 포함해서 한 글자씩 읽어와 출력하는 걸 볼 수 있다.
'JAVA' 카테고리의 다른 글
[JAVA] enum(열거형)이란? (0) | 2021.12.04 |
---|---|
[JAVA] JVM의 작동원리 (0) | 2021.10.08 |
[JAVA] SOLID 원칙이란? - 2 - (0) | 2021.07.24 |
[JAVA] Stream API란? (0) | 2021.07.20 |
[JAVA] SOLID 원칙이란? - 1 - (0) | 2021.07.19 |