前提
何度もすみません。以前(https://teratail.com/questions/36024)で質問させていただいたのですが、先輩からのコードレビューの結果、修正を求められました。
理由としては主に以下でした、
・whileの中でインスタンス生成をしているため、出力フォルダの同名ファイルの枝番の数だけ無駄にメモリを消費することとなる。
・なんだか無限ループにみえる
・出力フォルダの同名ファイルの枝番の数だけループさせるの?
うまく言い返せませんでした。
どのように最適化していけばいいでしょうか。。
処理仕様
ファイル出力をする際に、対象のフォルダ内に同名ファイルがあれば、
拡張子の前に枝番(例:20160525215810_access_1.log)を付与する。
枝番のついた同名ファイルがあれば枝番を+1して(例:20160525215810_access_2.log)出力する
そのほかの条件、
・ _(アンダーバー)と拡張子の間に数字以外の値が入っているファイルは無視
・ 枝番が飛んでいた場合(例:_1と_3がある)は、抜けている枝番のファイルを作成。
・同名ファイルがなければそのまま出力(例:20160525215810_access.log)
現在のソースコード
// 出力ファイルの設定
String outputPath; //保存場所のパス(パス区切り文字で終わっている)
String outputFileName; //保存ファイル名
File outputFile = new File(outputPath + outputFileName);
// 拡張子取得
int extensionIndex = outputFileName.lastIndexOf(".");
String extension = outputFileName.substring(extensionIndex);
//拡張子なしファイル名
String filename = outputFileName.substring(0, extensionIndex);
// 同名ファイルが存在する場合、出力ファイルに枝番を付与する処理
int branch = 0;
while (outputFile.exists()) {
branch++;
outputFile = new File(outputPath + filename + "_" + branch + extension);
}
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
+1
あなたの仕事はここで答えを聞いて先輩に伝えることですか?
そもそも自分で考えていないので、言い返せないのは当たり前ですよね。
また、コードレビューの結果に対して言い返すと言う表現を使うこと自体が誤りです。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
checkベストアンサー
0
File.exists()を使って判定していましたが、保存ディレクトリのFileオブジェクトに対してlist()でファイル名文字列配列を取得し、枝番付きのファイル名を順次作成し、そのファイル名が配列内にあるかどうかチェックする、という方法もあるかもしれません。ファイル名の配列をArrays.asListでListにすると、入っているかどうかのチェックがcontains()で一発で済みます。
ただし、逐次配列内をループして探索することになるので、ループ数は増えると思います。
その先輩の論に反論するならば…
・whileの中でインスタンス生成をしているため、出力フォルダの同名ファイルの枝番の数だけ無駄にメモリを消費することとなる。
変数が参照するFileオブジェクトが逐次入れ替わるため、古いFileはガベージコレクションの対象になる。むしろ上記の方法の様に存在するファイルを表すインスタンスを生成するという方法は、確実にファイルの数だけインスタンスを生成することになるが、この方法であれば、「そのディレクトリに存在するファイルすべてが入力したファイル名またはその枝番付きで、欠けのない連番になっている」状態の時のみ、ファイル数+1回のインスタンス生成になるが、途中で存在しないファイル名があればそこでインスタンス生成は打ち切られるため、平均的にはインスタンス生成数は少ない。
・なんだか無限ループにみえる
どこがそう見えるのか教えていただきたいくらいですが…
・出力フォルダの同名ファイルの枝番の数だけループさせるの?
ディレクトリのファイルが完全に連番であればその必要もないかもしれないが、今回その保証がない、むしろ欠けがあることを考慮すべきとの指示があるため、この方法でないと最小の欠け番を探すことができない。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.35%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
質問への追記・修正、ベストアンサー選択の依頼
退会済みユーザー
2016/05/27 22:48
あなたの疑問に答えるのは、先輩の仕事では?
swordone
2016/05/27 23:55 編集
質問とは直接関係ないですが、これだとoutputFileNameの文字列が拡張子がついたままになり、whileでのファイル名生成時に拡張子のあとに枝番がついて更に拡張子が付く形になってしまいます。あとファイル出力処理がないままになっていますね。
Hyonta
2016/05/28 11:35
ご指摘ありがとうございます。
拡張子なしファイル名取得を追加しました。
ファイル出力処理は省略しています。