使用File.createTempFile()

时间:2017-09-06 14:47:27

标签: java android

我有一个使用Android相机应用的Android应用。因为我需要特定的文件名,所以我创建了自己的CameraActivity。

在这个活动中,我创建了我的临时文件:

public File createImageFile() throws IOException {
    File pathOfStorageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
    pathOfStorageDir.mkdir();

    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    String filePrefix = "img_" + timeStamp + "_";
    String suffix = ".jpg";

    File image = File.createTempFile(filePrefix, suffix, pathOfStorageDir);
    currentFileName = image.getName();
    currentFilePath = image.getAbsolutePath();
    return image;
}

奇怪的是,我有时会在新文件名中得到负值。

当我看到createTempFile()调用generateTempFile()并且该方法应该创建随机绝对int 。为什么这个随机int有时是负数?或者我该如何避免这种情况?

问题:我稍后需要在我的应用中使用该文件,但无法使用&#34; - &#34;标志。这引发了我的异常: Error:com.android.build.gradle.tasks.ResourceException: <package-name>/app/src/main/res/drawable/img_sfr_20170715_-1‌​13604.jpg: Error: '-' is not a valid file-based resource name character: File-based resource names must contain only lowercase a-z, 0-9, or underscore

提前感谢您的帮助!

2 个答案:

答案 0 :(得分:0)

好的,这很有意思:似乎android.jar中的File.createTempFile()方法的实现方式与rt.jar中的方法不同。

在rt.jar(使用Java 8)中,我们有:

public static File createTempFile(String prefix, String suffix,
                                  File directory)
    throws IOException
{
    if (prefix.length() < 3)
        throw new IllegalArgumentException("Prefix string too short");
    if (suffix == null)
        suffix = ".tmp";

    File tmpdir = (directory != null) ? directory
                                      : TempDirectory.location();
    SecurityManager sm = System.getSecurityManager();
    File f;
    do {
        f = TempDirectory.generateFile(prefix, suffix, tmpdir);

        if (sm != null) {
            try {
                sm.checkWrite(f.getPath());
            } catch (SecurityException se) {
                // don't reveal temporary directory location
                if (directory == null)
                    throw new SecurityException("Unable to create temporary file");
                throw se;
            }
        }
    } while ((fs.getBooleanAttributes(f) & FileSystem.BA_EXISTS) != 0);

    if (!fs.createFileExclusively(f.getPath()))
        throw new IOException("Unable to create temporary file");

    return f;
}

使用TempDirectory.generateFile(String, String, File)

    private static final SecureRandom random = new SecureRandom();
    static File generateFile(String prefix, String suffix, File dir)
        throws IOException
    {
        long n = random.nextLong();
        if (n == Long.MIN_VALUE) {
            n = 0;      // corner case
        } else {
            n = Math.abs(n);
        }

        // Use only the file name from the supplied prefix
        prefix = (new File(prefix)).getName();

        String name = prefix + Long.toString(n) + suffix;
        File f = new File(dir, name);
        if (!name.equals(f.getName()) || f.isInvalid()) {
            if (System.getSecurityManager() != null)
                throw new IOException("Unable to create temporary file");
            else
                throw new IOException("Unable to create temporary file, " + f);
        }
        return f;
    }

这将导致文件名中包含正的随机数。

在android.jar(Android API 20)中,我们有:

public static File createTempFile(String prefix, String suffix, File directory)
        throws IOException {
    // Force a prefix null check first
    if (prefix.length() < 3) {
        throw new IllegalArgumentException("prefix must be at least 3 characters");
    }
    if (suffix == null) {
        suffix = ".tmp";
    }
    File tmpDirFile = directory;
    if (tmpDirFile == null) {
        String tmpDir = System.getProperty("java.io.tmpdir", ".");
        tmpDirFile = new File(tmpDir);
    }
    File result;
    do {
        result = new File(tmpDirFile, prefix + tempFileRandom.nextInt() + suffix);
    } while (!result.createNewFile());
    return result;
}

由于tempFileRandom是标准Random实例,因此其nextInt()方法将返回正整数和负整数。

因此,使用File.createTempFile()可以在Android上返回带有减号/连字符的文件名。

因此,最好的选择是根据运行时库中提供的方法实现自己的文件名生成器和createTempFile()方法,但只能使用正的随机数。

答案 1 :(得分:0)

为了便于解决,您可以直接替换&#34; - &#34;喜欢&#34; x&#34;在文件名字符串中。

严格地说,这可能会使保修无效。关于createFileExclusively(),但是这里几乎不存在种族/碰撞的可能性。