当前位置: 首页 > 面试题库 >

如何在Java中安全地编码字符串以用作文件名?

澹台权
2023-03-14
问题内容

我正在从外部进程接收字符串。我想使用该字符串创建文件名,然后写入该文件。这是执行此操作的代码段:

    String s = ... // comes from external source
    File currentFile = new File(System.getProperty("user.home"), s);
    PrintWriter currentWriter = new PrintWriter(currentFile);

如果s包含无效字符,例如在基于Unix的OS中为’/’,则(正确)抛出java.io.FileNotFoundException。

如何安全地编码字符串,以便可以将其用作文件名?

编辑:我希望的是一个为我做的API调用

我可以做这个:

    String s = ... // comes from external source
    File currentFile = new File(System.getProperty("user.home"), URLEncoder.encode(s, "UTF-8"));
    PrintWriter currentWriter = new PrintWriter(currentFile);

但是我不确定URLEncoder是否可用于此目的。


问题答案:

如果您希望结果类似于原始文件,则SHA-1或任何其他哈希方案都不是答案。如果必须避免冲突,那么简单替换或删除“不良”字符也不是答案。

相反,您想要这样的东西。(注意:这应该作为说明性示例,而不是要复制粘贴的内容。)

char fileSep = '/'; // ... or do this portably.
char escape = '%'; // ... or some other legal char.
String s = ...
int len = s.length();
StringBuilder sb = new StringBuilder(len);
for (int i = 0; i < len; i++) {
    char ch = s.charAt(i);
    if (ch < ' ' || ch >= 0x7F || ch == fileSep || ... // add other illegal chars
        || (ch == '.' && i == 0) // we don't want to collide with "." or ".."!
        || ch == escape) {
        sb.append(escape);
        if (ch < 0x10) {
            sb.append('0');
        }
        sb.append(Integer.toHexString(ch));
    } else {
        sb.append(ch);
    }
}
File currentFile = new File(System.getProperty("user.home"), sb.toString());
PrintWriter currentWriter = new PrintWriter(currentFile);

此解决方案提供了可逆编码(无冲突),其中在大多数情况下,编码后的字符串类似于原始字符串。我假设您使用的是8位字符。

URLEncoder 可以,但是它的缺点是它对很多合法的文件名字符进行编码。

如果您想要一个无法保证的可逆解决方案,则只需删除“不良”字符,而不是用转义序列替换它们。

上面编码的相反过程应同样直接实现。



 类似资料:
  • 问题内容: 我喜欢将字符串的Java映射编码为单个base 64编码的字符串。编码后的字符串将被传输到远程端点,并且可能由一个不好的人操纵。因此,应该发生的最糟糕的事情是密钥,值元组无效,但不应将任何其他安全风险置于一旁。 例: 是的,必须是Base64。不喜欢那个 或那个 或其他任何一个。是否有现有的轻量级解决方案(首选单一实用程序类)?还是我必须创建自己的? 有什么比这更好的了吗? 谢谢, 问

  • 问题内容: 我有一个 特殊情况, 要求我根据用户提供的输入值生成SQL WHERE子句的一部分。我想防止任何形式的SQL Injection漏洞。我想出了以下代码: 问题: 看到任何问题吗? 您能提供更好的解决方案吗? 是否有现有的库可以帮助您解决此问题? 笔记: 这是SO和其他地方的常见问题,但是我看到的唯一答案是始终使用PreparedStatements。Fwiw,我正在使用JasperRe

  • 问题内容: 就像标题所说的那样,我正在尝试在Java中将字符串“ test”编码为base32字符串“ ORSXG5A =“。 我在网上搜索时发现的所有类都是使用32位从字符串编码为数组的类,但是显然这不是我想要的。 很抱歉这个新手问题。 问题答案: Apache commons编解码器提供了一个可以执行此操作的类 版画 您可以在此处下载。

  • 本文向大家介绍如何在JavaScript中解码编码的字符串?,包括了如何在JavaScript中解码编码的字符串?的使用技巧和注意事项,需要的朋友参考一下 解码 在JavaScript中,使用unescape()方法解码字符串。该方法采用一个字符串,该字符串由escape()方法编码,并对其进行解码。字符串中的十六进制字符将被使用unescape()方法表示的实际字符替换。 语法 示例 接下来,两

  • 我使用javascript/jquery填充包含元数的dom元素: 我如何摆脱url编码,例如“h%e4nde”,而使用“hände”?我试过了 但似乎都不起作用... 多谢帮忙。

  • 问题内容: 我通过通过PHP回显将XML文档发送给AJAX调用来进行响应。为了形成这个XML文档,我遍历了数据库的记录。问题在于数据库中包含带有’<’符号的记录。因此,浏览器自然会在该特定位置引发错误。如何解决? 问题答案: 通过使用(或可能更适当地)使用库来构建XML文档(例如DOMDocument或XMLWriter)来转义这些字符。 另一种替代方法是使用CDATA节,但是您必须注意是否出现。