11

下面是一个实用方法的示例:

public static Long getFileSize(String fileString) {

    File file = new File(fileString);

    if (file == null || !file.isFile())
        return null;

    return file.length();
}

将字符串而不是文件传递给这样的方法是一种好习惯吗?一般来说,在制作这种风格的实用方法时应该应用什么推理?

4

9 回答 9

3

这是我的首选解决方案:

public static Long getFileSize(String path) {
    return getFileSize(new File(path));
}

public static Long getFileSize(File file) {
    return (!file.isFile()) ? -1L : file.length();
}

请注意,它返回 -1L 而不是 0L,以允许调用者区分空文件和由于某种原因无法确定长度的“文件”。file.length()在您没有零长度文件的某些情况下,它将返回零;例如

  • file不存在时
  • file是目录时
  • 当它file是一个特殊文件(例如设备文件、管道等)并且操作系统无法确定它的长度时。

file.isFile()电话处理这些情况。但是,方法是否应该返回-1L或抛出异常是有争议的。这场辩论的答案取决于-1L案件是“正常”还是“异常”,这只能参考该方法设计使用的上下文来确定,

于 2010-05-09T03:20:45.750 回答
2

我会选择File。对我来说感觉有点 OOP 正确:更多类型安全(字符串在 Java 中是如此“通用”......)并且在语义上表达:如果您正在处理文件,那么传递一个 File 对象。

回想一下,在 Java 中,File对象本身并不是真正的文件(它的内容),而是它的路径:“文件和目录路径名的抽象表示”(它甚至可以是不存在文件的路径),这几乎是正是您在这里需要的。

这只能是少数情况下的限制:如果“文件”实际上是某种伪文件或资源,例如在 jar 文件中。我发现一个有用的替代方法是URI,它(从概念上)包括一个 File 作为特例,但也包括其他资源。

如果您决定坚持使用这两种选择(字符串或文件),我强烈建议不要将这些方法命名为相同的名称。方法重载可能很痛苦,只有当它给你带来切实的好处时才使用它。

于 2010-05-10T20:16:02.947 回答
1

我认为这将取决于您将要调用此方法时可用的内容。如果您有文件名(字符串),但没有文件,那么让调用者从文件名创建文件似乎没什么意义。

当我不确定时,我的方法是创建两种方法,一种用于 String,一种用于 File。然后让字符串一创建文件并调用文件一。

public static long getFileSize (final String fileString) {
  return getFileSIze (new File (fileString)); 
}

public static long getFileSize (File file) {
   if (file == null || !file.isFile()) return null;
   return file.length();
}
于 2010-05-09T00:37:38.313 回答
1

这取决于客户端期望的实用程序。如果客户端已经有一个文件对象并且想要获取文件大小,客户端开发人员被迫提取文件路径并将其传递给实用程序方法。为了避免它,我会提供重载方法 1) 文件 2) 文件路径字符串

此外,如果文件不可用,我会抛出异常而不是返回 null。

于 2010-05-09T00:40:08.977 回答
1

我的建议是两者都有:

public static Long getFileSize(String path) {
    return getFileSize(new File(path));
}

public static Long getFileSize(File file) {
    return (file == null || !file.isFile()) ? 0L : file.length();
}

并让您的用户根据他们用来表示文件系统路径的对象类型进行选择。正如@Nikita 提到的,这两种选择都不是错误的。

于 2010-05-09T00:45:13.617 回答
1

在我看来,该函数仅对字符串参数有用。它有什么作用?

  • 它创建一个文件对象。
  • 检查它是否可以创建。
  • 检查它是否是一个文件
  • 返回长度

如果您将文件传递给它,则不需要第一件事,应该假设接下来的两个,并且长度是文件成员函数。如果你将这个文件传递给这个文件,这个函数就会变得太简单而无法编写:)

(另外,我认为从返回 long 的函数返回 null 很奇怪)

如果您已经有一个 File 对象,请使用:

length = file.isFile() ? file.length() : -1;

如果您的代码处理文件而不是文件名,如果您重用文件指针,您可以节省一些文件打开。在这种情况下,它可能会导致您通过文件名方法使用它们。

于 2010-05-09T00:46:01.717 回答
1

在这种情况下,方法重载是最佳实践。

于 2010-05-12T09:42:35.987 回答
1

有很多考虑:

  1. 存在实用方法来减少应用程序中重复样板代码的数量,从而使代码更具可读性并减少潜在错误的数量。迎合最常见的使用模式是有意义的,即如果大多数时候您有一个描述文件的字符串 - 传递该字符串。大部分好处来自于首先拥有一个实用方法,而不是获得 100% 面向未来的最佳签名。

  2. 传递文件而不是字符串提供了更强的类型,也就是说,可以在编译时检查更多代码以防止拼写错误。让编译器为您完成工作,利用强类型的好处。

  3. 传递文件意味着您可以传递任何类型的 File 对象,可能是定制的内存文件对象,而无需更改实用程序方法来处理定制的文件描述符。

  4. 当您必须处理大量操作系统文件路径并且只想用最少的行数检查大小时,传递字符串可能会有所帮助。

  5. 最后,您可以以非常低的成本拥有几个重载的实用程序方法。这种情况正是方法重载作为语言特性存在的原因。看看你的代码库中自然起作用的东西。代码具有延展性,这不是您必须永远忍受的这些设计决策之一,除非您正在构建一个 API 供其他人使用。

  6. 例如,您可能还希望将名称更改为更具描述性

    • long sizeFromFile(File f)
    • long sizeFromFileName(字符串名称)

    使用Joel Spolsky最初建议的约定。

于 2010-05-09T14:14:39.093 回答
0

唯一重要的是你将如何使用这种方法。换句话说,如果您的应用程序使用 File 对象进行操作,您可以传递它们并删除一些不必要的操作。如果使用文件路径进行操作,字符串参数可能更方便。

但最终,这两种选择都不是错误的:两者都不会让您的应用程序工作得更糟。

于 2010-05-09T00:36:36.333 回答