2017-09-06 62 views
0

我有一個使用Android相機應用程序的Android應用程序。因爲我需要特定的文件名,所以我創建了自己的CameraActivity。使用File.createTempFile()創建新文件時的負隨機int

在本活動中創建我的臨時文件像這樣:

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有時是負的?或者我怎樣才能避免這種情況?

問題:我需要稍後在我的應用程序中的文件,但不能用「 - 」符號導入它。這拋出了這個例外: 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

在此先感謝您的幫助!

+1

爲什麼這很重要?是否有它引起的特定問題,還是僅僅在美學上不令人滿意? –

+0

@Andy Turner:「 - 」符號不被接受爲Android中文件名的字符。所以我總是必須重命名這些名字。 –

+0

@HansiHansenbaum當然可以。 Android是Linux。唯一不可接受的字符是/和空終止符 –

回答

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()方法,該方法基於運行時庫中提供的方法,但只有正的隨機數。

+0

所以這是Android中的一個錯誤。它自己的代碼生成它不能使用的文件名。 – EJP

+0

正如其他評論所述,Android通常(基於Linux)可以處理帶有減號的文件名。這似乎是在構建過程中的文件名限制問題,從Hansenbaum的錯誤消息判斷:錯誤:com.android.build.gradle.tasks.ResourceException。無可否認,創建一個臨時文件然後將其添加爲資源有點不尋常。 –

+0

謝謝你的幫助!我想我讓這個幻燈片。我的目標是實現一個臨時解決方案來保存和添加圖像文件到原型。但從長遠來看,無論如何,我將不得不尋找基於網絡的解決方案。 –

0

要獲得簡單的解決方法,您可以在文件名字符串中用「x」之類的字符替換「 - 」。

嚴格地說,這可能會使createFileExclusively()失效,但是在這裏幾乎不存在競爭/碰撞的可能性。