質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
ファイル

ファイルとは、文字列に基づいた名前又はパスからアクセスすることができる、任意の情報のブロック又は情報を格納するためのリソースです。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

ファイルI/O

ファイルI/Oは、コンピューターにおけるファイルの入出力です。これは生成/削除やファイルを読み込んだり、出力をファイルに書き込むようなディレクトリやファイルの運用を含みます。

Q&A

解決済

2回答

5831閲覧

Java ファイル出力 ファイル名操作

Hyonta

総合スコア36

ファイル

ファイルとは、文字列に基づいた名前又はパスからアクセスすることができる、任意の情報のブロック又は情報を格納するためのリソースです。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

ファイルI/O

ファイルI/Oは、コンピューターにおけるファイルの入出力です。これは生成/削除やファイルを読み込んだり、出力をファイルに書き込むようなディレクトリやファイルの運用を含みます。

0グッド

0クリップ

投稿2016/05/27 13:44

編集2016/05/28 02:34

###前提
何度もすみません。以前(https://teratail.com/questions/36024)で質問させていただいたのですが、先輩からのコードレビューの結果、修正を求められました。

理由としては主に以下でした、
・whileの中でインスタンス生成をしているため、出力フォルダの同名ファイルの枝番の数だけ無駄にメモリを消費することとなる。
・なんだか無限ループにみえる
・出力フォルダの同名ファイルの枝番の数だけループさせるの?

うまく言い返せませんでした。
どのように最適化していけばいいでしょうか。。

###処理仕様
ファイル出力をする際に、対象のフォルダ内に同名ファイルがあれば、
拡張子の前に枝番(例:20160525215810_access_1.log)を付与する。
枝番のついた同名ファイルがあれば枝番を+1して(例:20160525215810_access_2.log)出力する

そのほかの条件、
・ _(アンダーバー)と拡張子の間に数字以外の値が入っているファイルは無視
・ 枝番が飛んでいた場合(例:_1と_3がある)は、抜けている枝番のファイルを作成。
・同名ファイルがなければそのまま出力(例:20160525215810_access.log)

###現在のソースコード

Java

1// 出力ファイルの設定 2 String outputPath; //保存場所のパス(パス区切り文字で終わっている) 3String outputFileName; //保存ファイル名 4 File outputFile = new File(outputPath + outputFileName); 5 6// 拡張子取得 7 int extensionIndex = outputFileName.lastIndexOf("."); 8 String extension = outputFileName.substring(extensionIndex); 9 10//拡張子なしファイル名 11String filename = outputFileName.substring(0, extensionIndex); 12 13// 同名ファイルが存在する場合、出力ファイルに枝番を付与する処理 14 int branch = 0; 15 while (outputFile.exists()) { 16 branch++; 17 outputFile = new File(outputPath + filename + "_" + branch + extension); 18 } 19

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2016/05/27 13:48

あなたの疑問に答えるのは、先輩の仕事では?
swordone

2016/05/27 14:57 編集

質問とは直接関係ないですが、これだとoutputFileNameの文字列が拡張子がついたままになり、whileでのファイル名生成時に拡張子のあとに枝番がついて更に拡張子が付く形になってしまいます。あとファイル出力処理がないままになっていますね。
Hyonta

2016/05/28 02:35

ご指摘ありがとうございます。 拡張子なしファイル名取得を追加しました。 ファイル出力処理は省略しています。
guest

回答2

0

あなたの仕事はここで答えを聞いて先輩に伝えることですか?

そもそも自分で考えていないので、言い返せないのは当たり前ですよね。
また、コードレビューの結果に対して言い返すと言う表現を使うこと自体が誤りです。

投稿2016/05/27 14:13

yona

総合スコア18155

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Hyonta

2016/05/28 02:26

厳しいお言葉ありがとうございます。 できるだけ自分で考えて議論できるようにがんばります。
guest

0

ベストアンサー

File.exists()を使って判定していましたが、保存ディレクトリのFileオブジェクトに対してlist()でファイル名文字列配列を取得し、枝番付きのファイル名を順次作成し、そのファイル名が配列内にあるかどうかチェックする、という方法もあるかもしれません。ファイル名の配列をArrays.asListでListにすると、入っているかどうかのチェックがcontains()で一発で済みます。
ただし、逐次配列内をループして探索することになるので、ループ数は増えると思います。

その先輩の論に反論するならば…

・whileの中でインスタンス生成をしているため、出力フォルダの同名ファイルの枝番の数だけ無駄にメモリを消費することとなる。

変数が参照するFileオブジェクトが逐次入れ替わるため、古いFileはガベージコレクションの対象になる。むしろ上記の方法の様に存在するファイルを表すインスタンスを生成するという方法は、確実にファイルの数だけインスタンスを生成することになるが、この方法であれば、「そのディレクトリに存在するファイルすべてが入力したファイル名またはその枝番付きで、欠けのない連番になっている」状態の時のみ、ファイル数+1回のインスタンス生成になるが、途中で存在しないファイル名があればそこでインスタンス生成は打ち切られるため、平均的にはインスタンス生成数は少ない。

・なんだか無限ループにみえる

どこがそう見えるのか教えていただきたいくらいですが…

・出力フォルダの同名ファイルの枝番の数だけループさせるの?

ディレクトリのファイルが完全に連番であればその必要もないかもしれないが、今回その保証がない、むしろ欠けがあることを考慮すべきとの指示があるため、この方法でないと最小の欠け番を探すことができない。

投稿2016/05/27 14:41

swordone

総合スコア20651

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Hyonta

2016/05/28 03:04

いつも回答ありがとうございます! たしかに欠け番を探すためには逐次検索のループを回すしかないですね。 swordoneさんに回答していただいたexists()を使った方法のほうがスッキリして好きなのですが、listを使う方法も含めて検討してみます。 本当にありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問