Utility method - Pass a File or String? [closed]

2020-06-03 03:15发布

Here's an example of a utility method:

public static Long getFileSize(String fileString) {

    File file = new File(fileString);

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

    return file.length();
}

Is it a good practise to pass a String rather than a File to a method like this? In general what reasoning should be applied when making utility methods of this style?

9条回答
叛逆
2楼-- · 2020-06-03 03:23

This is my preferred solution:

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

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

Note that it is returning -1L rather than 0L, to allow the caller to distinguish between an empty file, and a "file" whose length cannot be determined for some reason. The file.length() will return zero in some cases where you don't have a zero length file; e.g.

  • when the file does not exist
  • when the file is a directory
  • when the file is a special file (e.g. device file, pipe, etc) and the OS cannot determine its length.

The file.isFile() call deals with these cases. However, it is debatable whether the method(s) should return -1L or throw an exception. The answer to this debate turns on whether the -1L cases are "normal" or "exceptional", and that can only be determined with reference to the contexts in which the method is designed to be used,

查看更多
手持菜刀,她持情操
3楼-- · 2020-06-03 03:26

My recommendation would be to have both:

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();
}

and let your users choose based on the the kind of object they are using to represent filesystem paths. As @Nikita mentioned, neither choice is wrong.

查看更多
Deceive 欺骗
4楼-- · 2020-06-03 03:26

In my opinion, that function is only useful with a string parameter. What does it do?

  • It creates a file object.
  • Checks that it can be created.
  • Checks that it's a file
  • Returns the length

If you passed it a file, the first thing isn't needed, the next two should probably be assumed, and the length is a file member function. If you pass this a file, this function becomes too trivial to write :)

(Also, I think returning null from a function that returns a long is strange)

If you have a File object already, use:

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

If your code deals with files instead of file names you could save yourself some file opens if you reuse the File pointers. In that case, it might lead you to use them over the filename approach.

查看更多
做自己的国王
5楼-- · 2020-06-03 03:27

I would think this would depend upon what you have available at the point where you are going to be calling this method. If you have the file name (String), but no File, there seems little point in making the caller create the File from the file name.

My approach to this when I'm not sure is to create two methods, one for String, one for File. Then have the String one create the file and call the file one.

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();
}
查看更多
Anthone
6楼-- · 2020-06-03 03:33

Method Overloading is the best practice in such cases.

查看更多
再贱就再见
7楼-- · 2020-06-03 03:36

The only thing that matters is how you're gonna use this method. In other words, if your application operates with File objects, you could pass them and remove some unnecessary operations. If you operate with file paths, string parameter may be more convenient.

But ultimately, neither choice is wrong: neither will make your application work worse.

查看更多
登录 后发表回答