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

呼び出し元が空のファイルと、何らかの理由で長さを判別できない「ファイル」を区別できるようにするために、0Lではなく-1Lを返すことに注意してください。長さがゼロのfile.length()ファイルがない場合、はゼロを返します。例えば

  • file存在しない場合
  • fileがディレクトリの場合
  • file特殊ファイル(デバイスファイル、パイプなど)であり、OSがその長さを判別できない場合。

file.isFile()呼び出しはこれらのケースを扱います。ただし、メソッドが-1L例外を返すかスローするかについては議論の余地があります。この議論への答えは、-1Lケースが「正常」であるか「例外的」であるかを明らかにし、それは、メソッドが使用されるように設計されているコンテキストを参照してのみ決定できます。

于 2010-05-09T03:20:45.750 に答える
2

私はファイルで行きます。私には少しOOPが正しいと感じます:よりタイプセーフ(文字列はJavaでは「一般的」です...)そして意味的に表現力があります:ファイルを扱っている場合は、Fileオブジェクトを渡します。

Javaでは、 Fileオブジェクトは実際にはファイル自体(そのコンテンツ)ではなく、そのパスを表すことを思い出してください。「ファイルとディレクトリのパス名の抽象表現」(存在しないファイルのパスでもかまいません)。まさにここで必要なもの。

これは、いくつかの場合にのみ制限となる可能性があります。「ファイル」が実際にある種の疑似ファイルまたはリソースである場合、たとえばjarファイル内などです。私が便利だと思った別の方法はURIです。これには、(概念的には)特殊なケースとしてファイルが含まれていますが、他のリソースも含まれています。

また、2つの選択肢(文字列またはファイル)を使用する場合は、メソッドに同じ名前を付けることはお勧めしません。メソッドのオーバーロードは苦痛になる可能性があります。具体的なメリットがある場合にのみ使用してください。

于 2010-05-10T20:16:02.947 に答える
1

このような場合、メソッドのオーバーロードがベストプラクティスです。

于 2010-05-12T09:42:35.987 に答える
1

これは、このメソッドを呼び出す時点で利用できるものによって異なると思います。ファイル名(String)はあるがファイルがない場合、呼び出し元にファイル名からファイルを作成させることにはほとんど意味がないようです。

よくわからない場合の私のアプローチは、String用とFile用の2つのメソッドを作成することです。次に、String oneにファイルを作成させ、fileoneを呼び出します。

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

私の意見では、その関数は文字列パラメータでのみ役立ちます。それは何をするためのものか?

  • ファイルオブジェクトを作成します。
  • 作成できることを確認します。
  • ファイルであることを確認します
  • 長さを返します

ファイルを渡した場合、最初のものは必要ありません。次の2つを想定する必要があり、長さはファイルメンバー関数です。これをファイルに渡すと、この関数は簡単すぎて書き込めなくなります:)

(また、longを返す関数からnullを返すのは奇妙だと思います)

すでにFileオブジェクトがある場合は、次を使用します。

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

コードがファイル名ではなくファイルを処理する場合、ファイルポインターを再利用すると、ファイルを開くことができます。その場合、ファイル名アプローチでそれらを使用することにつながる可能性があります。

于 2010-05-09T00:46:01.717 に答える
1

いくつかの考慮事項があります。

  1. アプリ内の繰り返しボイラープレートコードの量を減らすためのユーティリティメソッドが存在するため、コードが読みやすくなり、潜在的なバグの数が減ります。最も一般的な使用パターンに対応することは理にかなっています。つまり、ほとんどの場合、ファイルを説明する文字列がある場合は、その文字列を渡します。利点のほとんどは、100%将来にわたって利用できる最適な署名を取得するのではなく、最初にユーティリティメソッドを使用することから得られます。

  2. 文字列の代わりにファイルを渡すと、より強力な入力が可能になります。つまり、コンパイル時に、タイプミスから保護して、より多くのコードをチェックできます。コンパイラに作業を任せ、強い型付けの利点を活用してください。

  3. ファイルを渡すということは、任意の種類のFileオブジェクト、場合によっては、特注のファイル記述子を処理するためにユーティリティメソッドを変更することなく、特注のメモリ内ファイルオブジェクトを渡すことができることを意味します。

  4. 文字列を渡すと、OSファイルのパスを大量に処理する必要があり、最小行数でサイズを確認したい場合に役立ちます。

  5. 最後に、非常に低コストでいくつかのオーバーロードされたユーティリティメソッドを使用できます。このシナリオは、言語機能としてメソッドのオーバーロードが存在する理由です。コードベースで自然に機能するものを確認してください。コードは順応性があり、他の人が使用するAPIを構築しない限り、これは永遠に生きなければならないこれらの設計上の決定の1つではありません。

  6. たとえば、名前をもう少しわかりやすい名前に変更することもできます。

    • long sizeFromFile(File f)および
    • long sizeFromFileName(文字列名)

    JoelSpolskyによって最初に提案された規則を使用します。

于 2010-05-09T14:14:39.093 に答える
0

重要なのは、この方法をどのように使用するかだけです。つまり、アプリケーションがFileオブジェクトで動作する場合、それらを渡して不要な操作を削除することができます。ファイルパスを操作する場合は、文字列パラメータの方が便利な場合があります。

しかし、最終的には、どちらの選択も間違っていません。どちらもアプリケーションの動作を悪化させることはありません。

于 2010-05-09T00:36:36.333 に答える