2

我想要获取文件的扩展名?如:

import os
print os.path.splitext('testit.doc')
""">>>('testit', '.doc')"""

但是当我使用以下示例时它不起作用。

import os
print os.path.splitext('testid.tar.gz')
""">>>('testit.tar', '.gz')"""

我看到当位置中有同名文件时,Chrome 可以自动重命名文件。它将添加 (1) 或 (n)。我想知道它是怎么做的!有没有机构可以告诉我? 在此处输入图像描述

4

2 回答 2

3

幸运的是,Chromium 是开源的,因此您可以查看记录良好的代码。好的...我找到了:这里

RenameAndUniquify是:

void DownloadFileImpl::RenameAndUniquify(
    const base::FilePath& full_path,
    const RenameCompletionCallback& callback) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));

  base::FilePath new_path(full_path);

  int uniquifier =
      file_util::GetUniquePathNumber(new_path, FILE_PATH_LITERAL(""));
  if (uniquifier > 0) {
    new_path = new_path.InsertBeforeExtensionASCII(
        base::StringPrintf(" (%d)", uniquifier));
  }

...

}

InsertBeforeExtension致电ExtensionSeperatorPosition您感兴趣的电话(链接):

// Find the position of the '.' that separates the extension from the rest
// of the file name. The position is relative to BaseName(), not value().
// This allows a second extension component of up to 4 characters when the
// rightmost extension component is a common double extension (gz, bz2, Z).
// For example, foo.tar.gz or foo.tar.Z would have extension components of
// '.tar.gz' and '.tar.Z' respectively. Returns npos if it can't find an
// extension.
StringType::size_type ExtensionSeparatorPosition(const StringType& path) {
  // Special case "." and ".."
  if (path == FilePath::kCurrentDirectory || path == FilePath::kParentDirectory)
    return StringType::npos;

  const StringType::size_type last_dot =
      path.rfind(FilePath::kExtensionSeparator);

  // No extension, or the extension is the whole filename.
  if (last_dot == StringType::npos || last_dot == 0U)
    return last_dot;

  const StringType::size_type penultimate_dot =
      path.rfind(FilePath::kExtensionSeparator, last_dot - 1);
  const StringType::size_type last_separator =
      path.find_last_of(FilePath::kSeparators, last_dot - 1,
                        arraysize(FilePath::kSeparators) - 1);

  if (penultimate_dot == StringType::npos ||
      (last_separator != StringType::npos &&
       penultimate_dot < last_separator)) {
    return last_dot;
  }

  for (size_t i = 0; i < arraysize(kCommonDoubleExtensions); ++i) {
    StringType extension(path, penultimate_dot + 1);
    if (LowerCaseEqualsASCII(extension, kCommonDoubleExtensions[i]))
      return penultimate_dot;
  }

  StringType extension(path, last_dot + 1);
  for (size_t i = 0; i < arraysize(kCommonDoubleExtensionSuffixes); ++i) {
    if (LowerCaseEqualsASCII(extension, kCommonDoubleExtensionSuffixes[i])) {
      if ((last_dot - penultimate_dot) <= 5U &&
          (last_dot - penultimate_dot) > 1U) {
        return penultimate_dot;
      }
    }
  }

  return last_dot;
}
于 2013-03-27T12:34:35.827 回答
0

我认为它使用了一个众所周知的文件扩展名列表,你也可以这样做,你有很多方法(可能比我的解决方案性能更好,例如使用正则表达式),但这是一个非常简单的解决方案:

import os

known_extensions = ['.tar.gz', '.tar.bz2']
def splitext(file_name):
    file_name = file_name.strip()

    for ex in known_extensions:
        if file_name[-len(ex):] == ex:
            return file_name[:-len(ex)], ex

    return os.path.splitext(file_name)
于 2013-03-27T12:04:52.920 回答