Java上传的文件不一样
Java Uploaded file is not the same
我的问题如下,我正在尝试通过 servlet 将文件上传到我的服务器,但上传的文件不一样,与原始文件相比有差异。
比如我上传TXT文件为例
# Root logger option
log4j.rootLogger=DEBUG, stdout, file
# Redirect log messages to console
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
# Rirect log messages to a log file
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=C:\filesLog\log.log
log4j.appender.file.MaxFileSize=5MB
log4j.appender.file.MaxBackupIndex=10
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
上传文件换行
...
NULNULNULNULNULNUL
(用Notepad++打开)。
如果文件是.exe,上传的文件不起作用。
我的代码如下
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
System.out.println("ES UN REQUEST MULTIPART " + isMultipart);
// Set factory constraints
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload();
// Set overall request size constraint
// MAX REQUEST SIZE
// Parse the request
// List / FileItem / items = upload.parseRequest(request);
FileItemIterator iter = upload.getItemIterator(request);
while (iter.hasNext()) {
// FileItem item = (FileItem) iter.next();
FileItemStream itemS = (FileItemStream) iter.next();
if (itemS.isFormField() == false) {
// Process a file upload
String fileName = itemS.getName();
System.out.println("FILE NAME " + fileName);
// Process a file upload
File uploadedFile = new File("C:\FilesUpload\" + UUID.randomUUID());
// InputStream uploadedStream = item.getInputStream();
FileOutputStream fout = new FileOutputStream(uploadedFile);
BufferedOutputStream bout = new BufferedOutputStream(fout);
BufferedInputStream bin = new BufferedInputStream(itemS.openStream());
byte buf[] = new byte[2048];
Long contador = 0L;
while ((bin.read(buf)) != -1) {
bout.write(buf);
contador = contador + 1L;
}
bout.close();
bin.close();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
您忽略了从 bin.read(buf)
返回的值,该值指示读取的字节数。无法保证读取操作会填满您的缓冲区。因此,您对 bout.write(buf)
的许多调用都在写入垃圾数据。
这是将 InputStream 保存到文件的更简单的方法(因此更不容易出错):
Files.copy(bin, uploadedFile.toPath());
在这部分代码中:
while ((bin.read(buf)) != -1) {
bout.write(buf);
contador = contador + 1L;
}
您没有检查已读取了多少字节。最后读取的缓冲区,如果文件长度不能正好被2048整除,将只读取部分。在这种情况下,bin.read(buf)
将 return 读取的字节数,并且您应该只在写入 buf
时使用该数字,否则您将在 [=14] 中写入所有 2048 个字节=],包括您之前读取的值或零(如果这是第一次读取)。
所以它应该是这样的:
int numBytesRead;
while ((numBytesRead = bin.read(buf)) != -1) {
bout.write(buf,0,numBytesRead);
contador = contador + 1L;
}
这将使它准确地写入它所读取的内容。
顺便说一句,如果您使用的是 Java 7 及更高版本,那么您可以使用 Files.copy
将整个流直接复制到您的文件,而不是执行所有这些操作。
Files.copy(itemS.openStream(),
Paths.get("C:\FilesUpload\" + UUID.randomUUID()),
StandardCopyOption.REPLACE_EXISTING );
勾选
bout.write(buf)
我会写整个缓冲区,即使它的一部分是空的。
注意你的 buf
是 2048
字节..
我的问题如下,我正在尝试通过 servlet 将文件上传到我的服务器,但上传的文件不一样,与原始文件相比有差异。
比如我上传TXT文件为例
# Root logger option
log4j.rootLogger=DEBUG, stdout, file
# Redirect log messages to console
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
# Rirect log messages to a log file
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=C:\filesLog\log.log
log4j.appender.file.MaxFileSize=5MB
log4j.appender.file.MaxBackupIndex=10
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
上传文件换行
...
NULNULNULNULNULNUL
(用Notepad++打开)。
如果文件是.exe,上传的文件不起作用。
我的代码如下
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
System.out.println("ES UN REQUEST MULTIPART " + isMultipart);
// Set factory constraints
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload();
// Set overall request size constraint
// MAX REQUEST SIZE
// Parse the request
// List / FileItem / items = upload.parseRequest(request);
FileItemIterator iter = upload.getItemIterator(request);
while (iter.hasNext()) {
// FileItem item = (FileItem) iter.next();
FileItemStream itemS = (FileItemStream) iter.next();
if (itemS.isFormField() == false) {
// Process a file upload
String fileName = itemS.getName();
System.out.println("FILE NAME " + fileName);
// Process a file upload
File uploadedFile = new File("C:\FilesUpload\" + UUID.randomUUID());
// InputStream uploadedStream = item.getInputStream();
FileOutputStream fout = new FileOutputStream(uploadedFile);
BufferedOutputStream bout = new BufferedOutputStream(fout);
BufferedInputStream bin = new BufferedInputStream(itemS.openStream());
byte buf[] = new byte[2048];
Long contador = 0L;
while ((bin.read(buf)) != -1) {
bout.write(buf);
contador = contador + 1L;
}
bout.close();
bin.close();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
您忽略了从 bin.read(buf)
返回的值,该值指示读取的字节数。无法保证读取操作会填满您的缓冲区。因此,您对 bout.write(buf)
的许多调用都在写入垃圾数据。
这是将 InputStream 保存到文件的更简单的方法(因此更不容易出错):
Files.copy(bin, uploadedFile.toPath());
在这部分代码中:
while ((bin.read(buf)) != -1) {
bout.write(buf);
contador = contador + 1L;
}
您没有检查已读取了多少字节。最后读取的缓冲区,如果文件长度不能正好被2048整除,将只读取部分。在这种情况下,bin.read(buf)
将 return 读取的字节数,并且您应该只在写入 buf
时使用该数字,否则您将在 [=14] 中写入所有 2048 个字节=],包括您之前读取的值或零(如果这是第一次读取)。
所以它应该是这样的:
int numBytesRead;
while ((numBytesRead = bin.read(buf)) != -1) {
bout.write(buf,0,numBytesRead);
contador = contador + 1L;
}
这将使它准确地写入它所读取的内容。
顺便说一句,如果您使用的是 Java 7 及更高版本,那么您可以使用 Files.copy
将整个流直接复制到您的文件,而不是执行所有这些操作。
Files.copy(itemS.openStream(),
Paths.get("C:\FilesUpload\" + UUID.randomUUID()),
StandardCopyOption.REPLACE_EXISTING );
勾选
bout.write(buf)
我会写整个缓冲区,即使它的一部分是空的。
注意你的 buf
是 2048
字节..