DownloadとUpload
ファイルダウンロード
ASP.NET
ファイル名の設定(共通)
string fileName = "一覧.csv";//クライアント側
fileName = HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8);
或いは
fileName = Server.UrlEncode(fileName);
string filePath = Server.MapPath("DownLoad/test.csv"); //サーバ側
1.Stream
byte[] bytes = null;
//★ファイルの場合
using (FileStream fs = new FileStream(filePath, FileMode.Open))
{
bytes = new byte[(int)fs.Length];
fs.Read(bytes, 0, bytes.Length);
fs.Close();
}
// ★文字列の場合
Encoding encoding = System.Text.Encoding.GetEncoding("Shift-JIS");
bytes = encoding.GetBytes(csvString);
// HTTPヘッダに規定のファイル名を指定
Response.AddHeader("Content-Disposition", "attachment;filename=" + fileName);
// ※attachment:ファイルをダウンロード、inline:ファイルを開く
// MIMEコンテンツタイプを指定
Response.ContentType = "application/octet-stream";
// HTTP出力ストリームにバイナリ文字の文字列を書き込む
Response.BinaryWrite(bytes);
// ページの実行を停止し、Application_EndRequestイベントを発生させる
Response.Flush();
Response.End();
2.WriteFile
FileInfo fileInfo = new FileInfo(filePath);
if (fileInfo.Exists)
{
Response.Clear();
Response.ClearContent();
Response.ClearHeaders();
Response.AddHeader("Content-Disposition", ...);
Response.AddHeader("Content-Length", fileInfo.Length.ToString());
Response.AddHeader("Content-Transfer-Encoding", "binary");
Response.ContentType = "application/octet-stream";
Response.ContentEncoding = System.Text.Encoding.GetEncoding("Shift-JIS");
Response.WriteFile(fileInfo.FullName);
Response.Flush();
Response.End();
}
3.WriteFile(Chunk)
サーバのトラフィックを減少
FileInfo fileInfo = new FileInfo(filePath);
if (fileInfo.Exists)
{
const long CHUNK_SIZE = 102400; //100K毎に
byte[] buffer = new byte[CHUNK_SIZE];
Response.Clear();
Response.AddHeader("Content-Disposition", ...);
Response.ContentType = "application/octet-stream";
using (FileStream fs = File.OpenRead(filePath))
{
long dataLength = fs.Length;
while (dataLength > 0 && Response.IsClientConnected)
{
int readLength = fs.Read(buffer, 0, Convert.ToInt32(CHUNK_SIZE));
Response.OutputStream.Write(buffer, 0, readLength);
Response.Flush();
dataLength -= readLength;
}
}
Response.Close();
}
4.TransmitFile
出力ファイルがHTTP Responseを含むため、binaryファイルに向けない
string fileName = "一覧.zip";//クライアント側
string filePath = Server.MapPath("DownLoad/test.zip"); //サーバ側
Response.AddHeader("Content-Disposition", "attachment;filename=" + fileName);
Response.ContentType = "application/x-zip-compressed";
Response.TransmitFile(filePath);
JavaEE (Servlet)
<a href="/project/download/test.zip">xxx</a>
或いは
<a href="/project/download?filename=test.zip">xxx</a>
String clientFileName = request.getParameter("filename");
String serverFileName = getServletContext().getRealPath("/download/" + clientFileName);
download(clientFileName, serverFileName);
public static void download(String clientFileName, String serverFileName) {
HttpServletResponse response = ResponseUtil.getResponse(); // Seasar2
String encodingFileName = null;
try {
encodingFileName = URLEncoder.encode(clientFileName, "UTF-8");
} catch (UnsupportedEncodingException e) {
...
}
response.setCharacterEncoding("UTF-8");
response.setContentType("application/octet-stream");
//response.setContentType(getServletContext().getMimeType(serverFileName));
response.setHeader("Content-Disposition",
"inline;filename=\"" + encodingFileName + "\"");
※"inline"(埋め込み)|"attachment"(添付)
// 書き方1
try (
BufferedReader in =
new BufferedReader(
new InputStreamReader(
new FileInputStream(serverFileName), "UTF-8"));
BufferedWriter out =
new BufferedWriter(
new OutputStreamWriter(response.getOutputStream(), "UTF-8"))
) {
String line = null;
while ((line = in.readLine()) != null) {
out.write(line);
out.newLine();
}
} catch (IOException e) {
...
}
// 書き方2
try (
BufferedInputStream in =
new BufferedInputStream(
new FileInputStream("/usr/local/test.csv"));
BufferedOutputStream out =
new BufferedOutputStream(response.getOutputStream())
) {
int x;
while ((x = in.read()) >= 0) {
out.write(x);
}
}catch(IOException e){
...
}
}
JavaEE (JAX-RS)
@GET
@Path("/download")
@Produces(MediaType.APPLICATION_OCTET_STREAM)
public Response download() throws UnsupportedEncodingException {
StringBuilder contents = new StringBuilder();
contents.append("...");
InputStream is =
new ByteArrayInputStream(contents.toString().getBytes("UTF-8"));
String fileName = URLEncoder.encode("ファイル名.txt", "UTF-8");
return Response.ok(is)
.header("Content-disposition",
"attachment; filename=" + fileName)
.build();
}
@GET
@Path("/text/{fileName}")
//@Path("/pdf/{fileName}")
//@Path("/image/{fileName}")
@Produces("text/plain")
//@Produces("application/pdf")
//@Produces("image/jpeg")
public Response getFile(@PathParam("fileName") String fileName) {
if(isNullOrEmpty(fileName)) {
ResponseBuilder response = Response.status(Status.BAD_REQUEST);
return response.build();
}
File file = new File("/path/xxxFile.txt");
//File file = new File("/path/xxxFile.pdf");
//File file = new File("/path/xxxFile.jpeg");
ResponseBuilder response = Response.ok((Object) file);
response.header("Content-Disposition", "attachment; filename='dw.txt'");
//response.header("Content-Disposition", "attachment; filename='dw.pdf'");
//response.header("Content-Disposition", "attachment; filename='dw.jpeg'");
return response.build();
}
Seasar2
public class FileDownloadAction {
@Execute(validator = false)
public String index() {
String fileName = ...;
// 日本語ファイル名対応
String userAgent = RequestUtil.getRequest().getHeader("USER-AGENT");
if(userAgent.indexOf("MSIE") >= 0 && userAgent.indexOf("Opera") < 0) {
fileName =
new String(fileName.getBytes("Windows-31J"), "ISO8859_1");
}else{
fileName = new String(fileName.getBytes("UTF-8"), "ISO8859_1");
}
InputStream is = ...;
ResponseUtil.download(fileName, is);
return null;
}
}
PHP
function downloadFile(){
$filepath = "D:\data\xxx.out";
header('Content-Disposition: attachment; filename="' . basename($filepath) . '"');
header('Content-Type: application/octet-stream'); // バイナリ
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . filesize($filepath));
flush();
readfile($filepath);
unlink($filepath); //一時的なファイルの場合に削除
}
header('Content-Type: application/zip'); // 圧縮
header("Content-Type: text/xml"); //XML
echo '<?xml version="1.0" encoding="utf-8">...';
header("Content-Type: application/x-javascript"); //JavaScript
echo "var a = 3";
header("Content-Type: text/css"); //CSS
echo "#id { background:blue; }";
クライアント側はExtJS、サーバ側はCakePHPの場合
var mask = null;
// マスク設定
mask = new Ext.LoadMask(Ext.getBody(), {msg: 'ダウンロード中…'});
mask.show();
var params = {
id: 101,
name: 'Andy'
};
// ダウンロードを要求
Ext.Ajax.request({
url: '<?php echo $html->url("/sample/createFile")?>',
success: callback,
params: params,
method: 'POST'
});
function callback(response, options){
if ( mask != null ) {
mask.hide();
mask = null;
}
// ファイルをダウンロードするため、ダミーフォームを作成
if (!Ext.fly('frmDummy')){
var frm = document.createElement('form');
frm.id = 'frmDummy';
frm.name = id;
frm.className = 'x-hidden';
frm.action = '<?php echo $html->url("/sample/downloadFile")?>'
frm.method = 'post';
document.body.appendChild(frm);
}
Ext.fly('frmDummy').dom.submit();
}
★セキュリティ対策
PHPの場合
if(strstr($_GET['filename'], '..')){
exit;
}
readfile('/usr/local/', $_GET['filename']);
Javaの場合
if(filename.indexOf("..") >= 0){
throw new Exception();
}
is = new FileInputStream("/usr/local/" + request.getParameter("filename"));
★日本語ファイル名対応
PHP
$filename = urlencode($filename);
header('Content-Disposition: attachment; filename=' . $filename);
$filename = mb_convert_encoding($filename, "SJIS", "auto"); // Windowsの場合
Java
filename = URLEncoder.encode(filename, "UTF-8");
response.setHeader("Content-Disposition", "attachment; filename=" + filename);
ファイルアップロード
ASP.NET
方法1
<form id="form1" runat="server">
<asp:FileUpload ID="fileUpload1" runat="server" />
<asp:Button ID="button1" runat="server" Text="アップロード" OnClick="button1_Click" />
</form>
方法2
<form id="form1" runat="server">
<input type="file" id="file1" runat="server" />
<asp:Button ID="button1" runat="server" Text="アップロード" OnClick="button1_Click" />
</form>
方法3
<form id="form1" runat="server" enctype="multipart/form-data">
<input type="file" name="file" />
<asp:Button ID="button1" runat="server" Text="アップロード" OnClick="button1_Click" />
</form>
JavaEE
import javax.servlet.http.Part;
public class UploadUtil{
public static String getFileType(Part p){
String name = p.getHeader("content-disposition");
String fileName = name.substring(name.indexOf("filename=") + 10);
return fileName.substring(
fileName.indexOf(".") + 1, fileName.indexOf("\""));
}
public static String getFileName(Part p){
String name = p.getHeader("content-disposition");
String fileName = name.substring(name.indexOf("filename=") + 10);
return fileName.substring(0, fileName.indexOf("\""));
}
}
Seasar2
<html:errors/>
<s:form method="POST" enctype="multipart/form-data">
<html:file property="file" />
<html:submit propterty="upload" value="アップロード" />
</s:form>
アップロードサイズの制限
struts-config.xml
<controller
maxFileSize="1024K"
bufferSize="1024"
processorClass="org.seasar.struts.action.S2RequestProcessor"
multipartClass="org.seasar.struts.upload.S2MultipartRequestHandler"
/>
import org.apache.struts.upload.FormFile;
public class FileUploadForm() {
@Required
public FormFile file;
}
public class FileUploadAction {
@ActionForm
@Resource
protected FileUploadForm fileUploadForm;
@Resource
protected HttpServletRequest request;
@Execute(validator = false)
public String index() {
SizeLimitExceededException ex = (SizeLimitExceededException)
request.getAttribute(S2MultipartRequestHandler.SIZE_EXCEPTION_KEY);
if(ex != null) {
ActionMessages errors = new ActionMessages();
errors.add(ActionMessages.GLOBAL_MESSAGE,
new ActionMessage("errors.upload.size",
new Object[]{ ex.getActualSize(), ex.getPermittedSize() }));
ActionMessagesUtil.addErrors(request, errors);
}
return "index.jsp";
}
@Execute(validator = true, input = "index.jsp")
public String upload() {
String fileName = this.fileUploadForm.file.getFileName();
int size = this.fileUploadForm.file.getFileSize();
String contentType = this.fileUploadForm.file.getContentType();
byte[] fileData = this.fileUploadForm.file.getFileData();
InputStream is = this.getContentType.getInputStream();
...
}
}