package com.yihu.wlyy.util.fastdfs; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.InetSocketAddress; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import org.csource.common.MyException; import org.csource.common.NameValuePair; import org.csource.fastdfs.ClientGlobal; import org.csource.fastdfs.ProtoCommon; import org.csource.fastdfs.StorageClient; import org.csource.fastdfs.StorageClient1; import org.csource.fastdfs.TrackerServer; /** * FastDFS 客户端工具. * * @author szx */ public class FastDFSUtil { public final static String GroupField = "groupName"; public final static String RemoteFileField = "remoteFileName"; public final static String FileIdField = "fid"; public final static String FileUrlField = "fileUrl"; // static TrackerClient tracker; // static TrackerServer trackerServer; // static StorageServer storageServer; // static StorageClient client; // // static { // try { // XEnvironmentOption environmentOption = ServiceFactory.getService(Services.EnvironmentOption); // String basePath = FastDFSUtil.class.getResource("/").getPath(); // String configFile = basePath + environmentOption.getOption(EnvironmentOptions.FastDFSConfig); // // ClientGlobal.init(configFile); // // tracker = new TrackerClient(); // trackerServer = tracker.getConnection(); // storageServer = null; // client = new StorageClient(trackerServer, storageServer); // } catch (FileNotFoundException e) { // LogService.getLogger(FastDFSUtil.class).fatal("FastDFS配置文件打开失败: " + e.getMessage()); // } catch (IOException e) { // LogService.getLogger(FastDFSUtil.class).fatal("FastDFS初始化失败: " + e.getMessage()); // } catch (MyException e) { // LogService.getLogger(FastDFSUtil.class).fatal("FastDFS初始化失败: " + e.getMessage()); // } // } final static int BUFFER_SIZE = 4096; /** * 以输入流的方式上传文件 * InputStream in = new FileInputStream("C://Desert.jpg"); * ObjectNode msg = FileUtil.upload(in,"jpg", "沙漠"); * in.close(); * * @param in 输入流 * @param fileExtension 文件扩展名,不要带“.” * @param description 文件名称(中文) * @return 返回值的格式如下: * { * "groupName": "healthArchiveGroup", * "remoteFileName": "/M00/00/24/rBFuH1XdQC6AP3CDAAzodQCbVVc052.jpg", * "fid": "group1/M00/00/24/rBFuH1XdQC6AP3CDAAzodQCbVVc052.jpg", * "fileURL": "http://172.19.103.13/healthArchiveGroup/M00/00/24/rBFuH1XdQC6AP3CDAAzodQCbVVc052.jpg" * } * * groupName 及 remoteFileName 可以用于查询在 fastDFS 中文件的信息,如果只是图片显示,可以忽略这两个值。 * fid 保存了在 fastDFS 上的完整路径,为了避免将来服务器域名发生变更,最好使用本值.服务器的域名另外配置。 * fileURL 保存了完整的 web 访问路径,为了避免将来服务器域名发生变更,最好不要直接使用本值。 * 如果需要在下载时,可以显示原始文件名,请在访问file_url时,增加 attname 参数,如: * * http://host/healthArchiveGroup/M00/00/00/rBFuH1XdIseAUTZZAA1rIuRd3Es062.jpg?attname=a.jpg * * @throws Exception */ public static ObjectNode upload(InputStream in, String fileExtension, String description) throws Exception { StorageClient client = FastDFSClientPool.getInstance().getStorageClient(); try { NameValuePair[] fileMetaData; fileMetaData = new NameValuePair[1]; fileMetaData[0] = new NameValuePair("description", description == null ? "" : description); ObjectMapper objectMapper = new ObjectMapper(); ObjectNode message = objectMapper.createObjectNode(); ByteArrayOutputStream swapStream = new ByteArrayOutputStream(); byte[] buff = new byte[BUFFER_SIZE]; //buff用于存放循环读取的临时数据 int rc = 0; while ((rc = in.read(buff, 0, BUFFER_SIZE)) > 0) { swapStream.write(buff, 0, rc); } byte[] fileBuffer = swapStream.toByteArray(); //in_b为转换之后的结果 TrackerServer trackerServer = FastDFSClientPool.getInstance().getTrackerServer(); String[] results = client.upload_file(fileBuffer, fileExtension, fileMetaData); if (results != null) { String fileId; int ts; String token; String fileURl; InetSocketAddress socketAddress; String groupName = results[0]; String remoteFile = results[1]; message.put(GroupField, groupName); message.put(RemoteFileField, remoteFile); fileId = groupName + StorageClient1.SPLIT_GROUP_NAME_AND_FILENAME_SEPERATOR + remoteFile; message.put(FileIdField, fileId); socketAddress = trackerServer.getInetSocketAddress(); fileURl = "http://" + socketAddress.getAddress().getHostAddress(); if (ClientGlobal.g_tracker_http_port != 80) { fileURl += ":" + ClientGlobal.g_tracker_http_port; } fileURl += "/" + fileId; if (ClientGlobal.g_anti_steal_token) { ts = (int) (System.currentTimeMillis() / 1000); token = ProtoCommon.getToken(fileId, ts, ClientGlobal.g_secret_key); fileURl += "?token=" + token + "&ts=" + ts; } message.put(FileUrlField, fileURl); return message; } else { return null; } }finally { FastDFSClientPool.getInstance().releaseStorageClient(client); } } /** * 上传本地文件 * ObjectNode a = FileUtil.upload("C://Desert.jpg", "沙漠"); * System.out.println(a.toString()); * * @param fileName 本地文件的绝对路径,如 C://Desert.jpg * @param description 文件备注, 可以为空 * @return {"groupName":"group1","remoteFileName":"/M00/00/24/rBFuH1XdQC6AP3CDAAzodQCbVVc052.jpg" * { * "groupName": "healthArchiveGroup", * "remoteFileName": "/M00/00/24/rBFuH1XdQC6AP3CDAAzodQCbVVc052.jpg", * "fid": "group1/M00/00/24/rBFuH1XdQC6AP3CDAAzodQCbVVc052.jpg", * "fileURL": "http://172.19.103.13/healthArchiveGroup/M00/00/24/rBFuH1XdQC6AP3CDAAzodQCbVVc052.jpg" * } * * groupName 及 remoteFileName 可以用于查询在 fastDFS 中文件的信息,如果只是图片显示,可以忽略这两个值。 * fid 保存了在 fastDFS 上的完整路径,为了避免将来服务器域名发生变更,最好使用本值.服务器的域名另外配置。 * fileURL 保存了完整的 web 访问路径,为了避免将来服务器域名发生变更,最好不要直接使用本值。 * 如果需要在下载时,可以显示原始文件名,请在访问file_url时,增加 attname 参数,如: * * http://host/healthArchiveGroup/M00/00/00/rBFuH1XdIseAUTZZAA1rIuRd3Es062.jpg?attname=a.jpg * * @throws Exception */ public static ObjectNode upload(String fileName, String description) throws Exception { StorageClient client = FastDFSClientPool.getInstance().getStorageClient(); try { NameValuePair[] meta_list; meta_list = new NameValuePair[1]; meta_list[0] = new NameValuePair("description", description == null ? "" : description); ObjectMapper objectMapper = new ObjectMapper(); ObjectNode message = objectMapper.createObjectNode(); String fileExtName = ""; if (fileName.contains(".")) { fileExtName = fileName.substring(fileName.lastIndexOf(".") + 1); } else { throw new RuntimeException("上传失败, 文件缺失扩展名."); } TrackerServer trackerServer = FastDFSClientPool.getInstance().getTrackerServer(); String[] results = client.upload_file(fileName, fileExtName, meta_list); if (results != null) { String fileId; int ts; String token; String fileUrl; InetSocketAddress inetSockAddr; String groupName = results[0]; String remoteFileName = results[1]; message.put(GroupField, groupName); message.put(RemoteFileField, remoteFileName); fileId = groupName + StorageClient1.SPLIT_GROUP_NAME_AND_FILENAME_SEPERATOR + remoteFileName; message.put(FileIdField, fileId); inetSockAddr = trackerServer.getInetSocketAddress(); fileUrl = "http://" + inetSockAddr.getAddress().getHostAddress(); if (ClientGlobal.g_tracker_http_port != 80) { fileUrl += ":" + ClientGlobal.g_tracker_http_port; } fileUrl += "/" + fileId; if (ClientGlobal.g_anti_steal_token) { ts = (int) (System.currentTimeMillis() / 1000); token = ProtoCommon.getToken(fileId, ts, ClientGlobal.g_secret_key); fileUrl += "?token=" + token + "&ts=" + ts; } message.put(FileUrlField, fileUrl); return message; } else { return null; } }finally { FastDFSClientPool.getInstance().releaseStorageClient(client); } } /** * 下载文件, 返回文件字节数组. * * @param groupName 在fastdfs上的卷名 * @param remoteFileName 在fastdfs上的路径 * @return 文件的字节码 * @throws Exception */ public static byte[] download(String groupName, String remoteFileName) throws Exception { StorageClient client = FastDFSClientPool.getInstance().getStorageClient(); try { byte[] b = client.download_file(groupName, remoteFileName); return b; } finally { FastDFSClientPool.getInstance().releaseStorageClient(client); } } /** * 下载文件到本地路径上. * * @param groupName 在 fastDFS 上的卷名 * @param remoteFileName 在 fastDFS 上的路径 * @param localPath 本地路径 * * @return 是否下载成功 */ public static String download(String groupName, String remoteFileName, String localPath) throws IOException, MyException { StorageClient client = FastDFSClientPool.getInstance().getStorageClient(); try { String localFileName = localPath + "\\" + remoteFileName.replaceAll("/", "_"); client.download_file(groupName, remoteFileName, 0, 0, localFileName); return localFileName; }finally { FastDFSClientPool.getInstance().releaseStorageClient(client); } } /** * 删除文件。 * * @param groupName * @param remoteFileName */ public static void delete(String groupName, String remoteFileName) throws IOException, MyException { StorageClient client = FastDFSClientPool.getInstance().getStorageClient(); try { client.delete_file(groupName, remoteFileName); }finally { FastDFSClientPool.getInstance().releaseStorageClient(client); } } }