FastDFSUtil.java 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. package cn.stylefeng.guns.zjxlUtil;
  2. import java.io.ByteArrayOutputStream;
  3. import java.io.IOException;
  4. import java.io.InputStream;
  5. import java.net.InetSocketAddress;
  6. import cn.stylefeng.guns.zjxlUtil.FastDFSClientPool;
  7. import com.fasterxml.jackson.databind.ObjectMapper;
  8. import com.fasterxml.jackson.databind.node.ObjectNode;
  9. import org.csource.common.MyException;
  10. import org.csource.common.NameValuePair;
  11. import org.csource.fastdfs.ClientGlobal;
  12. import org.csource.fastdfs.ProtoCommon;
  13. import org.csource.fastdfs.StorageClient;
  14. import org.csource.fastdfs.StorageClient1;
  15. import org.csource.fastdfs.TrackerServer;
  16. import org.slf4j.Logger;
  17. import org.slf4j.LoggerFactory;
  18. /**
  19. * FastDFS 客户端工具.
  20. *
  21. * @author szx
  22. */
  23. public class FastDFSUtil {
  24. public final static String GroupField = "groupName";
  25. public final static String RemoteFileField = "remoteFileName";
  26. public final static String FileIdField = "fid";
  27. public final static String FileUrlField = "fileUrl";
  28. // static TrackerClient tracker;
  29. // static TrackerServer trackerServer;
  30. // static StorageServer storageServer;
  31. // static StorageClient client;
  32. //
  33. // static {
  34. // try {
  35. // XEnvironmentOption environmentOption = ServiceFactory.getService(Services.EnvironmentOption);
  36. // String basePath = FastDFSUtil.class.getResource("/").getPath();
  37. // String configFile = basePath + environmentOption.getOption(EnvironmentOptions.FastDFSConfig);
  38. //
  39. // ClientGlobal.init(configFile);
  40. //
  41. // tracker = new TrackerClient();
  42. // trackerServer = tracker.getConnection();
  43. // storageServer = null;
  44. // client = new StorageClient(trackerServer, storageServer);
  45. // } catch (FileNotFoundException e) {
  46. // LogService.getLogger(FastDFSUtil.class).fatal("FastDFS配置文件打开失败: " + e.getMessage());
  47. // } catch (IOException e) {
  48. // LogService.getLogger(FastDFSUtil.class).fatal("FastDFS初始化失败: " + e.getMessage());
  49. // } catch (MyException e) {
  50. // LogService.getLogger(FastDFSUtil.class).fatal("FastDFS初始化失败: " + e.getMessage());
  51. // }
  52. // }
  53. final static int BUFFER_SIZE = 4096;
  54. /**
  55. * 以输入流的方式上传文件
  56. * InputStream in = new FileInputStream("C://Desert.jpg");
  57. * ObjectNode msg = FileUtil.upload(in,"jpg", "沙漠");
  58. * in.close();
  59. *
  60. * @param in 输入流
  61. * @param fileExtension 文件扩展名,不要带“.”
  62. * @param description 文件名称(中文)
  63. * @return 返回值的格式如下:
  64. * {
  65. * "groupName": "healthArchiveGroup",
  66. * "remoteFileName": "/M00/00/24/rBFuH1XdQC6AP3CDAAzodQCbVVc052.jpg",
  67. * "fid": "group1/M00/00/24/rBFuH1XdQC6AP3CDAAzodQCbVVc052.jpg",
  68. * "fileURL": "http://172.19.103.13/healthArchiveGroup/M00/00/24/rBFuH1XdQC6AP3CDAAzodQCbVVc052.jpg"
  69. * }
  70. *
  71. * groupName 及 remoteFileName 可以用于查询在 fastDFS 中文件的信息,如果只是图片显示,可以忽略这两个值。
  72. * fid 保存了在 fastDFS 上的完整路径,为了避免将来服务器域名发生变更,最好使用本值.服务器的域名另外配置。
  73. * fileURL 保存了完整的 web 访问路径,为了避免将来服务器域名发生变更,最好不要直接使用本值。
  74. * 如果需要在下载时,可以显示原始文件名,请在访问file_url时,增加 attname 参数,如:
  75. *
  76. * http://host/healthArchiveGroup/M00/00/00/rBFuH1XdIseAUTZZAA1rIuRd3Es062.jpg?attname=a.jpg
  77. *
  78. * @throws Exception
  79. */
  80. public static ObjectNode upload(InputStream in, String fileExtension,
  81. String description) throws Exception {
  82. System.out.println("FastDFSUtil→InputStream === "+in);
  83. StorageClient client = FastDFSClientPool.getInstance().getStorageClient();
  84. try {
  85. NameValuePair[] fileMetaData;
  86. fileMetaData = new NameValuePair[1];
  87. fileMetaData[0] = new NameValuePair("description", description == null ? "" : description);
  88. ObjectMapper objectMapper = new ObjectMapper();
  89. ObjectNode message = objectMapper.createObjectNode();
  90. ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
  91. byte[] buff = new byte[BUFFER_SIZE]; //buff用于存放循环读取的临时数据
  92. int rc = 0;
  93. while ((rc = in.read(buff, 0, BUFFER_SIZE)) > 0) {
  94. swapStream.write(buff, 0, rc);
  95. }
  96. byte[] fileBuffer = swapStream.toByteArray(); //in_b为转换之后的结果
  97. TrackerServer trackerServer = FastDFSClientPool.getInstance().getTrackerServer();
  98. String[] results = client.upload_file(fileBuffer, fileExtension, fileMetaData);
  99. if (results != null) {
  100. String fileId;
  101. int ts;
  102. String token;
  103. String fileURl;
  104. InetSocketAddress socketAddress;
  105. String groupName = results[0];
  106. String remoteFile = results[1];
  107. message.put(GroupField, groupName);
  108. message.put(RemoteFileField, remoteFile);
  109. fileId = groupName + StorageClient1.SPLIT_GROUP_NAME_AND_FILENAME_SEPERATOR + remoteFile;
  110. message.put(FileIdField, fileId);
  111. socketAddress = trackerServer.getInetSocketAddress();
  112. fileURl = "http://" + socketAddress.getAddress().getHostAddress();
  113. if (ClientGlobal.g_tracker_http_port != 80) {
  114. fileURl += ":" + ClientGlobal.g_tracker_http_port;
  115. }
  116. fileURl += "/" + fileId;
  117. if (ClientGlobal.g_anti_steal_token) {
  118. ts = (int) (System.currentTimeMillis() / 1000);
  119. token = ProtoCommon.getToken(fileId, ts, ClientGlobal.g_secret_key);
  120. fileURl += "?token=" + token + "&ts=" + ts;
  121. }
  122. message.put(FileUrlField, fileURl);
  123. return message;
  124. } else {
  125. return null;
  126. }
  127. }finally {
  128. FastDFSClientPool.getInstance().releaseStorageClient(client);
  129. }
  130. }
  131. /**
  132. * 上传本地文件
  133. * ObjectNode a = FileUtil.upload("C://Desert.jpg", "沙漠");
  134. * System.out.println(a.toString());
  135. *
  136. * @param fileName 本地文件的绝对路径,如 C://Desert.jpg
  137. * @param description 文件备注, 可以为空
  138. * @return {"groupName":"group1","remoteFileName":"/M00/00/24/rBFuH1XdQC6AP3CDAAzodQCbVVc052.jpg"
  139. * {
  140. * "groupName": "healthArchiveGroup",
  141. * "remoteFileName": "/M00/00/24/rBFuH1XdQC6AP3CDAAzodQCbVVc052.jpg",
  142. * "fid": "group1/M00/00/24/rBFuH1XdQC6AP3CDAAzodQCbVVc052.jpg",
  143. * "fileURL": "http://172.19.103.13/healthArchiveGroup/M00/00/24/rBFuH1XdQC6AP3CDAAzodQCbVVc052.jpg"
  144. * }
  145. *
  146. * groupName 及 remoteFileName 可以用于查询在 fastDFS 中文件的信息,如果只是图片显示,可以忽略这两个值。
  147. * fid 保存了在 fastDFS 上的完整路径,为了避免将来服务器域名发生变更,最好使用本值.服务器的域名另外配置。
  148. * fileURL 保存了完整的 web 访问路径,为了避免将来服务器域名发生变更,最好不要直接使用本值。
  149. * 如果需要在下载时,可以显示原始文件名,请在访问file_url时,增加 attname 参数,如:
  150. *
  151. * http://host/healthArchiveGroup/M00/00/00/rBFuH1XdIseAUTZZAA1rIuRd3Es062.jpg?attname=a.jpg
  152. *
  153. * @throws Exception
  154. */
  155. public static ObjectNode upload(String fileName, String description) throws Exception {
  156. StorageClient client = FastDFSClientPool.getInstance().getStorageClient();
  157. try {
  158. NameValuePair[] meta_list;
  159. meta_list = new NameValuePair[1];
  160. meta_list[0] = new NameValuePair("description", description == null ? "" : description);
  161. ObjectMapper objectMapper = new ObjectMapper();
  162. ObjectNode message = objectMapper.createObjectNode();
  163. String fileExtName = "";
  164. if (fileName.contains(".")) {
  165. fileExtName = fileName.substring(fileName.lastIndexOf(".") + 1);
  166. } else {
  167. throw new RuntimeException("上传失败, 文件缺失扩展名.");
  168. }
  169. TrackerServer trackerServer = FastDFSClientPool.getInstance().getTrackerServer();
  170. String[] results = client.upload_file(fileName, fileExtName, meta_list);
  171. if (results != null) {
  172. String fileId;
  173. int ts;
  174. String token;
  175. String fileUrl;
  176. InetSocketAddress inetSockAddr;
  177. String groupName = results[0];
  178. String remoteFileName = results[1];
  179. message.put(GroupField, groupName);
  180. message.put(RemoteFileField, remoteFileName);
  181. fileId = groupName + StorageClient1.SPLIT_GROUP_NAME_AND_FILENAME_SEPERATOR + remoteFileName;
  182. message.put(FileIdField, fileId);
  183. inetSockAddr = trackerServer.getInetSocketAddress();
  184. fileUrl = "http://" + inetSockAddr.getAddress().getHostAddress();
  185. if (ClientGlobal.g_tracker_http_port != 80) {
  186. fileUrl += ":" + ClientGlobal.g_tracker_http_port;
  187. }
  188. fileUrl += "/" + fileId;
  189. if (ClientGlobal.g_anti_steal_token) {
  190. ts = (int) (System.currentTimeMillis() / 1000);
  191. token = ProtoCommon.getToken(fileId, ts, ClientGlobal.g_secret_key);
  192. fileUrl += "?token=" + token + "&ts=" + ts;
  193. }
  194. message.put(FileUrlField, fileUrl);
  195. return message;
  196. } else {
  197. return null;
  198. }
  199. }finally {
  200. FastDFSClientPool.getInstance().releaseStorageClient(client);
  201. }
  202. }
  203. /**
  204. * 下载文件, 返回文件字节数组.
  205. *
  206. * @param groupName 在fastdfs上的卷名
  207. * @param remoteFileName 在fastdfs上的路径
  208. * @return 文件的字节码
  209. * @throws Exception
  210. */
  211. public static byte[] download(String groupName, String remoteFileName) throws Exception {
  212. StorageClient client = FastDFSClientPool.getInstance().getStorageClient();
  213. try {
  214. byte[] b = client.download_file(groupName, remoteFileName);
  215. return b;
  216. }
  217. finally {
  218. FastDFSClientPool.getInstance().releaseStorageClient(client);
  219. }
  220. }
  221. /**
  222. * 下载文件到本地路径上.
  223. *
  224. * @param groupName 在 fastDFS 上的卷名
  225. * @param remoteFileName 在 fastDFS 上的路径
  226. * @param localPath 本地路径
  227. *
  228. * @return 是否下载成功
  229. */
  230. public static String download(String groupName, String remoteFileName, String localPath) throws IOException, MyException {
  231. StorageClient client = FastDFSClientPool.getInstance().getStorageClient();
  232. try {
  233. String localFileName = localPath + "\\" + remoteFileName.replaceAll("/", "_");
  234. client.download_file(groupName, remoteFileName, 0, 0, localFileName);
  235. return localFileName;
  236. }finally {
  237. FastDFSClientPool.getInstance().releaseStorageClient(client);
  238. }
  239. }
  240. /**
  241. * 删除文件。
  242. *
  243. * @param groupName
  244. * @param remoteFileName
  245. */
  246. public static void delete(String groupName, String remoteFileName) throws IOException, MyException {
  247. StorageClient client = FastDFSClientPool.getInstance().getStorageClient();
  248. try {
  249. client.delete_file(groupName, remoteFileName);
  250. }finally {
  251. FastDFSClientPool.getInstance().releaseStorageClient(client);
  252. }
  253. }
  254. }