기술지원 문의

ServletOutputStream 을 이용한 다운로드시 화일깨짐현상
박창민 / 2003-01-23 00:00

말씀하신대로 outputstream 을 이용해서도 해보고
Vfs 를 이용해서도 해 보았지만 문제를 아직 해결 하지 못 했습니다.
제대로 되는 특별한 세팅과 환경을 알려주시면 고맙겠습니다.
그리고 제대로 돌아가는 다운로드하는 소스를 첨부해 주시면 감사하겠습
니다.
=================================
안녕하세요 
말씀하신 것을 서블릿으로 비슷하게 만들어서 
테스트해보았는데 정말 그러했습니다. 

그래서 ServletOutputStream를 사용하지 않고 
OutputStream를 이용해서 브라우저를 보내니 
정상적으로 작동하였습니다. 

ServletOutputStream이 OutputStream를 확장한 것이고 
ServletOutputStream중에는 write 메소드를 제공하지 않고 
OutputStream의 write를 상속해서 사용하는 것이라. 
어차피 그게 그것이란 얘긴데... 내부 메카니즘은 좀 연구를 
해보아야 될 것 같습니다. 

보통 파일 다운로드시 resin의 Vfs를 이용하는 것이 편리하고 
좋습니다. 

import=\"com.caucho.vfs.*\" 

OutputStream os = response.getOutputStream(); 
ReadStream Vfsrs = Vfs.openRead(pathname); 
Vfsrs.writeToStream(os) 

와 같은 형태이죠, 아주 빠르고 안정적입니다. 

--박창민 님의 글 [2003-01-20 17:59:44] 
>며칠전 답변은 감사합니다. 하지만 재 질문에 답변이 없어서 
이렇게 다시 글을 올립니다. 
response.setContentLength(파일사이즈) 
이구문을 사용하면 txt 류의 화일은 안 깨지는데 
zip 화일로 하면 내용이 깨집니다. 헤더가 잘 못 되었다면서요. 
그래서 그 구문을 빼고 하면 zip 화일 안에 doc,ppt 등의 문서가 있으면 
제대로 출력이 됩니다. 
하지만 doc,ppt 등으로 업로드하고 다운로드 받으면 내용이 깨지네요. 

지금 저의 설정은 win2000,apache2,resin2.1.6 srun loadbalencing이며 입니다. 
관리자님께서 이러한 것을 사용해보신적이 있고 성공하셨다면 성공하신 
환경과 다운로드 받는 부분만 전체소스를 보여주시면 안될까요... 
한계에 달해서 부탁드립니다. 그럼 감사합니다. 
톰켓같은곳에서는 아무 문제가 없었던 부분입니다. 제생각에는 
resin 에서는 한글처리를 따로 해주지 않아도 되는 차이땜에 이러한 
현상이 나타나는게 아닌가 생각되는데요.. 
좀 더 명확한 답변을 주시면 감사하겠습니다. 

--관리자 님의 글 [2003-01-16 16:57:56] 
>response로 출력하기전에 필요한 헤더를 설정하셨나요? 

