首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >提高文件搜索和MediadataRetriever的性能

提高文件搜索和MediadataRetriever的性能
EN

Stack Overflow用户
提问于 2018-05-30 23:24:51
回答 2查看 313关注 0票数 0

我有一个数组的文件,并想得到一个ArrayList,其中只包含音频文件从所说的阵列。

我想知道是否有一种方法可以提高我的代码的性能(现在迭代14000个文件需要大约85秒)。

我的代码:

final File[] ArrayOfFiles = mysteriousFunction(); //returns a ton of files
final MediaMetadataRetriever iLoveThisThing = new MediaMetadataRetriever();

ArrayList<File> audioFiles = new ArrayList<>();

for (File file : ArrayOfFiles)
            {
                final String fileString = file.toString();

                String extension = "";
                final int lastIndexOfDot = fileString.lastIndexOf('.');
                final int lastIndexOfSeperator = fileString.lastIndexOf(File.separatorChar);
                if (lastIndexOfDot > lastIndexOfSeperator)
                {
                    extension = fileString.substring(lastIndexOfDot + 1);

                }

                switch (extension)
                {
                    case "mp3":
                    case "mp4":
                    case "3gp":
                    case "m4a":
                    case "aac":
                    case "ogg":
                    case "wav":
                    case "mid":
                    case "ts":
                    case "imy":
                    case "flac":
                    case "xmf":
                    case "mxmf":
                    case "mkv":
                        iLoveThisThing.setDataSource(fileString);
                        final String foo1 = iLoveThisThing.extractMetadata(MediaMetadataRetriever.METADATA_KEY_MIMETYPE);
                        if (foo1 != null)
                        {
                            String foo2 = foo1.substring(0, foo1.indexOf('/'));
                            if (foo2.equals("audio"))
                            {
                                audioFiles.add(file);
                            }
                        }
                        break;
                    default:
                        break;
                }
            }

我已经收到了相当多的技巧,所以这是我的更新代码:

private static final Set<String> extensions = new HashSet<>(Arrays.asList("mp3", "mp4", "3gp", "m4a", "aac", "ogg", "wav", "mid", "ts", "imy", "flac", "xmf", "mxmf", "mkv"));

public static void DoStuff()
{
    new Thread(() -> {
        final File[] allFiles = get_a_ton_of_files();
        final Set<File> audioFilesSet = ConcurrentHashMap.newKeySet(allFiles.length);
        Arrays.stream(allFiles).parallel().forEach(file -> {
            final String fileString = file.toString();
            final int lastIndexOfDot = fileString.lastIndexOf('.');
            if (lastIndexOfDot > fileString.lastIndexOf(File.separatorChar))
            {
                final String extension = fileString.substring(lastIndexOfDot + 1);
                if (extensions.contains(extension))
                {
                    final MediaMetadataRetriever myMediadataRetriever = new MediaMetadataRetriever();
                    myMediadataRetriever.setDataSource(fileString);
                    final String mime = myMediadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_MIMETYPE);
                    if (mime != null && mime.startsWith("audio"))
                    {
                        audioFiles.add(file);
                    }
                    myMediadataRetriever.release();
                }
            }
        });
    }).start();
}

任何进一步的优化显然仍然是高度赞赏的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-05-31 00:00:38

你可以做一些事情来提高你的速度:

  1. for (File file : ArrayOfFiles)可以并行执行
  2. 请勿使用MediaMetadataRetriever。这很耗时。

在这个类中的其他方法之前调用这个方法。这种方法可能很耗时。

您可以改用ContentResolver

Uri uri = Uri.fromFile(file);
ContentResolver contentResolver = context.getContentResolver();
String mime = contentResolver.getType(uri);

把它付诸行动:

Set<File> audioFileSet = ConcurrentHashMap.newKeySet(ArrayOfFiles.length);

Set<String> ext = new HashSet<>(Arrays.asList("mp3", "mp4", ...));

ContentResolver contentResolver = context.getContentResolver();

Arrays.stream(ArrayOfFiles).parallel().forEach(file -> {
    String extension = ...;
    if (ext.contains(extension)) {
        String mime = contentResolver.getType(Uri.fromFile(file));
        ...
        audioFileSet.add(file);
    }
});

// If you want list:
List<File> list = new ArrayList<>(audioFileSet);

如果使用MediaMetadataRetriever

Arrays.stream(ArrayOfFiles).parallel().forEach(file -> {
    String extension = ...;
    if (ext.contains(extension)) {
        // Must init in side loop
        MediaMetadataRetriever iLoveThisThing = new MediaMetadataRetriever();
        iLoveThisThing.setDataSource(fileString);
        String mime = iLoveThisThing.extractMetadata(MediaMetadataRetriever.METADATA_KEY_MIMETYPE);
        ...
        audioFileSet.add(file);
        // Dont forget to release resource:
        iLoveThisThing.release();
    }
});
票数 1
EN

Stack Overflow用户

发布于 2018-05-30 23:36:36

最好使用以下方法检查文件是否为音频文件:

public static boolean isMediaFile(String filepath) {
    String mimeType = URLConnection.guessContentTypeFromName(filepath);
    return mimeType != null && mimeType.startsWith("audio");
}

因此您甚至不需要使用Switch-Case语句。试试看:

if (isMediaFile(file.getAbsolutePath()) {
    audioFiles.add(file);
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50608387

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档