1 Star 0 Fork 22

三良/WebJava

forked from 老馬/WebJava 
Create your Gitee Account
Explore and code with more than 14 million developers,Free private repositories !:)
Sign up
文件
This repository doesn't specify license. Please pay attention to the specific project description and its upstream code dependency when using it.
Clone or Download
StaticFileServer.java 6.80 KB
Copy Edit Raw Blame History
Ma authored 2015-06-12 09:41 +08:00 . 添加Demo
package Web;
import java.nio.channels.SocketChannel;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousFileChannel;
import java.nio.channels.CompletionHandler;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributeView;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.concurrent.TimeUnit;
/**
* 静态文件服务器
*
* @author Ma
*/
public class StaticFileServer {
public Request request;
public int size;
public ByteBuffer byteBuffer;
public SocketChannel socketChannel;
public Path filePath;
public String ExName;//扩展名字
/**
* 初始化一些东西
*
* @param request
*/
public StaticFileServer(Request request) {
this.request = request;
String path = Options.StaticPath + this.request.Path.substring(8);
this.filePath = Paths.get(path);
//设置扩展名
int index = this.request.Path.lastIndexOf(".");
this.ExName = this.request.Path.substring(index + 1);
}
/**
* 检测文件是否存在
*
* @return
*/
public boolean exists() {
return Files.exists(filePath);
}
/**
* 检查文件是否需要更新还是304状态吗
*
* @return
*/
public boolean update() {
try {
int lastTime = (int) Files.getLastModifiedTime(filePath).to(TimeUnit.SECONDS);//获取最后修改的时间戳
Object paramTime = this.request.Header.get("If-Modified-Since");
if ((paramTime != null) && (Integer.parseInt((String) paramTime) <= lastTime)) {
//处理304
Response.setStatus(304);
Response.setContentType(Response.findContentType(this.ExName));
Response.header("Last-Modified: " + lastTime);
Response.header("Cache-Control:public, max-age=2592000");
byte[] headerBytes = Response.getHeader().getBytes();
ByteBuffer writerBuffer = ByteBuffer.allocate(headerBytes.length);
writerBuffer.clear();
writerBuffer.put(headerBytes);
writerBuffer.flip();
while (writerBuffer.hasRemaining()) {
this.socketChannel.write(writerBuffer);
}
writerBuffer.clear();
this.socketChannel.close();
//输出debug信息
if (Options.DEBUG || Options.ParseLine) {
System.out.println(Response.Status + " " + this.request.Header.get("Host") + this.request.Path);
}
Response.finish();//清理信息
return false;
}
} catch (IOException ex) {
Logger.getLogger(StaticFileServer.class.getName()).log(Level.SEVERE, null, ex);
}
return true;
}
public void read(SocketChannel socketChannel) {
this.socketChannel = socketChannel;
//处理304
if (this.update()) {
//输出debug信息
if (Options.DEBUG || Options.ParseLine) {
System.out.println("Static File" + " " + this.request.Header.get("Host") + this.request.Path);
}
//处理200
BasicFileAttributeView basicView = Files.getFileAttributeView(this.filePath, BasicFileAttributeView.class);
try {
BasicFileAttributes basicAttrs = basicView.readAttributes();
long size = basicAttrs.size();
if (size > 2097152) {
//说明文件大于2M
}
this.size = (int) size;
int lastTime = (int) Files.getLastModifiedTime(filePath).to(TimeUnit.SECONDS);//获取最后修改的时间戳
this.byteBuffer = ByteBuffer.allocate((int) size);//申请缓存空间
//开始获取通道,读取文件
AsynchronousFileChannel afc = AsynchronousFileChannel.open(this.filePath);
afc.read(byteBuffer, 0, lastTime, new CompletionHandlerImpl(afc));
} catch (IOException ex) {
//处理500错误
Logger.getLogger(StaticFileServer.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
/**
* 成员类 处理文件完成后的操作
*/
private class CompletionHandlerImpl implements CompletionHandler<Integer, Object> {
AsynchronousFileChannel afc;
public CompletionHandlerImpl(AsynchronousFileChannel afc) {
this.afc = afc;
}
/**
* 处理成功的操作
*
* @param result
* @param attachment
*/
@Override
public void completed(Integer result, Object attachment) {
Integer lastModifyInteger = (Integer) attachment;
int lastModify = lastModifyInteger.intValue();
//Header不能使用Response
String header = "HTTP/1.1 200 OK\r\n"
+ "Content-type: " + Response.findContentType(StaticFileServer.this.ExName) + ";\r\n"
+ "Content-ength: " + StaticFileServer.this.size + "\r\n"
+ "Last-Modified: " + lastModify + "\r\n"
+ "Cache-Control:public, max-age=2592000 \r\n"
+ "Server: " + Response.Server + "\r\n\r\n";
byte[] headerBytes = header.getBytes();
byte[] contentBytes = StaticFileServer.this.byteBuffer.array();
ByteBuffer writerBuffer = ByteBuffer.allocate(headerBytes.length + contentBytes.length);
writerBuffer.clear();
writerBuffer.put(headerBytes);
writerBuffer.put(contentBytes);
writerBuffer.flip();
try {
while (writerBuffer.hasRemaining()) {
StaticFileServer.this.socketChannel.write(writerBuffer);
}
writerBuffer.clear();
StaticFileServer.this.socketChannel.close();
this.afc.close();
} catch (IOException ex) {
Logger.getLogger(StaticFileServer.class.getName()).log(Level.SEVERE, null, ex);
}
}
/**
* 处理失败的操作
*
* @param exc
* @param attachment
*/
@Override
public void failed(Throwable exc, Object attachment) {
System.out.println(exc.getCause());
//@todo 处理500错误
try {
StaticFileServer.this.socketChannel.close();
this.afc.close();
} catch (IOException ex) {
Logger.getLogger(StaticFileServer.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Java
1
https://gitee.com/sanliang/WebJava.git
git@gitee.com:sanliang/WebJava.git
sanliang
WebJava
WebJava
master

Search