본문 바로가기

나머지

BufferedInputStream 로 받은 파일이 사이즈가 더 클 경우

반응형

간만에 쌩짜로 짜려니 역시 낯설다.


파일을 받을 일이 있어서 url 을 가지고 input stream 을 얻어서 파일에 write 를 했는데 계속 파일이 깨지는거다. (이미지 파일인데 이미지 파일이 깨져서 보임)


몇 번을 테스트 해 봐도 결과가 마찬가지이고 이상하게 공통적으로 다운로드 받은 파일이 원본보다 사이즈가 큰 것을 확인 할 수 있었다.


문제가 있던 코드는 아래와 같다.

bis = new BufferedInputStream(someStream);
fos = new FileOutputStream(someFile);

byte[] bytes = new byte[1024];
while(bis.read(bytes) !=-1) {
fos.write(bytes);
}

fos.flush();

생가하기엔 아주 간단했다.


inputstream 에서 1024 byte를 읽어와서 읽은 만큼 output 에 쓴다.


근데 이상하게 정상 동작하지 않고 파일 사이즈가 더 커져서 저장이 된다.

뭔가 기대했던 것과는 다르게 읽은 만큼 쓰지 않고 더 쓰는거 같다. 그래서 확인차 하나씩 읽어 보기로 하고 아래와 같이 테스트를 해 봤더니...

is = new SomeInputStream();
fos = new FileOutputStream(someFile);

int readByte;
while((readByte=is.read())!=-1) {
fos.write(readByte);
}

fos.flush();

이건 정상적으로 동작을 한다.


버퍼를 이용해서 쓰는게 문제인걸로 보여서 뒤져보니

실제로 버퍼가 다 차지 전에( 파일 다운로드니까.. 외부에서 바이트를 읽어 올 때 ) 버퍼를 읽어서 값을 가져 오는걸 시도하는데 실제 버퍼가 다 안 찼기 때문에 그냥 빈(아마도 0?) 데이터를 채워서 읽어 오는게 문제로 확인 된다.


그래서 아래와 같이 버퍼를 읽은 만큼 쓰는걸로 변경해야 한다.

int readByteSize;
byte[] readBytes = new byte[1024];

while((readByteSize=is.read(readBytes))!=-1) {
fos.write(readBytes, 0, readByteSize);
}

fos.flush();


까먹고 다시 삽질하고 까먹고 다시 삽질하고... 힘들다.ㅋ


그냥 IOUtils 나 어차피 다운로드도 httpclient 라이브러리를 쓸 거기 때문에 HttpEntity 에 writeTo 메소드를 사용하는게 역시 답인거 같기도 하다.

반응형