왜 내 이미지가 왜곡되어 나오나요?
-
09-06-2019 - |
문제
서블릿과 Apache Commons FileUpload를 사용하여 파일을 설정된 디렉토리에 업로드하는 Java 코드가 있습니다.문자 데이터(예:텍스트 파일)인데 이미지 파일이 깨져서 나옵니다.열 수는 있지만 이미지가 열리지 않는 것 같습니다.내 코드는 다음과 같습니다.
서블릿
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
try {
String customerPath = "\\leetest\\";
// Check that we have a file upload request
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
if (isMultipart) {
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload();
// Parse the request
FileItemIterator iter = upload.getItemIterator(request);
while (iter.hasNext()) {
FileItemStream item = iter.next();
String name = item.getFieldName();
if (item.isFormField()) {
// Form field. Ignore for now
} else {
BufferedInputStream stream = new BufferedInputStream(item
.openStream());
if (stream == null) {
LOGGER
.error("Something went wrong with fetching the stream for field "
+ name);
}
byte[] bytes = StreamUtils.getBytes(stream);
FileManager.createFile(customerPath, item.getName(), bytes);
stream.close();
}
}
}
} catch (Exception e) {
throw new UploadException("An error occured during upload: "
+ e.getMessage());
}
}
StreamUtils.getBytes(stream)은 다음과 같습니다:
public static byte[] getBytes(InputStream src, int buffsize)
throws IOException {
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
byte[] buff = new byte[buffsize];
while (true) {
int nBytesRead = src.read(buff);
if (nBytesRead < 0) {
break;
}
byteStream.write(buff);
}
byte[] result = byteStream.toByteArray();
byteStream.close();
return result;
}
마지막으로 FileManager.createFile은 다음과 같습니다.
public static void createFile(String customerPath, String filename,
byte[] fileData) throws IOException {
customerPath = getFullPath(customerPath + filename);
File newFile = new File(customerPath);
if (!newFile.getParentFile().exists()) {
newFile.getParentFile().mkdirs();
}
FileOutputStream outputStream = new FileOutputStream(newFile);
outputStream.write(fileData);
outputStream.close();
}
내가 뭘 잘못하고 있는지 알아낼 수 있는 사람이 있나요?
건배, 리
해결책
내가 좋아하지 않는 한 가지는 StreamUtils.getBytes()의 이 블록에 있습니다.
1 while (true) {
2 int nBytesRead = src.read(buff);
3 if (nBytesRead < 0) {
4 break;
5 }
6 byteStream.write(buff);
7 }
6번째 줄에서는 읽은 바이트 수에 관계없이 전체 버퍼를 씁니다.나는 이것이 항상 그럴 것이라고 확신하지 않습니다.다음과 같이 하는 것이 더 정확할 것입니다.
1 while (true) {
2 int nBytesRead = src.read(buff);
3 if (nBytesRead < 0) {
4 break;
5 } else {
6 byteStream.write(buff, 0, nBytesRead);
7 }
8 }
5행의 'else'와 6행의 두 추가 매개변수(배열 인덱스 시작 위치 및 복사할 길이)에 유의하세요.
이미지와 같은 더 큰 파일의 경우 버퍼가 채워지기 전에 버퍼가 반환된다는 것을 상상할 수 있습니다(어쩌면 더 많은 것을 기다리고 있을 수도 있습니다).즉, 버퍼의 끝 부분에 남아 있던 오래된 데이터를 의도치 않게 기록하게 된다는 의미입니다.이는 버퍼가 1바이트보다 크다고 가정할 때 EoF에서 대부분의 시간 동안 발생하는 것이 거의 확실하지만 EoF의 추가 데이터는 아마도 손상의 원인이 아닐 것입니다. 이는 바람직하지 않습니다.
다른 팁
난 그냥 사용할 것 커먼즈 io 그런 다음 IOUtils.copy(InputStream, OutputStream);
다른 유용한 유틸리티 방법이 많이 있습니다.
이미지가 왜곡되어 나오지 않거나 도중에 일부 패킷이 삭제되지 않는 것이 확실합니까?
어떤 차이가 있는지는 모르겠지만 메서드 서명이 일치하지 않는 것 같습니다.그만큼 getBytes()
메소드가 호출되었습니다. doPost()
메소드에는 인수가 하나만 있습니다:
byte[] bytes = StreamUtils.getBytes(stream);
포함된 메소드 소스에는 두 개의 인수가 있습니다.
public static byte[] getBytes(InputStream src, int buffsize)
도움이 되길 바랍니다.
원본 파일과 업로드된 파일에 대해 체크섬을 수행하여 즉각적인 차이점이 있는지 확인할 수 있습니까?
그렇다면 diff를 수행하여 누락된 파일의 정확한 부분이 변경되었는지 확인할 수 있습니다.
마음에 떠오르는 것은 스트림의 시작이나 끝 또는 엔디안입니다.