最近遇到一个需求,需要判断 U 盘中指定文件夹下的所有文件是否为图片文件,如果为图片文件,则存到自己包名文件夹下的 image 文件夹中。

网上找了很多方法,类似 ImageIO 巴拉巴拉的,Android 中没有啊!可把我愁坏了。但是,皇天不负有心人。我有的问题,别人一定遇到过,并且成功解决了!所以我找到了下面这篇参考文章:Android获取文件类型 - 工具类 ,当然我看到了一篇更早的: Android中Java根据文件头获取文件类型的方法 基本上一模一样,变量名都一样,关键是第一篇文章居然标明原创!!! 不过第二篇文章我也不知道是不是借鉴的啦。

窃取劳动成果是非常可耻的一件事情!!谨记~

好啦碎碎念归碎碎念,第一篇文章的排版啥的都还是更好看的,接下来进入正题。


一. 判断文件是否为图片

参考链接

FileUtil

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
public class FileUtil {

private static final String TAG = "qll_file_util";

public static String getFileType(String path) {
HashMap<String, String> mFileTypes = new HashMap<String, String>();
mFileTypes.put("FFD8FF", "jpg");
mFileTypes.put("89504E47", "png");
mFileTypes.put("47494638", "gif");
mFileTypes.put("424D", "bmp");

return mFileTypes.get(getFileHeader(path));

}

public static String getFileHeader(String filePath) {
FileInputStream is = null;
String value = null;
try {
is = new FileInputStream(filePath);
byte[] b = new byte[3];
is.read(b, 0, b.length);
value = bytesToHexString(b);
} catch (Exception e) {
} finally {
if (null != is) {
try {
is.close();
} catch (IOException e) {
}
}
}
return value;
}

/**
* 将byte字节转换为十六进制字符串
*
* @param src
* @return
*/
private static String bytesToHexString(byte[] src) {
StringBuilder builder = new StringBuilder();
if (src == null || src.length <= 0) {
return null;
}
String hv;
for (int i = 0; i < src.length; i++) {
hv = Integer.toHexString(src[i] & 0xFF).toUpperCase();
if (hv.length() < 2) {
builder.append(0);
}
builder.append(hv);
}
return builder.toString();
}

/**
* 获取外部存储的所有路径,包括 扩展 SD 卡
* */
public static String[] getExternalPaths(Context context) {
String[] paths = {};
StorageManager sm = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);

try {
Class<?>[] paramTypes = {};
Method getVolumePaths = StorageManager.class.getMethod("getVolumePaths", paramTypes);
getVolumePaths.setAccessible(true);
Object[] values = {};
paths = (String[]) getVolumePaths.invoke(sm, values);


} catch (NoSuchMethodException e) {
Log.e(TAG, "getExternalPath: " + e.toString());
} catch (IllegalAccessException e) {
Log.e(TAG, "getExternalPath: " + e.toString() );
} catch (InvocationTargetException e) {
Log.e(TAG, "getExternalPath: " + e.toString() );
}

return paths;
}
}

除最后一个方法,都是照搬的,删去了我不需要的部分——我只需要判断文件是否为图片就好。需要判断所有文件类型的,去参考链接看看吧。

最后一个方法是获取外部存储的所有路径,之前的文章 中有提到。

二. 将图片文件存进指定文件夹中:

参考链接 (链接中还有拷贝文件夹的方法,需要的可以去拜访一下。)

Myservice

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
public class MyService extends Service {

private static final String TAG = "qll_my_service";

public static final String MOUNT_PATH = "/mnt/sda/sda1";
public static final String IMAGE_DIR = "/image";
public static final int FIND_DEVICE = 0;
private String[] paths;

/**
* 依次读取指定路径下的文件,忽略文件夹
* */
void readImage() {
String path = MOUNT_PATH + IMAGE_DIR;
File file = new File(path);

if (!file.exists()) {
Log.i(TAG, "readImage: 文件夹不存在");
return;
}
// 关键代码
File[] pictures = file.listFiles();
for (File item : pictures) {
if (item.isFile()) {
String fileType = FileUtil.getFileType(item.getPath());
if (fileType == null) {
Log.i(TAG, "readImage: 非图片文件");
continue;
}
addData(item);
}
}
}

/**
* 将图片文件写入 包名/files/image 文件夹下
* */
void addData(File file) {
File imageDir = getExternalFilesDir("image");
if (file != null) {
Log.i(TAG, "onCreate: file_path----" + imageDir.toString());
try {
// 关键代码
FileInputStream fileInputStream = new FileInputStream(file);
String fileName = file.getName();
String outPath = imageDir.getPath() + "/" + fileName;
File outFile = new File(outPath);
FileOutputStream fileOutputStream = new FileOutputStream(outFile);
byte[] buffer = new byte[1024];
int byteRead;
while (-1 != (byteRead = fileInputStream.read(buffer))) {
fileOutputStream.write(buffer, 0, byteRead);
}
fileInputStream.close();
fileOutputStream.flush();
fileOutputStream.close();

} catch (Exception e) {
Log.e(TAG, "addData: 写入图片出错----" + e.toString() );
}
}
}

这一段只截取了跟上面 FileUtil 以及解决上面提到的需求的部分代码。

三. 最后

关于 Java 的文件读写,其实我还没理清楚,现在仅限于能把代码 copy 过来并且实现功能而已。之后需要写一个 文件读写 的合集,挖坑待填。