예를 들면 
response.setContentType(\"application/octet-stream\") 
response.setContentLength(파일사이즈) 
response.setHeader(\"Content-Disposition\", \"filename=\" + 파일이름 + \";\") 
response.setHeader(\"Pragma\", \"no-cache\") 
response.setHeader(\"Connection\", \"close\") 
등등 파일 다운로드시 필요한 몇가지 헤더를 먼저 설정하시고 
다시 테스트해보세요. 


--박창민 님의 글 [2003-01-15 17:38:31] 
>os:win2000 server 
resin : 2.1.6 
apache : 2x 

웹루트디렉토리와는 별도로 업로드 디렉토리를 만들고 
다운로드시에 File을 이용해서 읽어와서 
if (file.isFile()) 

FileInputStream fin = null; 

fin = new FileInputStream(file); 

ServletOutputStream outputStream = response.getOutputStream(); 

int read = 0; 

while ((read = fin.read(b)) != -1) 

outputStream.write(b, 0, read); 


outputStream.close(); 

fin.close(); 


이런 형태로 화일을 다운로드 받게 합니다. 
그런데 원본화일은 멀쩡한데도 불구하고 다운로드 받은 화일은 깨져 있습니다. 
전에 tomcat 같은 환경에서도 무난히 잘 되던건데 이상하네요.. 
resin 에서의 설정 문제 인가요? 
이거 땜에 무지 고생하고 있습니다. 제발 빠른 답변 부탁합니다. 
전에도 resin 에서 이러한 문제가 있어서 별도도 다른 서버를 돌린적이 있는데 운영체제나 버젼문제는 아닌거 같습니다.리눅스에서도 안되었거든요. 
참고적으로 화일을 못찾는 문제는 아닙니다. 다 깨지는 건 아니고 
doc 같은 문서화일이 깨집니다. 내용이 깨지는 걸로 봐서는 character 문제인거 같기도 하고 그거땜에 헤더가 깨지는 거 같기도 한데 zip 같은건 또 안깨지는거 같더라구요. 

Re:ServletOutputStream 을 이용한 다운로드시 화일깨짐현상
관리자 / 2003-01-27 00:00

제가 테스트시 사용했던 소스입니다.

제 환경은 
OS : Redhat 8.0
JDK : 1.4.1_01
resin : 2.1.6
$RESIN_HOME/doc를 documentRoot로 사용하고
그 밑에 upload/data디렉토리를 생성한 후
여러가지 파일들을 data디렉토리에 올려 테스트했었습니다.
정확하게 잘 수행되면 아주 빠르고 안정적이었습니다.

파일을 넘겨주는 쪽을 조금 수정하면 편하게 테스트할 수 
있겠습니다만. 귀찮으시면
http://localhost/upload/dn.jsp?fname=테스트.xsl 와 같은
형식으로 테스트해보실 수 있겠습니다.

dn.jsp
-------------------------------------------------------
<%@ page language=\"java\" contentType=\"application;\" %>
<%@ page import=\"java.util.*,java.io.*,java.text.*\" %>
<%@ page import=\"java.sql.*, javax.sql.*, javax.naming.*\" %>
<%@ page import=\"com.caucho.vfs.*\" %>

<%
String upLoadDataPath = \"upload/data/\";
String upLoadRealPath = request.getRealPath(\"/\")+upLoadDataPath;
String fname = request.getParameter(\"fname\");
String encfname = new String(request.getParameter(\"fname\").getBytes(\"8859_1\"), \"euc-kr\");
String pname = upLoadRealPath+encfname;
File file = new File(pname);

response.reset();
response.setContentType(\"application/octet-stream\");
response.setContentLength((int)file.length());
response.setHeader(\"Content-Disposition\",\"attachment; filename=\\\"\"+ fname + \"\\\"\");
response.setHeader(\"Pragma\", \"no-cache\");
response.flushBuffer();

OutputStream os = response.getOutputStream();
ReadStream Vfsrs = Vfs.openRead(pname);
Vfsrs.writeToStream(os);
Vfsrs.close();
os.close();

%>
-------------------------------------------------------

--박창민 님의 글 [2003-01-23 15:40:40]
>말씀하신대로 outputstream 을 이용해서도 해보고
Vfs 를 이용해서도 해 보았지만 문제를 아직 해결 하지 못 했습니다.
제대로 되는 특별한 세팅과 환경을 알려주시면 고맙겠습니다.
그리고 제대로 돌아가는 다운로드하는 소스를 첨부해 주시면 감사하겠습
니다.
=================================
안녕하세요 
말씀하신 것을 서블릿으로 비슷하게 만들어서 
테스트해보았는데 정말 그러했습니다. 

그래서 ServletOutputStream를 사용하지 않고 
OutputStream를 이용해서 브라우저를 보내니 
정상적으로 작동하였습니다. 

ServletOutputStream이 OutputStream를 확장한 것이고 
ServletOutputStream중에는 write 메소드를 제공하지 않고 
OutputStream의 write를 상속해서 사용하는 것이라. 
어차피 그게 그것이란 얘긴데... 내부 메카니즘은 좀 연구를 
해보아야 될 것 같습니다. 

보통 파일 다운로드시 resin의 Vfs를 이용하는 것이 편리하고 
좋습니다. 

import=\"com.caucho.vfs.*\" 

OutputStream os = response.getOutputStream(); 
ReadStream Vfsrs = Vfs.openRead(pathname); 
Vfsrs.writeToStream(os) 

와 같은 형태이죠, 아주 빠르고 안정적입니다. 

--박창민 님의 글 [2003-01-20 17:59:44] 
>며칠전 답변은 감사합니다. 하지만 재 질문에 답변이 없어서 
이렇게 다시 글을 올립니다. 
response.setContentLength(파일사이즈) 
이구문을 사용하면 txt 류의 화일은 안 깨지는데 
zip 화일로 하면 내용이 깨집니다. 헤더가 잘 못 되었다면서요. 
그래서 그 구문을 빼고 하면 zip 화일 안에 doc,ppt 등의 문서가 있으면 
제대로 출력이 됩니다. 
하지만 doc,ppt 등으로 업로드하고 다운로드 받으면 내용이 깨지네요. 

지금 저의 설정은 win2000,apache2,resin2.1.6 srun loadbalencing이며 입니다. 
관리자님께서 이러한 것을 사용해보신적이 있고 성공하셨다면 성공하신 
환경과 다운로드 받는 부분만 전체소스를 보여주시면 안될까요... 
한계에 달해서 부탁드립니다. 그럼 감사합니다. 
톰켓같은곳에서는 아무 문제가 없었던 부분입니다. 제생각에는 
resin 에서는 한글처리를 따로 해주지 않아도 되는 차이땜에 이러한 
현상이 나타나는게 아닌가 생각되는데요.. 
좀 더 명확한 답변을 주시면 감사하겠습니다. 

--관리자 님의 글 [2003-01-16 16:57:56] 
>response로 출력하기전에 필요한 헤더를 설정하셨나요? 

예를 들면 
response.setContentType(\"application/octet-stream\") 
response.setContentLength(파일사이즈) 
response.setHeader(\"Content-Disposition\", \"filename=\" + 파일이름 + \";\") 
response.setHeader(\"Pragma\", \"no-cache\") 
response.setHeader(\"Connection\", \"close\") 
등등 파일 다운로드시 필요한 몇가지 헤더를 먼저 설정하시고 
다시 테스트해보세요. 


--박창민 님의 글 [2003-01-15 17:38:31] 
>os:win2000 server 
resin : 2.1.6 
apache : 2x 

웹루트디렉토리와는 별도로 업로드 디렉토리를 만들고 
다운로드시에 File을 이용해서 읽어와서 
if (file.isFile()) 

FileInputStream fin = null; 

fin = new FileInputStream(file); 

ServletOutputStream outputStream = response.getOutputStream(); 

int read = 0; 

while ((read = fin.read(b)) != -1) 

outputStream.write(b, 0, read); 


outputStream.close(); 

fin.close(); 


이런 형태로 화일을 다운로드 받게 합니다. 
그런데 원본화일은 멀쩡한데도 불구하고 다운로드 받은 화일은 깨져 있습니다. 
전에 tomcat 같은 환경에서도 무난히 잘 되던건데 이상하네요.. 
resin 에서의 설정 문제 인가요? 
이거 땜에 무지 고생하고 있습니다. 제발 빠른 답변 부탁합니다. 
전에도 resin 에서 이러한 문제가 있어서 별도도 다른 서버를 돌린적이 있는데 운영체제나 버젼문제는 아닌거 같습니다.리눅스에서도 안되었거든요. 
참고적으로 화일을 못찾는 문제는 아닙니다. 다 깨지는 건 아니고 
doc 같은 문서화일이 깨집니다. 내용이 깨지는 걸로 봐서는 character 문제인거 같기도 하고 그거땜에 헤더가 깨지는 거 같기도 한데 zip 같은건 또 안깨지는거 같더라구요.