filePaths,
244 | final ServerRunnable.ProgressCallBack callBack) {
245 | mFilePaths = filePaths;
246 | closeServer();
247 | new Thread(new Runnable() {
248 |
249 | @Override
250 | public void run() {
251 | try {
252 | server = new ServerSocket(Constant.PORT);
253 | server.setReuseAddress(true);
254 | mExecutorService = Executors.newCachedThreadPool();
255 |
256 | Message.obtain(mHandler, S_STARTED, "服务器已开启").sendToTarget();
257 | isServerRunning = true;
258 | Socket client = null;
259 | while (isServerRunning) {
260 | client = server.accept();
261 | mExecutorService.execute(new ServerRunnable(client,
262 | mHandler, mFilePaths, callBack));
263 |
264 | }
265 | } catch (Exception e) {
266 | e.printStackTrace();
267 | }
268 | }
269 | }).start();
270 | }
271 |
272 | /**
273 | * 关闭socket服务器
274 | */
275 | public void closeServer() {
276 | isServerRunning = false;
277 | if (server != null) {
278 | try {
279 | server.close();
280 | server = null;
281 | } catch (IOException e) {
282 | e.printStackTrace();
283 | }
284 | }
285 | }
286 |
287 | /**
288 | * 创建一个socket客户端
289 | *
290 | * @param hostIp
291 | * 要连接的主机ip地址
292 | * @param port
293 | * 要连接的端口号
294 | * @param path
295 | * 接收的文件路径
296 | * @param fileLen
297 | * 接收的文件字节长度
298 | * @param offset
299 | * 文件写入位置
300 | * @param callBack
301 | * 回调
302 | */
303 | public void newClient(String hostIp, int port, String path, long fileLen,
304 | int offset, SocketJob.FileCallBack callBack) {
305 | // if (Constant.isReceiving){
306 | // if (handler!=null)
307 | // Message.obtain(handler,3," 文件正在接收....不要重复接收").sendToTarget();
308 | // return;
309 | // }
310 | File file = new File(path);
311 |
312 | if (isFileReceived(file, fileLen)) {
313 | if (mHandler != null)
314 | Message.obtain(mHandler, C_MESSAGE, " 文件已经接收过,路径为: " + path)
315 | .sendToTarget();
316 | return;
317 | }
318 | if (isFileReceiving(file, fileLen)) {
319 | if (mHandler != null)
320 | Message.obtain(mHandler, C_MESSAGE, " 文件正在接收...").sendToTarget();
321 | return;
322 | }
323 | mCallBack = callBack;
324 | // Message.obtain(mHandler, C_MESSAGE, "开始连接服务器... ").sendToTarget();
325 | String fileName=file.getName();
326 | // new ClientThread(hostIp, port, offset, fileName, mHandler, callBack).start();
327 | SocketJobManager.getInstance().addJobInBackground(new SocketJob(hostIp,port,offset,fileName,mHandler,callBack));
328 |
329 | }
330 |
331 | private boolean isFileReceiving(File file, long fileLen) {
332 |
333 | if (file.exists() && file.length() != fileLen && Constant.isReceiving) {
334 | return true;
335 | }
336 | return false;
337 | }
338 |
339 | /**
340 | * 创建一个socket客户端
341 | *
342 | * @param hostIp
343 | * 要连接的主机ip地址
344 | * @param port
345 | * 要连接的端口号
346 | */
347 | public void newClient(String hostIp, int port) {
348 | // new ClientThread(hostIp, port, mClientHandler, mCallBack).start();
349 | newClient(hostIp, port, "", 0, 0, mCallBack);
350 | }
351 |
352 | public void reconnect(String hostIp, int port) {
353 | if (isFileReceived(new File(Constant.RECEIVE_FILE_PATH),
354 | Constant.RECEIVE_FILE_LENGTH)) {
355 | Message.obtain(mHandler, C_MESSAGE,
356 | " 文件已经接收过,路径为: " + Constant.RECEIVE_FILE_PATH)
357 | .sendToTarget();
358 | } else {
359 |
360 | newClient(hostIp, port);
361 | }
362 | }
363 |
364 | private boolean isFileReceived(File file, long fileLen) {
365 |
366 | if (file.exists() && file.length() == fileLen) {
367 | return true;
368 | }
369 | return false;
370 | }
371 |
372 | public void onDestroy() {
373 | isReceiveBroadcast = false;
374 | isServerRunning = false;
375 | if (mReceiveMulticast != null && mReceiveAddress != null) {
376 | try {
377 | mReceiveMulticast.leaveGroup(mReceiveAddress);
378 | } catch (IOException e) {
379 | e.printStackTrace();
380 | }
381 | }
382 | }
383 |
384 | private void receiveBroadcast() {
385 | new Thread(new Runnable() {
386 | @Override
387 | public void run() {
388 | isReceiveBroadcast = true;
389 | try {
390 |
391 | while (isReceiveBroadcast) {
392 | mReceiveAddress = null;
393 |
394 | mReceiveAddress = InetAddress
395 | .getByName(Constant.multicastHost);
396 |
397 | if (!mReceiveAddress.isMulticastAddress()) {// 测试是否为多播地址
398 |
399 | DebugLogger.e("请使用多播地址");
400 |
401 | }
402 | mReceiveMulticast = new MulticastSocket(
403 | Constant.multicastPort);
404 | mReceiveMulticast.setReuseAddress(true);
405 | mReceiveMulticast.joinGroup(mReceiveAddress);
406 |
407 | DatagramPacket dp = new DatagramPacket(new byte[1024],
408 | 1024);
409 |
410 | mReceiveMulticast.receive(dp);
411 | String msg = new String(dp.getData()).trim();
412 | BroadcastBean broadcastBean = mGson.fromJson(msg, BroadcastBean.class);
413 | DebugLogger.e(msg);
414 | Message.obtain(mHandler, C_BROADCAST_MESSAGE, broadcastBean).sendToTarget();
415 | }
416 | } catch (IOException e) {
417 | e.printStackTrace();
418 | }
419 | }
420 | }).start();
421 |
422 | }
423 |
424 | // 将 int 转成字节
425 | public byte[] i2b(int i) {
426 | return new byte[]{(byte) ((i >> 24) & 0xFF), (byte) ((i >> 16) & 0xFF),
427 | (byte) ((i >> 8) & 0xFF), (byte) (i & 0xFF)};
428 | }
429 |
430 | // 输出byte长度和内容
431 | public void writeByte(byte[] bytes, OutputStream os) throws IOException {
432 | os.write(i2b(bytes.length)); // 输出文件名长度
433 | os.write(bytes); // 输出文件名
434 | }
435 |
436 | // 根据byte长度读取内容
437 | public String readByte(InputStream is) throws IOException {
438 | int name_len = readInteger(is);
439 | byte[] result = new byte[name_len];
440 | is.read(result);
441 | return new String(result);
442 | }
443 |
444 | // 读取一个数字
445 | public int readInteger(InputStream is) throws IOException {
446 | byte[] bytes = new byte[4];
447 | is.read(bytes);
448 | return b2i(bytes);
449 | }
450 |
451 | // 将字节转成 int。b 长度不得小于 4,且只会取前 4 位。
452 | public int b2i(byte[] b) {
453 | int value = 0;
454 | for (int i = 0; i < 4; i++) {
455 | int shift = (4 - 1 - i) * 8;
456 | value += (b[i] & 0x000000FF) << shift;
457 | }
458 | return value;
459 | }
460 |
461 | public void handleClientEx(Exception ex) {
462 | Constant.isReceiving = false;
463 | if (ex instanceof ConnectException) {
464 | DebugLogger.e("连接异常");
465 | } else if (ex instanceof SocketTimeoutException) {
466 | DebugLogger.e("连接超时,重连服务器...");
467 |
468 | }
469 | }
470 | }
471 |
--------------------------------------------------------------------------------
/app/src/main/java/com/accvmedia/mysocket/util/DebugLogger.java:
--------------------------------------------------------------------------------
1 | package com.accvmedia.mysocket.util;
2 |
3 | import android.util.Log;
4 |
5 | import com.accvmedia.mysocket.BuildConfig;
6 |
7 | /**
8 | * 日志工具类 在发布时不显示日志
9 | */
10 | public class DebugLogger {
11 |
12 | static String className;
13 | static String methodName;
14 | static int lineNumber;
15 |
16 | private DebugLogger(){
17 | /* Protect from instantiations */
18 | }
19 |
20 | public static boolean isDebuggable() {
21 | return BuildConfig.DEBUG;
22 | }
23 |
24 | private static String createLog(String log ) {
25 |
26 | StringBuffer buffer = new StringBuffer();
27 | buffer.append("[");
28 | buffer.append(methodName);
29 | buffer.append(":");
30 | buffer.append(lineNumber);
31 | buffer.append("]");
32 | buffer.append(log);
33 |
34 | return buffer.toString();
35 | }
36 |
37 | private static void getMethodNames(StackTraceElement[] sElements){
38 | className = sElements[1].getFileName();
39 | methodName = sElements[1].getMethodName();
40 | lineNumber = sElements[1].getLineNumber();
41 | }
42 |
43 | public static void e(String message){
44 | if (!isDebuggable())
45 | return;
46 |
47 | // Throwable instance must be created before any methods
48 | getMethodNames(new Throwable().getStackTrace());
49 | Log.e(className, createLog(message));
50 | }
51 |
52 | public static void i(String message){
53 | if (!isDebuggable())
54 | return;
55 |
56 | getMethodNames(new Throwable().getStackTrace());
57 | Log.i(className, createLog(message));
58 | }
59 |
60 | public static void d(String message){
61 | if (!isDebuggable())
62 | return;
63 |
64 | getMethodNames(new Throwable().getStackTrace());
65 | Log.d(className, createLog(message));
66 | }
67 |
68 | public static void v(String message){
69 | if (!isDebuggable())
70 | return;
71 |
72 | getMethodNames(new Throwable().getStackTrace());
73 | Log.v(className, createLog(message));
74 | }
75 |
76 | public static void w(String message){
77 | if (!isDebuggable())
78 | return;
79 |
80 | getMethodNames(new Throwable().getStackTrace());
81 | Log.w(className, createLog(message));
82 | }
83 |
84 | public static void wtf(String message){
85 | if (!isDebuggable())
86 | return;
87 |
88 | getMethodNames(new Throwable().getStackTrace());
89 | Log.wtf(className, createLog(message));
90 | }
91 |
92 | public static void e(String message, Throwable t) {
93 | if (!isDebuggable())
94 | return;
95 |
96 | // Throwable instance must be created before any methods
97 | getMethodNames(new Throwable().getStackTrace());
98 | Log.e(className, createLog(message),t);
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/app/src/main/java/com/accvmedia/mysocket/util/FileUtils.java:
--------------------------------------------------------------------------------
1 | package com.accvmedia.mysocket.util;
2 |
3 | import android.text.TextUtils;
4 |
5 | import java.io.BufferedInputStream;
6 | import java.io.BufferedOutputStream;
7 | import java.io.BufferedReader;
8 | import java.io.BufferedWriter;
9 | import java.io.File;
10 | import java.io.FileInputStream;
11 | import java.io.FileNotFoundException;
12 | import java.io.FileOutputStream;
13 | import java.io.FileReader;
14 | import java.io.FileWriter;
15 | import java.io.FilenameFilter;
16 | import java.io.IOException;
17 | import java.io.InputStream;
18 | import java.io.InputStreamReader;
19 | import java.io.OutputStream;
20 | import java.security.DigestInputStream;
21 | import java.security.MessageDigest;
22 | import java.security.NoSuchAlgorithmException;
23 | import java.util.ArrayList;
24 | import java.util.Collections;
25 | import java.util.List;
26 |
27 | /**
28 | *
29 | * author: Blankj
30 | * blog : http://blankj.com
31 | * time : 2016/8/11
32 | * desc : 文件相关工具类
33 | *
34 | */
35 | public class FileUtils {
36 |
37 | private FileUtils() {
38 | throw new UnsupportedOperationException("u can't instantiate me...");
39 | }
40 |
41 | /**
42 | * 根据文件路径获取文件
43 | *
44 | * @param filePath 文件路径
45 | * @return 文件
46 | */
47 | public static File getFileByPath(String filePath) {
48 | return TextUtils.isEmpty(filePath) ? null : new File(filePath);
49 | }
50 |
51 | /**
52 | * 判断文件是否存在
53 | *
54 | * @param filePath 文件路径
55 | * @return {@code true}: 存在
{@code false}: 不存在
56 | */
57 | public static boolean isFileExists(String filePath) {
58 | return isFileExists(getFileByPath(filePath));
59 | }
60 |
61 | /**
62 | * 判断文件是否存在
63 | *
64 | * @param file 文件
65 | * @return {@code true}: 存在
{@code false}: 不存在
66 | */
67 | public static boolean isFileExists(File file) {
68 | return file != null && file.exists();
69 | }
70 |
71 | /**
72 | * 重命名文件
73 | *
74 | * @param filePath 文件路径
75 | * @param newName 新名称
76 | * @return {@code true}: 重命名成功
{@code false}: 重命名失败
77 | */
78 | public static boolean rename(String filePath, String newName) {
79 | return rename(getFileByPath(filePath), newName);
80 | }
81 |
82 | /**
83 | * 重命名文件
84 | *
85 | * @param file 文件
86 | * @param newName 新名称
87 | * @return {@code true}: 重命名成功
{@code false}: 重命名失败
88 | */
89 | public static boolean rename(File file, String newName) {
90 | // 文件为空返回false
91 | if (file == null) return false;
92 | // 文件不存在返回false
93 | if (!file.exists()) return false;
94 | // 新的文件名为空返回false
95 | if (TextUtils.isEmpty(newName)) return false;
96 | // 如果文件名没有改变返回true
97 | if (newName.equals(file.getName())) return true;
98 | File newFile = new File(file.getParent() + File.separator + newName);
99 | // 如果重命名的文件已存在返回false
100 | return !newFile.exists()
101 | && file.renameTo(newFile);
102 | }
103 |
104 | /**
105 | * 判断是否是目录
106 | *
107 | * @param dirPath 目录路径
108 | * @return {@code true}: 是
{@code false}: 否
109 | */
110 | public static boolean isDir(String dirPath) {
111 | return isDir(getFileByPath(dirPath));
112 | }
113 |
114 | /**
115 | * 判断是否是目录
116 | *
117 | * @param file 文件
118 | * @return {@code true}: 是
{@code false}: 否
119 | */
120 | public static boolean isDir(File file) {
121 | return isFileExists(file) && file.isDirectory();
122 | }
123 |
124 | /**
125 | * 判断是否是文件
126 | *
127 | * @param filePath 文件路径
128 | * @return {@code true}: 是
{@code false}: 否
129 | */
130 | public static boolean isFile(String filePath) {
131 | return isFile(getFileByPath(filePath));
132 | }
133 |
134 | /**
135 | * 判断是否是文件
136 | *
137 | * @param file 文件
138 | * @return {@code true}: 是
{@code false}: 否
139 | */
140 | public static boolean isFile(File file) {
141 | return isFileExists(file) && file.isFile();
142 | }
143 |
144 | /**
145 | * 判断目录是否存在,不存在则判断是否创建成功
146 | *
147 | * @param dirPath 目录路径
148 | * @return {@code true}: 存在或创建成功
{@code false}: 不存在或创建失败
149 | */
150 | public static boolean createOrExistsDir(String dirPath) {
151 | return createOrExistsDir(getFileByPath(dirPath));
152 | }
153 |
154 | /**
155 | * 判断目录是否存在,不存在则判断是否创建成功
156 | *
157 | * @param file 文件
158 | * @return {@code true}: 存在或创建成功
{@code false}: 不存在或创建失败
159 | */
160 | public static boolean createOrExistsDir(File file) {
161 | // 如果存在,是目录则返回true,是文件则返回false,不存在则返回是否创建成功
162 | return file != null && (file.exists() ? file.isDirectory() : file.mkdirs());
163 | }
164 |
165 | /**
166 | * 判断文件是否存在,不存在则判断是否创建成功
167 | *
168 | * @param filePath 文件路径
169 | * @return {@code true}: 存在或创建成功
{@code false}: 不存在或创建失败
170 | */
171 | public static boolean createOrExistsFile(String filePath) {
172 | return createOrExistsFile(getFileByPath(filePath));
173 | }
174 |
175 | /**
176 | * 判断文件是否存在,不存在则判断是否创建成功
177 | *
178 | * @param file 文件
179 | * @return {@code true}: 存在或创建成功
{@code false}: 不存在或创建失败
180 | */
181 | public static boolean createOrExistsFile(File file) {
182 | if (file == null) return false;
183 | // 如果存在,是文件则返回true,是目录则返回false
184 | if (file.exists()) return file.isFile();
185 | if (!createOrExistsDir(file.getParentFile())) return false;
186 | try {
187 | return file.createNewFile();
188 | } catch (IOException e) {
189 | e.printStackTrace();
190 | return false;
191 | }
192 | }
193 |
194 | /**
195 | * 判断文件是否存在,存在则在创建之前删除
196 | *
197 | * @param filePath 文件路径
198 | * @return {@code true}: 创建成功
{@code false}: 创建失败
199 | */
200 | public static boolean createFileByDeleteOldFile(String filePath) {
201 | return createFileByDeleteOldFile(getFileByPath(filePath));
202 | }
203 |
204 | /**
205 | * 判断文件是否存在,存在则在创建之前删除
206 | *
207 | * @param file 文件
208 | * @return {@code true}: 创建成功
{@code false}: 创建失败
209 | */
210 | public static boolean createFileByDeleteOldFile(File file) {
211 | if (file == null) return false;
212 | // 文件存在并且删除失败返回false
213 | if (file.exists() && file.isFile() && !file.delete()) return false;
214 | // 创建目录失败返回false
215 | if (!createOrExistsDir(file.getParentFile())) return false;
216 | try {
217 | return file.createNewFile();
218 | } catch (IOException e) {
219 | e.printStackTrace();
220 | return false;
221 | }
222 | }
223 |
224 | /**
225 | * 复制或移动目录
226 | *
227 | * @param srcDirPath 源目录路径
228 | * @param destDirPath 目标目录路径
229 | * @param isMove 是否移动
230 | * @return {@code true}: 复制或移动成功
{@code false}: 复制或移动失败
231 | */
232 | private static boolean copyOrMoveDir(String srcDirPath, String destDirPath, boolean isMove) {
233 | return copyOrMoveDir(getFileByPath(srcDirPath), getFileByPath(destDirPath), isMove);
234 | }
235 |
236 | /**
237 | * 复制或移动目录
238 | *
239 | * @param srcDir 源目录
240 | * @param destDir 目标目录
241 | * @param isMove 是否移动
242 | * @return {@code true}: 复制或移动成功
{@code false}: 复制或移动失败
243 | */
244 | private static boolean copyOrMoveDir(File srcDir, File destDir, boolean isMove) {
245 | if (srcDir == null || destDir == null) return false;
246 | // 如果目标目录在源目录中则返回false,看不懂的话好好想想递归怎么结束
247 | // srcPath : F:\\MyGithub\\AndroidUtilCode\\utilcode\\src\\test\\res
248 | // destPath: F:\\MyGithub\\AndroidUtilCode\\utilcode\\src\\test\\res1
249 | // 为防止以上这种情况出现出现误判,须分别在后面加个路径分隔符
250 | String srcPath = srcDir.getPath() + File.separator;
251 | String destPath = destDir.getPath() + File.separator;
252 | if (destPath.contains(srcPath)) return false;
253 | // 源文件不存在或者不是目录则返回false
254 | if (!srcDir.exists() || !srcDir.isDirectory()) return false;
255 | // 目标目录不存在返回false
256 | if (!createOrExistsDir(destDir)) return false;
257 | File[] files = srcDir.listFiles();
258 | for (File file : files) {
259 | File oneDestFile = new File(destPath + file.getName());
260 | if (file.isFile()) {
261 | // 如果操作失败返回false
262 | if (!copyOrMoveFile(file, oneDestFile, isMove)) return false;
263 | } else if (file.isDirectory()) {
264 | // 如果操作失败返回false
265 | if (!copyOrMoveDir(file, oneDestFile, isMove)) return false;
266 | }
267 | }
268 | return !isMove || deleteDir(srcDir);
269 | }
270 |
271 | /**
272 | * 复制或移动文件
273 | *
274 | * @param srcFilePath 源文件路径
275 | * @param destFilePath 目标文件路径
276 | * @param isMove 是否移动
277 | * @return {@code true}: 复制或移动成功
{@code false}: 复制或移动失败
278 | */
279 | private static boolean copyOrMoveFile(String srcFilePath, String destFilePath, boolean isMove) {
280 | return copyOrMoveFile(getFileByPath(srcFilePath), getFileByPath(destFilePath), isMove);
281 | }
282 |
283 | /**
284 | * 复制或移动文件
285 | *
286 | * @param srcFile 源文件
287 | * @param destFile 目标文件
288 | * @param isMove 是否移动
289 | * @return {@code true}: 复制或移动成功
{@code false}: 复制或移动失败
290 | */
291 | private static boolean copyOrMoveFile(File srcFile, File destFile, boolean isMove) {
292 | if (srcFile == null || destFile == null) return false;
293 | // 源文件不存在或者不是文件则返回false
294 | if (!srcFile.exists() || !srcFile.isFile()) return false;
295 | // 目标文件存在且是文件则返回false
296 | if (destFile.exists() && destFile.isFile()) return false;
297 | // 目标目录不存在返回false
298 | if (!createOrExistsDir(destFile.getParentFile())) return false;
299 | try {
300 | return writeFileFromIS(destFile, new FileInputStream(srcFile), false)
301 | && !(isMove && !deleteFile(srcFile));
302 | } catch (FileNotFoundException e) {
303 | e.printStackTrace();
304 | return false;
305 | }
306 | }
307 |
308 | /**
309 | * 复制目录
310 | *
311 | * @param srcDirPath 源目录路径
312 | * @param destDirPath 目标目录路径
313 | * @return {@code true}: 复制成功
{@code false}: 复制失败
314 | */
315 | public static boolean copyDir(String srcDirPath, String destDirPath) {
316 | return copyDir(getFileByPath(srcDirPath), getFileByPath(destDirPath));
317 | }
318 |
319 | /**
320 | * 复制目录
321 | *
322 | * @param srcDir 源目录
323 | * @param destDir 目标目录
324 | * @return {@code true}: 复制成功
{@code false}: 复制失败
325 | */
326 | public static boolean copyDir(File srcDir, File destDir) {
327 | return copyOrMoveDir(srcDir, destDir, false);
328 | }
329 |
330 | /**
331 | * 复制文件
332 | *
333 | * @param srcFilePath 源文件路径
334 | * @param destFilePath 目标文件路径
335 | * @return {@code true}: 复制成功
{@code false}: 复制失败
336 | */
337 | public static boolean copyFile(String srcFilePath, String destFilePath) {
338 | return copyFile(getFileByPath(srcFilePath), getFileByPath(destFilePath));
339 | }
340 |
341 | /**
342 | * 复制文件
343 | *
344 | * @param srcFile 源文件
345 | * @param destFile 目标文件
346 | * @return {@code true}: 复制成功
{@code false}: 复制失败
347 | */
348 | public static boolean copyFile(File srcFile, File destFile) {
349 | return copyOrMoveFile(srcFile, destFile, false);
350 | }
351 |
352 | /**
353 | * 移动目录
354 | *
355 | * @param srcDirPath 源目录路径
356 | * @param destDirPath 目标目录路径
357 | * @return {@code true}: 移动成功
{@code false}: 移动失败
358 | */
359 | public static boolean moveDir(String srcDirPath, String destDirPath) {
360 | return moveDir(getFileByPath(srcDirPath), getFileByPath(destDirPath));
361 | }
362 |
363 | /**
364 | * 移动目录
365 | *
366 | * @param srcDir 源目录
367 | * @param destDir 目标目录
368 | * @return {@code true}: 移动成功
{@code false}: 移动失败
369 | */
370 | public static boolean moveDir(File srcDir, File destDir) {
371 | return copyOrMoveDir(srcDir, destDir, true);
372 | }
373 |
374 | /**
375 | * 移动文件
376 | *
377 | * @param srcFilePath 源文件路径
378 | * @param destFilePath 目标文件路径
379 | * @return {@code true}: 移动成功
{@code false}: 移动失败
380 | */
381 | public static boolean moveFile(String srcFilePath, String destFilePath) {
382 | return moveFile(getFileByPath(srcFilePath), getFileByPath(destFilePath));
383 | }
384 |
385 | /**
386 | * 移动文件
387 | *
388 | * @param srcFile 源文件
389 | * @param destFile 目标文件
390 | * @return {@code true}: 移动成功
{@code false}: 移动失败
391 | */
392 | public static boolean moveFile(File srcFile, File destFile) {
393 | return copyOrMoveFile(srcFile, destFile, true);
394 | }
395 |
396 | /**
397 | * 删除目录
398 | *
399 | * @param dirPath 目录路径
400 | * @return {@code true}: 删除成功
{@code false}: 删除失败
401 | */
402 | public static boolean deleteDir(String dirPath) {
403 | return deleteDir(getFileByPath(dirPath));
404 | }
405 |
406 | /**
407 | * 删除目录
408 | *
409 | * @param dir 目录
410 | * @return {@code true}: 删除成功
{@code false}: 删除失败
411 | */
412 | public static boolean deleteDir(File dir) {
413 | if (dir == null) return false;
414 | // 目录不存在返回true
415 | if (!dir.exists()) return true;
416 | // 不是目录返回false
417 | if (!dir.isDirectory()) return false;
418 | // 现在文件存在且是文件夹
419 | File[] files = dir.listFiles();
420 | if (files != null && files.length != 0) {
421 | for (File file : files) {
422 | if (file.isFile()) {
423 | if (!deleteFile(file)) return false;
424 | } else if (file.isDirectory()) {
425 | if (!deleteDir(file)) return false;
426 | }
427 | }
428 | }
429 | return dir.delete();
430 | }
431 |
432 | /**
433 | * 删除文件
434 | *
435 | * @param srcFilePath 文件路径
436 | * @return {@code true}: 删除成功
{@code false}: 删除失败
437 | */
438 | public static boolean deleteFile(String srcFilePath) {
439 | return deleteFile(getFileByPath(srcFilePath));
440 | }
441 |
442 | /**
443 | * 删除文件
444 | *
445 | * @param file 文件
446 | * @return {@code true}: 删除成功
{@code false}: 删除失败
447 | */
448 | public static boolean deleteFile(File file) {
449 | return file != null && (!file.exists() || file.isFile() && file.delete());
450 | }
451 |
452 | /**
453 | * 删除目录下的所有文件
454 | *
455 | * @param dirPath 目录路径
456 | * @return {@code true}: 删除成功
{@code false}: 删除失败
457 | */
458 | public static boolean deleteFilesInDir(String dirPath) {
459 | return deleteFilesInDir(getFileByPath(dirPath));
460 | }
461 |
462 | /**
463 | * 删除目录下的所有文件
464 | *
465 | * @param dir 目录
466 | * @return {@code true}: 删除成功
{@code false}: 删除失败
467 | */
468 | public static boolean deleteFilesInDir(File dir) {
469 | if (dir == null) return false;
470 | // 目录不存在返回true
471 | if (!dir.exists()) return true;
472 | // 不是目录返回false
473 | if (!dir.isDirectory()) return false;
474 | // 现在文件存在且是文件夹
475 | File[] files = dir.listFiles();
476 | if (files != null && files.length != 0) {
477 | for (File file : files) {
478 | if (file.isFile()) {
479 | if (!deleteFile(file)) return false;
480 | } else if (file.isDirectory()) {
481 | if (!deleteDir(file)) return false;
482 | }
483 | }
484 | }
485 | return true;
486 | }
487 |
488 | /**
489 | * 获取目录下所有文件
490 | *
491 | * @param dirPath 目录路径
492 | * @param isRecursive 是否递归进子目录
493 | * @return 文件链表
494 | */
495 | public static List listFilesInDir(String dirPath, boolean isRecursive) {
496 | return listFilesInDir(getFileByPath(dirPath), isRecursive);
497 | }
498 |
499 | /**
500 | * 获取目录下所有文件
501 | *
502 | * @param dir 目录
503 | * @param isRecursive 是否递归进子目录
504 | * @return 文件链表
505 | */
506 | public static List listFilesInDir(File dir, boolean isRecursive) {
507 | if (!isDir(dir)) return null;
508 | if (isRecursive) return listFilesInDir(dir);
509 | List list = new ArrayList<>();
510 | File[] files = dir.listFiles();
511 | if (files != null && files.length != 0) {
512 | Collections.addAll(list, files);
513 | }
514 | return list;
515 | }
516 |
517 | /**
518 | * 获取目录下所有文件包括子目录
519 | *
520 | * @param dirPath 目录路径
521 | * @return 文件链表
522 | */
523 | public static List listFilesInDir(String dirPath) {
524 | return listFilesInDir(getFileByPath(dirPath));
525 | }
526 |
527 | /**
528 | * 获取目录下所有文件包括子目录
529 | *
530 | * @param dir 目录
531 | * @return 文件链表
532 | */
533 | public static List listFilesInDir(File dir) {
534 | if (!isDir(dir)) return null;
535 | List list = new ArrayList<>();
536 | File[] files = dir.listFiles();
537 | if (files != null && files.length != 0) {
538 | for (File file : files) {
539 | list.add(file);
540 | if (file.isDirectory()) {
541 | list.addAll(listFilesInDir(file));
542 | }
543 | }
544 | }
545 | return list;
546 | }
547 |
548 | /**
549 | * 获取目录下所有后缀名为suffix的文件
550 | * 大小写忽略
551 | *
552 | * @param dirPath 目录路径
553 | * @param suffix 后缀名
554 | * @param isRecursive 是否递归进子目录
555 | * @return 文件链表
556 | */
557 | public static List listFilesInDirWithFilter(String dirPath, String suffix, boolean isRecursive) {
558 | return listFilesInDirWithFilter(getFileByPath(dirPath), suffix, isRecursive);
559 | }
560 |
561 | /**
562 | * 获取目录下所有后缀名为suffix的文件
563 | * 大小写忽略
564 | *
565 | * @param dir 目录
566 | * @param suffix 后缀名
567 | * @param isRecursive 是否递归进子目录
568 | * @return 文件链表
569 | */
570 | public static List listFilesInDirWithFilter(File dir, String suffix, boolean isRecursive) {
571 | if (isRecursive) return listFilesInDirWithFilter(dir, suffix);
572 | if (dir == null || !isDir(dir)) return null;
573 | List list = new ArrayList<>();
574 | File[] files = dir.listFiles();
575 | if (files != null && files.length != 0) {
576 | for (File file : files) {
577 | if (file.getName().toUpperCase().endsWith(suffix.toUpperCase())) {
578 | list.add(file);
579 | }
580 | }
581 | }
582 | return list;
583 | }
584 |
585 | /**
586 | * 获取目录下所有后缀名为suffix的文件包括子目录
587 | * 大小写忽略
588 | *
589 | * @param dirPath 目录路径
590 | * @param suffix 后缀名
591 | * @return 文件链表
592 | */
593 | public static List listFilesInDirWithFilter(String dirPath, String suffix) {
594 | return listFilesInDirWithFilter(getFileByPath(dirPath), suffix);
595 | }
596 |
597 | /**
598 | * 获取目录下所有后缀名为suffix的文件包括子目录
599 | * 大小写忽略
600 | *
601 | * @param dir 目录
602 | * @param suffix 后缀名
603 | * @return 文件链表
604 | */
605 | public static List listFilesInDirWithFilter(File dir, String suffix) {
606 | if (dir == null || !isDir(dir)) return null;
607 | List list = new ArrayList<>();
608 | File[] files = dir.listFiles();
609 | if (files != null && files.length != 0) {
610 | for (File file : files) {
611 | if (file.getName().toUpperCase().endsWith(suffix.toUpperCase())) {
612 | list.add(file);
613 | }
614 | if (file.isDirectory()) {
615 | list.addAll(listFilesInDirWithFilter(file, suffix));
616 | }
617 | }
618 | }
619 | return list;
620 | }
621 |
622 | /**
623 | * 获取目录下所有符合filter的文件
624 | *
625 | * @param dirPath 目录路径
626 | * @param filter 过滤器
627 | * @param isRecursive 是否递归进子目录
628 | * @return 文件链表
629 | */
630 | public static List listFilesInDirWithFilter(String dirPath, FilenameFilter filter, boolean isRecursive) {
631 | return listFilesInDirWithFilter(getFileByPath(dirPath), filter, isRecursive);
632 | }
633 |
634 | /**
635 | * 获取目录下所有符合filter的文件
636 | *
637 | * @param dir 目录
638 | * @param filter 过滤器
639 | * @param isRecursive 是否递归进子目录
640 | * @return 文件链表
641 | */
642 | public static List listFilesInDirWithFilter(File dir, FilenameFilter filter, boolean isRecursive) {
643 | if (isRecursive) return listFilesInDirWithFilter(dir, filter);
644 | if (dir == null || !isDir(dir)) return null;
645 | List list = new ArrayList<>();
646 | File[] files = dir.listFiles();
647 | if (files != null && files.length != 0) {
648 | for (File file : files) {
649 | if (filter.accept(file.getParentFile(), file.getName())) {
650 | list.add(file);
651 | }
652 | }
653 | }
654 | return list;
655 | }
656 |
657 | /**
658 | * 获取目录下所有符合filter的文件包括子目录
659 | *
660 | * @param dirPath 目录路径
661 | * @param filter 过滤器
662 | * @return 文件链表
663 | */
664 | public static List listFilesInDirWithFilter(String dirPath, FilenameFilter filter) {
665 | return listFilesInDirWithFilter(getFileByPath(dirPath), filter);
666 | }
667 |
668 | /**
669 | * 获取目录下所有符合filter的文件包括子目录
670 | *
671 | * @param dir 目录
672 | * @param filter 过滤器
673 | * @return 文件链表
674 | */
675 | public static List listFilesInDirWithFilter(File dir, FilenameFilter filter) {
676 | if (dir == null || !isDir(dir)) return null;
677 | List list = new ArrayList<>();
678 | File[] files = dir.listFiles();
679 | if (files != null && files.length != 0) {
680 | for (File file : files) {
681 | if (filter.accept(file.getParentFile(), file.getName())) {
682 | list.add(file);
683 | }
684 | if (file.isDirectory()) {
685 | list.addAll(listFilesInDirWithFilter(file, filter));
686 | }
687 | }
688 | }
689 | return list;
690 | }
691 |
692 | /**
693 | * 获取目录下指定文件名的文件包括子目录
694 | * 大小写忽略
695 | *
696 | * @param dirPath 目录路径
697 | * @param fileName 文件名
698 | * @return 文件链表
699 | */
700 | public static List searchFileInDir(String dirPath, String fileName) {
701 | return searchFileInDir(getFileByPath(dirPath), fileName);
702 | }
703 |
704 | /**
705 | * 获取目录下指定文件名的文件包括子目录
706 | * 大小写忽略
707 | *
708 | * @param dir 目录
709 | * @param fileName 文件名
710 | * @return 文件链表
711 | */
712 | public static List searchFileInDir(File dir, String fileName) {
713 | if (dir == null || !isDir(dir)) return null;
714 | List list = new ArrayList<>();
715 | File[] files = dir.listFiles();
716 | if (files != null && files.length != 0) {
717 | for (File file : files) {
718 | if (file.getName().toUpperCase().equals(fileName.toUpperCase())) {
719 | list.add(file);
720 | }
721 | if (file.isDirectory()) {
722 | list.addAll(searchFileInDir(file, fileName));
723 | }
724 | }
725 | }
726 | return list;
727 | }
728 |
729 | /**
730 | * 将输入流写入文件
731 | *
732 | * @param filePath 路径
733 | * @param is 输入流
734 | * @param append 是否追加在文件末
735 | * @return {@code true}: 写入成功
{@code false}: 写入失败
736 | */
737 | public static boolean writeFileFromIS(String filePath, InputStream is, boolean append) {
738 | return writeFileFromIS(getFileByPath(filePath), is, append);
739 | }
740 |
741 | /**
742 | * 将输入流写入文件
743 | *
744 | * @param file 文件
745 | * @param is 输入流
746 | * @param append 是否追加在文件末
747 | * @return {@code true}: 写入成功
{@code false}: 写入失败
748 | */
749 | public static boolean writeFileFromIS(File file, InputStream is, boolean append) {
750 | if (file == null || is == null) return false;
751 | if (!createOrExistsFile(file)) return false;
752 | OutputStream os = null;
753 | try {
754 | os = new BufferedOutputStream(new FileOutputStream(file, append));
755 | byte data[] = new byte[1024];
756 | int len;
757 | while ((len = is.read(data, 0, 1024)) != -1) {
758 | os.write(data, 0, len);
759 | }
760 | return true;
761 | } catch (IOException e) {
762 | e.printStackTrace();
763 | return false;
764 | } finally {
765 | try {
766 | is.close();
767 | os.close();
768 | } catch (IOException e) {
769 | e.printStackTrace();
770 | }
771 | }
772 | }
773 |
774 | /**
775 | * 将字符串写入文件
776 | *
777 | * @param filePath 文件路径
778 | * @param content 写入内容
779 | * @param append 是否追加在文件末
780 | * @return {@code true}: 写入成功
{@code false}: 写入失败
781 | */
782 | public static boolean writeFileFromString(String filePath, String content, boolean append) {
783 | return writeFileFromString(getFileByPath(filePath), content, append);
784 | }
785 |
786 | /**
787 | * 将字符串写入文件
788 | *
789 | * @param file 文件
790 | * @param content 写入内容
791 | * @param append 是否追加在文件末
792 | * @return {@code true}: 写入成功
{@code false}: 写入失败
793 | */
794 | public static boolean writeFileFromString(File file, String content, boolean append) {
795 | if (file == null || content == null) return false;
796 | if (!createOrExistsFile(file)) return false;
797 | BufferedWriter bw = null;
798 | try {
799 | bw = new BufferedWriter(new FileWriter(file, append));
800 | bw.write(content);
801 | return true;
802 | } catch (IOException e) {
803 | e.printStackTrace();
804 | return false;
805 | } finally {
806 | try {
807 | bw.close();
808 | } catch (IOException e) {
809 | e.printStackTrace();
810 | }
811 | }
812 | }
813 |
814 | /**
815 | * 指定编码按行读取文件到List
816 | *
817 | * @param filePath 文件路径
818 | * @param charsetName 编码格式
819 | * @return 文件行链表
820 | */
821 | public static List readFile2List(String filePath, String charsetName) {
822 | return readFile2List(getFileByPath(filePath), charsetName);
823 | }
824 |
825 | /**
826 | * 指定编码按行读取文件到List
827 | *
828 | * @param file 文件
829 | * @param charsetName 编码格式
830 | * @return 文件行链表
831 | */
832 | public static List readFile2List(File file, String charsetName) {
833 | return readFile2List(file, 0, 0x7FFFFFFF, charsetName);
834 | }
835 |
836 | /**
837 | * 指定编码按行读取文件到List
838 | *
839 | * @param filePath 文件路径
840 | * @param st 需要读取的开始行数
841 | * @param end 需要读取的结束行数
842 | * @param charsetName 编码格式
843 | * @return 包含制定行的list
844 | */
845 | public static List readFile2List(String filePath, int st, int end, String
846 | charsetName) {
847 | return readFile2List(getFileByPath(filePath), st, end, charsetName);
848 | }
849 |
850 | /**
851 | * 指定编码按行读取文件到List
852 | *
853 | * @param file 文件
854 | * @param st 需要读取的开始行数
855 | * @param end 需要读取的结束行数
856 | * @param charsetName 编码格式
857 | * @return 包含从start行到end行的list
858 | */
859 | public static List readFile2List(File file, int st, int end, String charsetName) {
860 | if (file == null) return null;
861 | if (st > end) return null;
862 | BufferedReader reader = null;
863 | try {
864 | String line;
865 | int curLine = 1;
866 | List list = new ArrayList<>();
867 | if (TextUtils.isEmpty(charsetName)) {
868 | reader = new BufferedReader(new FileReader(file));
869 | } else {
870 | reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), charsetName));
871 | }
872 | while ((line = reader.readLine()) != null) {
873 | if (curLine > end) break;
874 | if (st <= curLine && curLine <= end) list.add(line);
875 | ++curLine;
876 | }
877 | return list;
878 | } catch (IOException e) {
879 | e.printStackTrace();
880 | return null;
881 | } finally {
882 | try {
883 | reader.close();
884 | } catch (IOException e) {
885 | e.printStackTrace();
886 | }
887 | }
888 | }
889 |
890 | /**
891 | * 指定编码按行读取文件到字符串中
892 | *
893 | * @param filePath 文件路径
894 | * @param charsetName 编码格式
895 | * @return 字符串
896 | */
897 | public static String readFile2String(String filePath, String charsetName) {
898 | return readFile2String(getFileByPath(filePath), charsetName);
899 | }
900 |
901 | /**
902 | * 指定编码按行读取文件到字符串中
903 | *
904 | * @param file 文件
905 | * @param charsetName 编码格式
906 | * @return 字符串
907 | */
908 | public static String readFile2String(File file, String charsetName) {
909 | if (file == null) return null;
910 | BufferedReader reader = null;
911 | try {
912 | StringBuilder sb = new StringBuilder();
913 | if (TextUtils.isEmpty(charsetName)) {
914 | reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
915 | } else {
916 | reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), charsetName));
917 | }
918 | String line;
919 | while ((line = reader.readLine()) != null) {
920 | sb.append(line).append("\r\n");// windows系统换行为\r\n,Linux为\n
921 | }
922 | // 要去除最后的换行符
923 | return sb.delete(sb.length() - 2, sb.length()).toString();
924 | } catch (IOException e) {
925 | e.printStackTrace();
926 | return null;
927 | } finally {
928 | try {
929 | reader.close();
930 | } catch (IOException e) {
931 | e.printStackTrace();
932 | }
933 | }
934 | }
935 |
936 | /**
937 | * 读取文件到字符数组中
938 | *
939 | * @param filePath 文件路径
940 | * @return 字符数组
941 | */
942 | // public static byte[] readFile2Bytes(String filePath) {
943 | //// return readFile2Bytes(getFileByPath(filePath));
944 | // return readFile2Bytes(getFileByPath(filePath));
945 | // }
946 |
947 | /**
948 | * 读取文件到字符数组中
949 | *
950 | * @param file 文件
951 | * @return 字符数组
952 | */
953 | // public static byte[] readFile2Bytes(File file) {
954 | // if (file == null) return null;
955 | // try {
956 | // return ConvertUtils.inputStream2Bytes(new FileInputStream(file));
957 | // } catch (FileNotFoundException e) {
958 | // e.printStackTrace();
959 | // return null;
960 | // }
961 | // }
962 |
963 | /**
964 | * 简单获取文件编码格式
965 | *
966 | * @param filePath 文件路径
967 | * @return 文件编码
968 | */
969 | public static String getFileCharsetSimple(String filePath) {
970 | return getFileCharsetSimple(getFileByPath(filePath));
971 | }
972 |
973 | /**
974 | * 简单获取文件编码格式
975 | *
976 | * @param file 文件
977 | * @return 文件编码
978 | */
979 | public static String getFileCharsetSimple(File file) {
980 | int p = 0;
981 | InputStream is = null;
982 | try {
983 | is = new BufferedInputStream(new FileInputStream(file));
984 | p = (is.read() << 8) + is.read();
985 | } catch (IOException e) {
986 | e.printStackTrace();
987 | } finally {
988 | try {
989 | is.close();
990 | } catch (IOException e) {
991 | e.printStackTrace();
992 | }
993 | }
994 | switch (p) {
995 | case 0xefbb:
996 | return "UTF-8";
997 | case 0xfffe:
998 | return "Unicode";
999 | case 0xfeff:
1000 | return "UTF-16BE";
1001 | default:
1002 | return "GBK";
1003 | }
1004 | }
1005 |
1006 | /**
1007 | * 获取文件行数
1008 | *
1009 | * @param filePath 文件路径
1010 | * @return 文件行数
1011 | */
1012 | public static int getFileLines(String filePath) {
1013 | return getFileLines(getFileByPath(filePath));
1014 | }
1015 |
1016 | /**
1017 | * 获取文件行数
1018 | *
1019 | * @param file 文件
1020 | * @return 文件行数
1021 | */
1022 | public static int getFileLines(File file) {
1023 | int count = 1;
1024 | InputStream is = null;
1025 | try {
1026 | is = new BufferedInputStream(new FileInputStream(file));
1027 | byte[] buffer = new byte[1024];
1028 | int readChars;
1029 | while ((readChars = is.read(buffer, 0, 1024)) != -1) {
1030 | for (int i = 0; i < readChars; ++i) {
1031 | if (buffer[i] == '\n') ++count;
1032 | }
1033 | }
1034 | } catch (IOException e) {
1035 | e.printStackTrace();
1036 | } finally {
1037 | try {
1038 | is.close();
1039 | } catch (IOException e) {
1040 | e.printStackTrace();
1041 | }
1042 | }
1043 | return count;
1044 | }
1045 |
1046 | /**
1047 | * 获取目录大小
1048 | *
1049 | * @param dirPath 目录路径
1050 | * @return 文件大小
1051 | */
1052 | public static String getDirSize(String dirPath) {
1053 | // return getDirSize(getFileByPath(dirPath));
1054 | return "";
1055 | }
1056 |
1057 | /**
1058 | * 获取目录大小
1059 | *
1060 | * @param dir 目录
1061 | * @return 文件大小
1062 | */
1063 | // public static String getDirSize(File dir) {
1064 | // long len = getDirLength(dir);
1065 | // return len == -1 ? "" : ConvertUtils.byte2FitMemorySize(len);
1066 | // }
1067 |
1068 | /**
1069 | * 获取文件大小
1070 | *
1071 | * @param filePath 文件路径
1072 | * @return 文件大小
1073 | */
1074 | public static String getFileSize(String filePath) {
1075 | return getFileSize(getFileByPath(filePath));
1076 | }
1077 |
1078 | /**
1079 | * 获取文件大小
1080 | *
1081 | * @param file 文件
1082 | * @return 文件大小
1083 | */
1084 | public static String getFileSize(File file) {
1085 | long len = getFileLength(file);
1086 | return len == -1 ? "" : "w";
1087 | // return len == -1 ? "" : ConvertUtils.byte2FitMemorySize(len);
1088 | }
1089 |
1090 | /**
1091 | * 获取目录长度
1092 | *
1093 | * @param dirPath 目录路径
1094 | * @return 文件大小
1095 | */
1096 | public static long getDirLength(String dirPath) {
1097 | return getDirLength(getFileByPath(dirPath));
1098 | }
1099 |
1100 | /**
1101 | * 获取目录长度
1102 | *
1103 | * @param dir 目录
1104 | * @return 文件大小
1105 | */
1106 | public static long getDirLength(File dir) {
1107 | if (!isDir(dir)) return -1;
1108 | long len = 0;
1109 | File[] files = dir.listFiles();
1110 | if (files != null && files.length != 0) {
1111 | for (File file : files) {
1112 | if (file.isDirectory()) {
1113 | len += getDirLength(file);
1114 | } else {
1115 | len += file.length();
1116 | }
1117 | }
1118 | }
1119 | return len;
1120 | }
1121 |
1122 | /**
1123 | * 获取文件长度
1124 | *
1125 | * @param filePath 文件路径
1126 | * @return 文件大小
1127 | */
1128 | public static long getFileLength(String filePath) {
1129 | return getFileLength(getFileByPath(filePath));
1130 | }
1131 |
1132 | /**
1133 | * 获取文件长度
1134 | *
1135 | * @param file 文件
1136 | * @return 文件大小
1137 | */
1138 | public static long getFileLength(File file) {
1139 | if (!isFile(file)) return -1;
1140 | return file.length();
1141 | }
1142 |
1143 | /**
1144 | * 获取文件的MD5校验码
1145 | *
1146 | * @param filePath 文件路径
1147 | * @return 文件的MD5校验码
1148 | */
1149 | public static String getFileMD5ToString(String filePath) {
1150 | File file = TextUtils.isEmpty(filePath) ? null : new File(filePath);
1151 | return getFileMD5ToString(file);
1152 | }
1153 |
1154 | /**
1155 | * 获取文件的MD5校验码
1156 | *
1157 | * @param filePath 文件路径
1158 | * @return 文件的MD5校验码
1159 | */
1160 | public static byte[] getFileMD5(String filePath) {
1161 | File file = TextUtils.isEmpty(filePath) ? null : new File(filePath);
1162 | return getFileMD5(file);
1163 | }
1164 |
1165 | /**
1166 | * 获取文件的MD5校验码
1167 | *
1168 | * @param file 文件
1169 | * @return 文件的MD5校验码
1170 | */
1171 | public static String getFileMD5ToString(File file) {
1172 | // return ConvertUtils.bytes2HexString(getFileMD5(file));
1173 | return "aa";
1174 | }
1175 |
1176 | /**
1177 | * 获取文件的MD5校验码
1178 | *
1179 | * @param file 文件
1180 | * @return 文件的MD5校验码
1181 | */
1182 | public static byte[] getFileMD5(File file) {
1183 | if (file == null) return null;
1184 | DigestInputStream dis = null;
1185 | try {
1186 | FileInputStream fis = new FileInputStream(file);
1187 | MessageDigest md = MessageDigest.getInstance("MD5");
1188 | dis = new DigestInputStream(fis, md);
1189 | byte[] buffer = new byte[1024 * 256];
1190 | while (dis.read(buffer) > 0) ;
1191 | md = dis.getMessageDigest();
1192 | return md.digest();
1193 | } catch (NoSuchAlgorithmException | IOException e) {
1194 | e.printStackTrace();
1195 | } finally {
1196 | try {
1197 | dis.close();
1198 | } catch (IOException e) {
1199 | e.printStackTrace();
1200 | }
1201 | }
1202 | return null;
1203 | }
1204 |
1205 | /**
1206 | * 获取全路径中的最长目录
1207 | *
1208 | * @param file 文件
1209 | * @return filePath最长目录
1210 | */
1211 | public static String getDirName(File file) {
1212 | if (file == null) return null;
1213 | return getDirName(file.getPath());
1214 | }
1215 |
1216 | /**
1217 | * 获取全路径中的最长目录
1218 | *
1219 | * @param filePath 文件路径
1220 | * @return filePath最长目录
1221 | */
1222 | public static String getDirName(String filePath) {
1223 | if (TextUtils.isEmpty(filePath)) return filePath;
1224 | int lastSep = filePath.lastIndexOf(File.separator);
1225 | return lastSep == -1 ? "" : filePath.substring(0, lastSep + 1);
1226 | }
1227 |
1228 | /**
1229 | * 获取全路径中的文件名
1230 | *
1231 | * @param file 文件
1232 | * @return 文件名
1233 | */
1234 | public static String getFileName(File file) {
1235 | if (file == null) return null;
1236 | return getFileName(file.getPath());
1237 | }
1238 |
1239 | /**
1240 | * 获取全路径中的文件名
1241 | *
1242 | * @param filePath 文件路径
1243 | * @return 文件名
1244 | */
1245 | public static String getFileName(String filePath) {
1246 | if (TextUtils.isEmpty(filePath)) return filePath;
1247 | int lastSep = filePath.lastIndexOf(File.separator);
1248 | return lastSep == -1 ? filePath : filePath.substring(lastSep + 1);
1249 | }
1250 |
1251 | /**
1252 | * 获取全路径中的不带拓展名的文件名
1253 | *
1254 | * @param file 文件
1255 | * @return 不带拓展名的文件名
1256 | */
1257 | public static String getFileNameNoExtension(File file) {
1258 | if (file == null) return null;
1259 | return getFileNameNoExtension(file.getPath());
1260 | }
1261 |
1262 | /**
1263 | * 获取全路径中的不带拓展名的文件名
1264 | *
1265 | * @param filePath 文件路径
1266 | * @return 不带拓展名的文件名
1267 | */
1268 | public static String getFileNameNoExtension(String filePath) {
1269 | if (TextUtils.isEmpty(filePath)) return filePath;
1270 | int lastPoi = filePath.lastIndexOf('.');
1271 | int lastSep = filePath.lastIndexOf(File.separator);
1272 | if (lastSep == -1) {
1273 | return (lastPoi == -1 ? filePath : filePath.substring(0, lastPoi));
1274 | }
1275 | if (lastPoi == -1 || lastSep > lastPoi) {
1276 | return filePath.substring(lastSep + 1);
1277 | }
1278 | return filePath.substring(lastSep + 1, lastPoi);
1279 | }
1280 |
1281 | /**
1282 | * 获取全路径中的文件拓展名
1283 | *
1284 | * @param file 文件
1285 | * @return 文件拓展名
1286 | */
1287 | public static String getFileExtension(File file) {
1288 | if (file == null) return null;
1289 | return getFileExtension(file.getPath());
1290 | }
1291 |
1292 | /**
1293 | * 获取全路径中的文件拓展名
1294 | *
1295 | * @param filePath 文件路径
1296 | * @return 文件拓展名
1297 | */
1298 | public static String getFileExtension(String filePath) {
1299 | if (TextUtils.isEmpty(filePath)) return filePath;
1300 | int lastPoi = filePath.lastIndexOf('.');
1301 | int lastSep = filePath.lastIndexOf(File.separator);
1302 | if (lastPoi == -1 || lastSep >= lastPoi) return "";
1303 | return filePath.substring(lastPoi + 1);
1304 | }
1305 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/accvmedia/mysocket/util/WifiUtils.java:
--------------------------------------------------------------------------------
1 | package com.accvmedia.mysocket.util;
2 |
3 | import android.content.Context;
4 | import android.net.DhcpInfo;
5 | import android.net.wifi.ScanResult;
6 | import android.net.wifi.WifiConfiguration;
7 | import android.net.wifi.WifiInfo;
8 | import android.net.wifi.WifiManager;
9 | import android.util.Log;
10 |
11 | import java.io.BufferedReader;
12 | import java.io.InputStreamReader;
13 | import java.lang.reflect.Method;
14 | import java.net.InetAddress;
15 | import java.net.UnknownHostException;
16 | import java.util.List;
17 | import java.util.regex.Matcher;
18 | import java.util.regex.Pattern;
19 |
20 | /**
21 | * Created by dempseyZheng on 2016/12/23
22 | */
23 |
24 | public class WifiUtils {
25 | public static final int WIFICIPHER_NOPASS = 1;
26 | public static final int WIFICIPHER_WEP = 2;
27 | public static final int WIFICIPHER_WPA = 3;
28 | private static final String TAG = "WifiUtils";
29 | // 定义WifiManager对象
30 | private WifiManager mWifiManager;
31 | // 定义WifiInfo对象
32 | private WifiInfo mWifiInfo;
33 | // 扫描出的网络连接列表
34 | private List mWifiList;
35 | // 网络连接列表
36 | private List mWifiConfiguration;
37 | // 定义一个WifiLock
38 | WifiManager.WifiLock mWifiLock;
39 | private static WifiUtils wifiUtils = null;
40 |
41 | static {
42 | wifiUtils = new WifiUtils();
43 | }
44 |
45 | public static WifiUtils getInstance() {
46 | return wifiUtils;
47 |
48 | }
49 |
50 | // 构造器
51 | public void init(Context context) {
52 | // 取得WifiManager对象
53 | mWifiManager = (WifiManager) context
54 | .getSystemService(Context.WIFI_SERVICE);
55 | // 取得WifiInfo对象
56 | mWifiInfo = mWifiManager.getConnectionInfo();
57 | }
58 |
59 | private WifiUtils() {
60 | }
61 |
62 |
63 | // 打开WIFI
64 | public void openWifi() {
65 | if (!mWifiManager.isWifiEnabled()) {
66 | mWifiManager.setWifiEnabled(true);
67 | }
68 | }
69 |
70 | // 断开当前网络
71 | public void disconnectWifi() {
72 | if (!mWifiManager.isWifiEnabled()) {
73 | mWifiManager.disconnect();
74 | }
75 | }
76 |
77 | // 关闭WIFI
78 | public void closeWifi() {
79 | if (mWifiManager.isWifiEnabled()) {
80 | mWifiManager.setWifiEnabled(false);
81 | }
82 | }
83 |
84 | // 检查当前WIFI状态
85 | public int checkState() {
86 | return mWifiManager.getWifiState();
87 | }
88 |
89 | // 锁定WifiLock
90 | public void acquireWifiLock() {
91 | mWifiLock.acquire();
92 | }
93 |
94 | // 解锁WifiLock
95 | public void releaseWifiLock() {
96 | // 判断时候锁定
97 | if (mWifiLock.isHeld()) {
98 | mWifiLock.acquire();
99 | }
100 | }
101 |
102 | // 创建一个WifiLock
103 | public void creatWifiLock() {
104 | mWifiLock = mWifiManager.createWifiLock("Test");
105 | }
106 |
107 | // 得到配置好的网络
108 | public List getConfiguration() {
109 | return mWifiConfiguration;
110 | }
111 |
112 | // 指定配置好的网络进行连接
113 | public void connectConfiguration(int index) {
114 | // 索引大于配置好的网络索引返回
115 | if (index > mWifiConfiguration.size()) {
116 | return;
117 | }
118 | // 连接配置好的指定ID的网络
119 | mWifiManager.enableNetwork(mWifiConfiguration.get(index).networkId,
120 | true);
121 | }
122 |
123 | public void startScan() {
124 | mWifiManager.startScan();
125 | // 得到扫描结果
126 | mWifiList = mWifiManager.getScanResults();
127 | // 得到配置好的网络连接
128 | mWifiConfiguration = mWifiManager.getConfiguredNetworks();
129 | }
130 |
131 | // 得到网络列表
132 | public List getWifiList() {
133 | return mWifiList;
134 | }
135 |
136 | // 查看扫描结果
137 | public StringBuilder lookUpScan() {
138 | StringBuilder stringBuilder = new StringBuilder();
139 | for (int i = 0; i < mWifiList.size(); i++) {
140 | stringBuilder.append("Index_" + Integer.valueOf(i + 1)
141 | .toString()
142 | + ":");
143 | // 将ScanResult信息转换成一个字符串包
144 | // 其中把包括:BSSID、SSID、capabilities、frequency、level
145 | stringBuilder.append((mWifiList.get(i)).toString());
146 | stringBuilder.append("/n");
147 | }
148 | return stringBuilder;
149 | }
150 |
151 | // 得到MAC地址
152 | public String getMacAddress() {
153 | if (mWifiManager!=null)
154 | mWifiInfo = mWifiManager.getConnectionInfo();
155 | return (mWifiInfo == null)
156 | ? "NULL"
157 | : mWifiInfo.getMacAddress();
158 | }
159 |
160 | // 得到接入点的BSSID
161 | public String getBSSID() {
162 | return (mWifiInfo == null)
163 | ? "NULL"
164 | : mWifiInfo.getBSSID();
165 | }
166 |
167 | // 得到IP地址
168 | public int getIPAddress() {
169 | if (mWifiManager!=null)
170 | mWifiInfo = mWifiManager.getConnectionInfo();
171 | return (mWifiInfo == null)
172 | ? 0
173 | : mWifiInfo.getIpAddress();
174 | }
175 | private String intToIp(int i) {
176 |
177 | return (i & 0xFF) + "." +
178 | ((i >> 8) & 0xFF) + "." +
179 | ((i >> 16) & 0xFF) + "." +
180 | (i >> 24 & 0xFF);
181 | }
182 |
183 | public String getParsedIp() {
184 | return intToIp(getIPAddress());
185 | }
186 | // 得到连接的ID
187 | public int getNetworkId() {
188 | return (mWifiInfo == null)
189 | ? 0
190 | : mWifiInfo.getNetworkId();
191 | }
192 |
193 | // 得到WifiInfo的所有信息包
194 | public String getWifiInfo() {
195 | return (mWifiInfo == null)
196 | ? "NULL"
197 | : mWifiInfo.toString();
198 | }
199 |
200 | // 添加一个网络并连接
201 | public void addNetwork(WifiConfiguration wcg) {
202 | int wcgID = mWifiManager.addNetwork(wcg);
203 | boolean b = mWifiManager.enableNetwork(wcgID, true);
204 | System.out.println("netId--" + wcgID);
205 | System.out.println("是否成功--" + b);
206 | }
207 |
208 | // 断开指定ID的网络
209 | public void disconnectWifi(int netId) {
210 | mWifiManager.disableNetwork(netId);
211 | mWifiManager.disconnect();
212 | }
213 |
214 | public WifiConfiguration CreateWifiInfo(String SSID, String Password,
215 | int Type)
216 | {
217 | if (Password.length()<8){
218 | throw new RuntimeException("password length must not be less than 8");
219 | }
220 | WifiConfiguration config = new WifiConfiguration();
221 | config.allowedAuthAlgorithms.clear();
222 | config.allowedGroupCiphers.clear();
223 | config.allowedKeyManagement.clear();
224 | config.allowedPairwiseCiphers.clear();
225 | config.allowedProtocols.clear();
226 | // config.SSID = "\"" + SSID + "\"";
227 | config.SSID = SSID ;
228 |
229 | WifiConfiguration tempConfig = this.IsExsits(SSID);
230 | if (tempConfig != null) {
231 | mWifiManager.removeNetwork(tempConfig.networkId);
232 | }
233 |
234 | if (Type == WIFICIPHER_NOPASS) // WIFICIPHER_NOPASS
235 | {
236 | config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
237 | }
238 | if (Type == WIFICIPHER_WEP) // WIFICIPHER_WEP
239 | {
240 | config.hiddenSSID = true;
241 | // config.wepKeys[0] = "\"" + Password + "\"";
242 | config.wepKeys[0] = Password ;
243 | config.allowedAuthAlgorithms
244 | .set(WifiConfiguration.AuthAlgorithm.SHARED);
245 | config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
246 | config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
247 | config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
248 | config.allowedGroupCiphers
249 | .set(WifiConfiguration.GroupCipher.WEP104);
250 | config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
251 | config.wepTxKeyIndex = 0;
252 | }
253 | if (Type == WIFICIPHER_WPA) // WIFICIPHER_WPA
254 | {
255 | // config.preSharedKey = "\"" + Password + "\"";
256 | config.preSharedKey = Password ;
257 | config.hiddenSSID = true;
258 | config.allowedAuthAlgorithms
259 | .set(WifiConfiguration.AuthAlgorithm.OPEN);
260 | config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
261 | config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
262 | config.allowedPairwiseCiphers
263 | .set(WifiConfiguration.PairwiseCipher.TKIP);
264 | config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
265 | config.allowedPairwiseCiphers
266 | .set(WifiConfiguration.PairwiseCipher.CCMP);
267 | config.status = WifiConfiguration.Status.ENABLED;
268 | }
269 | return config;
270 | }
271 |
272 | private WifiConfiguration IsExsits(String SSID) {
273 | List existingConfigs = mWifiManager
274 | .getConfiguredNetworks();
275 | if (existingConfigs!=null&&existingConfigs.size()>0) {
276 | for (WifiConfiguration existingConfig : existingConfigs) {
277 | // if (existingConfig.SSID.equals("\"" + SSID + "\"")) {
278 | if (existingConfig.SSID.equals( SSID )) {
279 | return existingConfig;
280 | }
281 | }
282 | }
283 | return null;
284 | }
285 |
286 | private boolean setWifiApEnabled(String SSID,String pwd,boolean enable){
287 | closeWifi();
288 | WifiConfiguration apConfig = CreateWifiInfo(SSID, pwd,WIFICIPHER_WPA);
289 | //通过反射调用设置热点
290 | Method method = null;
291 | try {
292 | method = mWifiManager.getClass().getMethod(
293 | "setWifiApEnabled", WifiConfiguration.class, Boolean.TYPE);
294 |
295 | Log.e(TAG, "setWifiAp: "+"连接账号:"+apConfig.SSID+",密码是:"+apConfig.preSharedKey);//提示信息接收方要连接的热点账号和密码
296 |
297 | return (Boolean) method.invoke(mWifiManager, apConfig, enable);
298 | } catch (Exception e) {
299 | e.printStackTrace();
300 | return false;
301 | }
302 | }
303 |
304 | public void modifyWifiAp(String SSID,String pwd){
305 | setWifiApEnabled(SSID,pwd,false);
306 | setWifiApEnabled(SSID,pwd,true);
307 |
308 | }
309 |
310 | /**
311 | * 获取局域网的广播地址
312 | * @param context
313 | * @return
314 | * @throws UnknownHostException
315 | */
316 | public InetAddress getBroadcastAddress(Context context) throws UnknownHostException {
317 | DhcpInfo dhcp = mWifiManager.getDhcpInfo();
318 | if(dhcp==null) {
319 | return InetAddress.getByName("255.255.255.255");
320 | }
321 | int broadcast = (dhcp.ipAddress & dhcp.netmask) | ~dhcp.netmask;
322 | byte[] quads = new byte[4];
323 | for (int k = 0; k < 4; k++)
324 | quads[k] = (byte) ((broadcast >> k * 8) & 0xFF);
325 | return InetAddress.getByAddress(quads);
326 | }
327 |
328 | /**
329 | * 获取路由器MAC地址
330 | * @return 返回MAC地址
331 | */
332 | public static String getRouterMac(String ip){
333 | String macAddress = "";
334 | macAddress = getMacInLinux(ip).trim();
335 | return macAddress;
336 | }
337 | /**
338 | * @param ip 目标ip
339 | * @return Mac Address
340 | *
341 | */
342 | public static String getMacInLinux(final String ip){
343 | String result = "";
344 | String[] cmd = {
345 | "/bin/sh",
346 | "-c",
347 | "ping " + ip + " -c 2 && arp -a"
348 | };
349 | String cmdResult = callCmd(cmd);
350 | result = filterMacAddress(ip,cmdResult,":");
351 |
352 | return result;
353 | }
354 | /**
355 | *
356 | * @param ip 目标ip,一般在局域网内
357 | * @param sourceString 命令处理的结果字符串
358 | * @param macSeparator mac分隔符号
359 | * @return mac地址,用上面的分隔符号表示
360 | */
361 | public static String filterMacAddress(final String ip, final String sourceString,final String macSeparator) {
362 | String result = "";
363 | String regExp = "((([0-9,A-F,a-f]{1,2}" + macSeparator + "){1,5})[0-9,A-F,a-f]{1,2})";
364 | Pattern pattern = Pattern.compile(regExp);
365 | Matcher matcher = pattern.matcher(sourceString);
366 | while(matcher.find()){
367 | result = matcher.group(1);
368 | if(sourceString.indexOf(ip) <= sourceString.lastIndexOf(matcher.group(1))) {
369 | break; //如果有多个IP,只匹配本IP对应的Mac.
370 | }
371 | }
372 |
373 | return result;
374 | }
375 | public static String callCmd(String[] cmd) {
376 | String result = "";
377 | String line = "";
378 | try {
379 | Process proc = Runtime.getRuntime().exec(cmd);
380 | InputStreamReader is = new InputStreamReader(proc.getInputStream());
381 | BufferedReader br = new BufferedReader (is);
382 | while ((line = br.readLine ()) != null) {
383 | result += line;
384 | }
385 | }
386 | catch(Exception e) {
387 | e.printStackTrace();
388 | }
389 | return result;
390 | }
391 | }
392 |
393 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/act_new_client.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
15 |
16 |
21 |
26 |
32 |
38 |
42 |
47 |
48 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
13 |
18 |
23 |
28 |
33 |
34 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_server.xml:
--------------------------------------------------------------------------------
1 |
2 |
15 |
20 |
26 |
27 |
28 |
35 |
36 |
41 |
48 |
56 |
64 |
72 |
80 |
81 |
87 |
88 |
89 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/client_item_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
13 |
20 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/item_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
11 |
16 |
22 |
28 |
34 |
35 |
41 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DempseyZheng/android-socket-file-pass/516cba145d07e02653bb5cda8501102c840e801a/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DempseyZheng/android-socket-file-pass/516cba145d07e02653bb5cda8501102c840e801a/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DempseyZheng/android-socket-file-pass/516cba145d07e02653bb5cda8501102c840e801a/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DempseyZheng/android-socket-file-pass/516cba145d07e02653bb5cda8501102c840e801a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DempseyZheng/android-socket-file-pass/516cba145d07e02653bb5cda8501102c840e801a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | 分布式发布demo
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
22 |
27 |
28 |
--------------------------------------------------------------------------------
/app/src/test/java/com/accvmedia/mysocket/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.accvmedia.mysocket;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * To work on unit tests, switch the Test Artifact in the Build Variants view.
9 | */
10 | public class ExampleUnitTest {
11 | @Test
12 | public void addition_isCorrect()
13 | throws Exception
14 | {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/art/socket.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DempseyZheng/android-socket-file-pass/516cba145d07e02653bb5cda8501102c840e801a/art/socket.gif
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:2.1.2'
9 | // NOTE: Do not place your application dependencies here; they belong
10 | // in the individual module build.gradle files
11 | }
12 | }
13 |
14 | allprojects {
15 | repositories {
16 | jcenter()
17 | }
18 | }
19 |
20 | task clean(type: Delete) {
21 | delete rootProject.buildDir
22 | }
23 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DempseyZheng/android-socket-file-pass/516cba145d07e02653bb5cda8501102c840e801a/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Mon Dec 28 10:00:20 PST 2015
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/local.properties:
--------------------------------------------------------------------------------
1 | ## This file is automatically generated by Android Studio.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must *NOT* be checked into Version Control Systems,
5 | # as it contains information specific to your local configuration.
6 | #
7 | # Location of the SDK. This is only used by Gradle.
8 | # For customization when using a Version Control System, please read the
9 | # header note.
10 | #Tue Mar 14 17:53:49 CST 2017
11 | ndk.dir=D\:\\sdk\\ndk-bundle
12 | sdk.dir=D\:\\sdk
13 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------