others
버퍼와 스트림에 대해서

버퍼와 스트림
버퍼는 데이터를 메모리에 임시로 저장하는 공간을 의미한다
스트림을 버퍼에 저장된 데이터를 사용하는 방식을 의미한다 ( 지속적으로 전달하는 방식 )
버퍼
버퍼는 동영상등의 데이터가 프로그래밍으로 핸들링 될수있도록 메모리에 저장하는것이다
100mb의 동영상을 재생하는 경우 버퍼만 사용한다면 아래와 같은 일이 발생한다
- 100mb의 메모리를 사용할 경우 서버에 항상 100MB의 메모리를 차지한다 (메모리를 많이 사용함)
스트림
스트림은 데이터를 작은 청크(버퍼)로 나누어 보낸다 (예: 1MB씩 100번)
100mb의 동영상을 재생하는 경우 버퍼만 사용한다면 아래와 같은 일이 발생한다
- 100mb의 메모리를 사용할 경우 서버에 항상 1MB의 메모리를 차지한다 (메모리 절약)
스트림을 사용하는 이유
스트림 방식은 데이터를 작은 단위로 나누어 전송함으로써 메모리 사용량을 줄이는 데 있다.
반면, 버퍼 방식은 파일 전체를 메모리에 로드하여 처리한다는 점에서 큰 파일의 경우 메모리를 많이 사용하게 된다.
버퍼를 사용한 예제
@app.route('/buffer')
def buffer_example():
buffer = io.BytesIO()
with open('example.txt', 'rb') as f:
buffer.write(f.read()) # 해당 부분에서 파일을 읽어서 버퍼로 저장함 ( 반환값 : 버퍼 )
# 버퍼의 포인터를 시작 위치로 이동
buffer.seek(0)
return send_file(buffer, as_attachment=True, download_name='example.txt') # 버퍼로 저장한 파일을 클라이언트에 전송
if __name__ == '__main__':
app.run(debug=True)
스트림을 사용한 예제
def generate():
with open('example.txt', 'rb') as f: # 파일을 메모리 내의 버퍼로 읽기
while True:
chunk = f.read(1024) # 해당 부분에서 파일을 읽어서 버퍼로 저장함 ( 반환값 : 버퍼 1024바이트 )
# 청크 = 버퍼
if not chunk:
break
yield chunk
@app.route('/stream')
def stream_example():
return Response(generate(), mimetype='text/plain')
generate 함수는 파일의 내용을 작은 조각(chunk)으로 읽어서 클라이언트에게 점진적으로 전달합니다
( 즉 버퍼파일을 스트리밍방식으로 데이터를 클라이언트에 전달한다는 의미 )
버퍼링과 스트리밍의 차이
미리 여유있게 데이터를 받아놓는다 → 버퍼링
데이터를 받자마자 재생시킨다 → 스트리밍
( 둘다 버퍼라는 저장공간을 사용하며 일시적으로 저장하는 데이터의 크기에 따라 버퍼링과 스트리밍으로 나뉜다 )
( 버퍼공간을 크게해서 데이터를 미리 많이 저장해둔다 : 버퍼링 )
( 버퍼공간을 작게해서 데이터를 바로바로 쓴다 : 스트리밍 )
버퍼링
-
특징:
- 초기 일정량의 데이터를 서버에서 받아서 버퍼에 저장 후 재생을 시작합니다.
- 예를 들어, 100MB 파일을 받을 때 초기에 10MB를 받아 버퍼에 저장한 후 동영상을 재생합니다. 이후 1MB씩 받아가며 버퍼를 채우고 재생을 완료합니다.
- 초기 재생 시간이 약간 늦어질 수 있습니다.
- 어느 정도 데이터를 미리 받아놓기 때문에 네트워크가 일시적으로 불안해도 영상이 끊기지 않습니다.
스트리밍
-
특징:
- 데이터를 받자마자 바로 재생을 시작합니다.
- 예를 들어, 100MB 파일을 받을 때 서버에서 1MB를 받아 버퍼에 저장한 후 바로 동영상을 재생합니다. 이후 1MB씩 받아가며 계속 재생합니다.
- 초기 재생 시간이 빠릅니다.
- 네트워크가 불안정하면 받아놓은 데이터가 적기 때문에 영상이 끊길 수 있습니다.
한줄정리
버퍼는 공간
스트림은 방식
참조