トップ回答者
C# ファイルの保存と読み出し時にアクセス先のフォルダや拡張子を指定したいです。

質問
-
Visual Studio Community 2017 Version15.7.2 を使っております。初心者です。テキストボックスなどの値をCSVファイルで保存したり読みだしてテキストボックスに入れるなどのプログラムをネットで検索したものをコピーして使っています。この際に追加でやりたい機能があります。
①保存の際にファイル名と拡張子を任意で指定したいです。
保存のダイアログ画面が開いた時ファイル名が常に空欄になっています。既存のファイルを触れば済むことなのですがお客が嫌だと言います。
空欄.csv と常になっていて欲しいようです。
②最後に読み出したフォルダを常に読み出しに行きたいです。
保存の方は最後のアクセス先を覚えているようですが読み出しの方はいつも Cドライブを読みに行きファイル名にはdefault.htmlと書かれます。
調べては見るものの基本の機能を理解出来ていないため難しいです。
今のプログラムに何か行を追加すれば出来るのでしょうか。
質問には必要ない箇所もあるかと思いますが今のプログラムを貼ります。
どうかよろしくお願い致します。
【保存のプログラム】
// パラメータ保存
private void Save_data()
{
string[] save_data = new string[Varu_PARA + 4];// データ格納用for (int i = 0; i < Varu_PARA + 4; i++) {save_data[i] = PARA[i]; }
SaveFileDialog sfd = new SaveFileDialog(); //SaveFileDialogクラスのインスタンスを作成
if (sfd.ShowDialog() == DialogResult.OK) //ダイアログを表示する
{
System.IO.Stream stream;
stream = sfd.OpenFile();
if (stream != null)
{
//ファイルに書き込む
System.IO.StreamWriter sw = new System.IO.StreamWriter(stream);for (int i = 0; i < Varu_PARA; i++)
{
if (i < 16) { sw.Write(save_data[i]); sw.Write("\n"); }
else
{
// checkBoxの状態をセル毎に保存
var cb = (CheckBox)Controls[$"checkBox{i -15}"];
sw.Write("{0},", Convert.ToInt32(cb.Checked));
sw.Write("\n");
}
}
sw.Write(save_data[29]); sw.Write("\n");
sw.Write(save_data[30]); sw.Write("\n");
sw.Write(save_data[31]); sw.Write("\n");
sw.Write(save_data[32]); sw.Write("\n");//閉じる
sw.Close();
stream.Close();
}
}
}【読み出しのプログラム】
// パラメータ保存
private void Road_para()
{
//OpenFileDialogクラスのインスタンスを作成
OpenFileDialog ofd = new OpenFileDialog();//はじめのファイル名を指定する
//はじめに「ファイル名」で表示される文字列を指定する
ofd.FileName = "default.html";
//はじめに表示されるフォルダを指定する
//指定しない(空の文字列)の時は、現在のディレクトリが表示される
ofd.InitialDirectory = @"C:\";
//[ファイルの種類]に表示される選択肢を指定する
//指定しないとすべてのファイルが表示される
ofd.Filter = "HTMLファイル(*.html;*.htm)|*.html;*.htm|すべてのファイル(*.*)|*.*";
//[ファイルの種類]ではじめに選択されるものを指定する
//2番目の「すべてのファイル」が選択されているようにする
ofd.FilterIndex = 2;
//タイトルを設定する
ofd.Title = "開くファイルを選択してください";
//ダイアログボックスを閉じる前に現在のディレクトリを復元するようにする
ofd.RestoreDirectory = true;
//存在しないファイルの名前が指定されたとき警告を表示する
//デフォルトでTrueなので指定する必要はない
ofd.CheckFileExists = true;
//存在しないパスが指定されたとき警告を表示する
//デフォルトでTrueなので指定する必要はない
ofd.CheckPathExists = true;//ダイアログを表示する
if (ofd.ShowDialog() == DialogResult.OK)
{
//読み込むテキストファイル
string textFile = ofd.FileName;
StreamReader sr = new StreamReader(textFile, Encoding.GetEncoding("Shift_JIS"));try
{
int i;
i = 0;//while (sr.EndOfStream == false)
for(i = 0;i < Varu_PARA + 4; i ++)
{
string line = sr.ReadLine();
string[] fields = line.Split(',');
if (i < 16) { Controls[$"TextBox{i + 1}"].Text = fields[0]; }
switch (i)
{
case 16: if (fields[0] == "1") { checkBox1.Checked = true; } else { checkBox1.Checked = false; } break;
case 17: if (fields[0] == "1") { checkBox2.Checked = true; } else { checkBox2.Checked = false; } break;
case 18: if (fields[0] == "1") { checkBox3.Checked = true; } else { checkBox3.Checked = false; } break;
case 19: if (fields[0] == "1") { checkBox4.Checked = true; } else { checkBox4.Checked = false; } break;
case 20: if (fields[0] == "1") { checkBox5.Checked = true; } else { checkBox5.Checked = false; } break;
case 21: if (fields[0] == "1") { checkBox6.Checked = true; } else { checkBox6.Checked = false; } break;
case 22: if (fields[0] == "1") { checkBox7.Checked = true; } else { checkBox7.Checked = false; } break;
case 23: if (fields[0] == "1") { checkBox8.Checked = true; } else { checkBox8.Checked = false; } break;
case 24: if (fields[0] == "1") { checkBox9.Checked = true; } else { checkBox9.Checked = false; } break;
case 25: if (fields[0] == "1") { checkBox10.Checked = true; } else { checkBox10.Checked = false; } break;
case 26: if (fields[0] == "1") { checkBox11.Checked = true; } else { checkBox11.Checked = false; } break;
case 27: if (fields[0] == "1") { checkBox12.Checked = true; } else { checkBox12.Checked = false; } break;
case 28: if (fields[0] == "1") { checkBox13.Checked = true; } else { checkBox13.Checked = false; } break;
// PARA 追加分
case 29: if (fields[0] == "1") { radioButton1.Checked = true; } else { radioButton1.Checked = false; } break;
case 30: if (fields[0] == "1") { radioButton2.Checked = true; } else { radioButton2.Checked = false; } break;
case 31: comboBox1.Text = fields[0]; break;
case 32: comboBox2.Text = fields[0]; break;
}
}
}
finally
{
sr.Close();
}
}
}
回答
-
①に関しては、SaveFileDialogのFileNameプロパティにセットすれば良いです。
sfd.FileName = "空欄.csv";
②に関しては、最後に読みだしたフォルダを覚えて置き、それをOpenFileDialogを開く際にセットすれば良いでしょう。
最後に読みだしたフォルダを記録するには、以下を参考にしてみて下さい。Visual Studioでアプリケーションの設定を保存する
https://dobon.net/vb/dotnet/programing/mysettings.htmlところで上記には続きがあります。ソースをネットで検索することは良いことだと思いますが、それをそのまま使わずに100%理解して使うようにしないとプログラミング力が上がりません。①のsfd.FileNameに関しては、②のOpenFileDialogに関するソースを理解していれば、容易に気が付くことだと思います。
また、②のソースに、
ofd.InitialDirectory = @"C:\";
と書かれているので、必ずCドライブのルートを開いてしまいます。まずはこの行を消してみて下さい。それだけでユーザーの要求に答えられるかもしれません。★良い回答には質問者は回答済みマークを、閲覧者は投票を!
- 回答としてマーク kinto-to-clave 2019年4月23日 6:55
すべての返信
-
①に関しては、SaveFileDialogのFileNameプロパティにセットすれば良いです。
sfd.FileName = "空欄.csv";
②に関しては、最後に読みだしたフォルダを覚えて置き、それをOpenFileDialogを開く際にセットすれば良いでしょう。
最後に読みだしたフォルダを記録するには、以下を参考にしてみて下さい。Visual Studioでアプリケーションの設定を保存する
https://dobon.net/vb/dotnet/programing/mysettings.htmlところで上記には続きがあります。ソースをネットで検索することは良いことだと思いますが、それをそのまま使わずに100%理解して使うようにしないとプログラミング力が上がりません。①のsfd.FileNameに関しては、②のOpenFileDialogに関するソースを理解していれば、容易に気が付くことだと思います。
また、②のソースに、
ofd.InitialDirectory = @"C:\";
と書かれているので、必ずCドライブのルートを開いてしまいます。まずはこの行を消してみて下さい。それだけでユーザーの要求に答えられるかもしれません。★良い回答には質問者は回答済みマークを、閲覧者は投票を!
- 回答としてマーク kinto-to-clave 2019年4月23日 6:55
-
【読み出し】
読み出した時に、default.htmlと表示される問題は、
ofd.FileName = "default.html"; と書かれている部分を削除するか、//ofd.FileName = "default.html"; と書き換えて下さい。←この処理でdefault.htmlと表示されなくなります。
ofd.InitialDirectory = @"C:\"; ←間違ってます。
ofd.InitialDirectory = "C:\\";に書き直して下さい。
試しに、ofd.InitialDirectory = "C:\";と書かれている部分を
ofd.InitialDirectory = "C:\\Users\\User\\Documents"; に書き換えると、ドキュメントフォルダーを最初に開く様になります。但し、二個目のUserは、僕の環境です。ここは、君のパソコンの使用者名に書き換えて下さい。
【保存】
saveFileDialog.RestoreDirectory = true; ←で、ディレクトリーを記録できます。
↑これをtrueにするならば、//saveFileDialog1.InitialDirectory = "C:\\Users\\User\\Documents";と記述する事。但し、二個目のUserは、僕の環境です。ここは、君のパソコンの使用者名に書き換えて下さい。
saveFileDialog.DefaultExt = "csv"; ←で、自動的に負荷する場合の拡張子の指定
saveFileDialog.AddExtension = true; ←で、拡張子を自動的に負荷する。これを記述しても、.csvとは表示されませんが、書かれていない場合は、付加されます。
saveFileDialog.Filter = "全てのファイル(*.*)|*.*"; ←で、すべてのファイルを表示する
saveFileDialog.ShowDialog(); ←で、ダイアログを表示
saveFileDialog.InitialDirectory = "C:\\Users\\User\\Documents"; ←で、開いた時に、表示するディレクトリーを指定できます。この場合は、常にドキュメントフォルダーになります。
【蛇足だけど、一番重要】
後、物凄く危険なプログラムになっています。
書き込んだ後の後処理に必ず、Flush();しないとWindowsが壊れます。
Close();する前に、必ず、Flush();して下さい。
保存の最後の処理です。
//閉じる
sw.Close();
stream.Close();
となっていますが、ここを以下の様に書き換えて下さい。
//閉じる
sw.Flush();
sw.Close();
【 最重要 著作権について 】
誰かが公開しているプログラムソースには、著作権があります。どこのホームページのプログラムを書き換えて使っているのかを明示する必要があります。
著作権者に告訴された場合大変な事になる場合があります。
- 編集済み Wupu One 2019年4月19日 7:42
-
Close()する前に、必ず、Flush()して下さい、という理由はなんでしょうか? 小生は、Close()と書くだけでFlush()も行われると理解しています。もし間違っていたらご教示ください。
Flush()しないとWindowsが壊れます、という理由はなんでしょうか? バッファにデータが溜まったまま何らかの理由で書き込みが中断されたとして、小生は、当該ファイルにそのデータは書き込まれないことになりますが、Windowsのシステムとは無関係であると理解しています。もし間違っていたらご教示ください。- 編集済み 外池 2019年4月19日 1:00
-
外池さんの指摘の通りでWupu Oneさんの
後、物凄く危険なプログラムになっています。
書き込んだ後の後処理に必ず、Flush();しないとWindowsが壊れます。
Close();する前に、必ず、Flush();して下さい。この記述は明確な誤りです。StreamWriterのCloseはDisposeを呼びますが、Dispose内でFlushを呼び出しています。ですので明示的にFlushを呼び出しても無駄な処理でしかなく、なにも改善しません。なお、C#言語のusingステートメントを使用すれば自動的にDisposeが呼ばれるため、FlushやCloseの明示的な記述が不要になります。
-
> ①保存の際にファイル名と拡張子を任意で指定したいです。空欄.csv と常になっていて欲しいようです。
> ②最後に読み出したフォルダを常に読み出しに行きたいです。上記の「空欄.csv」というのが以下の画像の赤枠のような表示で良いなら、
上に引用した質問者さんのやりたいことだけは、以下のようにしてできるのでは?
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.IO; namespace WindowsFormsApplication1 { public partial class Form2 : Form { public Form2() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { Stream myStream; OpenFileDialog openFileDialog1 = new OpenFileDialog(); openFileDialog1.RestoreDirectory = true; openFileDialog1.Filter = "csv files (*.csv)|*.csv"; if (openFileDialog1.ShowDialog() == DialogResult.OK) { if ((myStream = openFileDialog1.OpenFile()) != null) { using (myStream) { // 処理 } } } } private void button2_Click(object sender, EventArgs e) { Stream myStream; SaveFileDialog saveFileDialog1 = new SaveFileDialog(); saveFileDialog1.RestoreDirectory = true; saveFileDialog1.FileName = ".csv"; saveFileDialog1.Filter = "csv files (*.csv)|*.csv"; if (saveFileDialog1.ShowDialog() == DialogResult.OK) { if ((myStream = saveFileDialog1.OpenFile()) != null) { using (myStream) { // 処理 } } } } } }
これでは期待した通りにならないなら、どこがどう期待と違うのか具体的に書いてください。
-
Windowsが壊れる理由は知りません。
マイクロソフトの解説書に、後処理に、FlushとCloseをしなさい。と書かれいます。実際、バグで、書き込み処理途中でデバッグで引っかかると、保存ができなくなると言う状態になっています。
C#のみならず、Javaでも、非常に危険なので必ずtryでエラーを補足する事と、Flushをする事と説明しているのが普通です。
また、間違っていると指摘した事が間違っている様でしたら、申し訳ありませんでした。しかし、間違っていると確信していない本人には、分からない事です。
とんでもなく、失礼な言い回しだとおもいませんか?
間違っている事が、分かっていない人にとって、断定的な発言をするなとは、どういう事をですか?
間違っている可能性があると、あやふやな思いがあれば、あやふやだと書きます。当然です。あなたは、他人の気持ちを考えることができない様ですね。失礼な人間だ。
責任ですか?
なんでか?
親切で回答してあげているだけですよ。
間違っている事も、あるかもしれない。しかし、回答した内容そのものは、問題ないと思いますよ。僕言う通りに書き換えたら、動かない!と言う状態になるなら、大きな問題と言うか、大変、申し訳ない回答だと言うますけど。
変な言いがかりに近いね反駁、物凄く遺憾に思っております。
-
ofd.InitialDirectory = @"C:\"; ←間違ってます。
ofd.InitialDirectory = "C:\\";に書き直して下さい。外池さんも指摘されていますが、この訂正を求める記述も明確に間違っています。
C#言語には逐語的文字列リテラル(verbatim string literal)という機能があり、 @"C:\" と "C:\\" は同じ意味です。
-
実際、バグで、書き込み処理途中でデバッグで引っかかると、保存ができなくなると言う状態になっています。
例示されているケース(デバッグ実行中にブレークした場合にその時点までの書き込みが反映されない)はそうですね。
ただ、Flush したところで、Windows OS のキャッシュから実際にディスクに反映されるまでの隙間もあるので、極限の状況での確実性を求める場合は単なる Flush だけでは足らないこともあります。
また、デバッグ中にブレークした(一時停止した、強制的に終了させた)場合のケアはどちらかと言えば不要なケースが多いでしょう。どこで一時停止しても完全な動作を保障することは不可能なので、考えても仕方ない領域に属することが多いためです。C#のみならず、Javaでも、非常に危険なので必ずtryでエラーを補足する事と、Flushをする事と説明しているのが普通です。
普通かどうかは出典がないのでコメントしかねますが、「非常に危険かどうか」は場合によります。大抵はうまく動きますし、それで困るケースは少ないでしょう。
(本当に危険なのであれば、新しいフレームワークであればあるほど、それを自動的に実行する、隠蔽することで間違わないようにすることが正しいでしょうから)親切で回答してあげているだけですよ。
間違っている事も、あるかもしれない。しかし、回答した内容そのものは、問題ないと思いますよ。僕言う通りに書き換えたら、動かない!と言う状態になるなら、大きな問題と言うか、大変、申し訳ない回答だと言うますけど。
別スレッド で質問されている立場だと思いますが、「間違った情報を断定的に書かれて、それを信じた結果、後で不具合につながった」場合や「正しいコードとして提示された内容が冗長なコードであったとわかった」場合に、どう感じますか?
提示してもらったコードを調査して裏付けを取る、検証するというアクションが身についている人なら問題ないですが、フォーラムで質問される方はそうでないケースが多いですし、初心者と言える領域に対しては正しく検証するための知識・経験が伴わないので、受け身になりがちです。
それはあなた自身が 別スレッド で主張されているようなのでご理解いただいているものと思っています。
質問者に考えるきっかけを与える、調べ方の断片を示すという意味でも、出典は明示した方が良いでしょう。また、技術的な議論において、感情を持ち込むのはやめた方が良いです。
感情を持ち込んでも、誰にとっても有益ではなく、第三の読者からしても気分の良いものではないためです。
冷静に、理性的に、指摘された事実を受け入れるか、根拠を示して反論するかしましょう。
(感情的に反応したくなる部分はぐっと我慢して捨て置くか、フォーラムオペレーターに采配を求めるために、不適切な発言として報告するか。技術者は論理的に批判することが多いので、冷たい言葉や攻撃的になりがちなのは技術者の悪癖かなぁ?)- 編集済み AzuleanMVP, Moderator 2019年4月24日 12:41
-
ご自身達は、全然、出所をかかないんですね。説明だけで、でたらめな説明なら、誰にでもできます。
FLUSHに関しては、
発行 日経BBソフトプレス
プログラミング VisualC#.NET マイクロソフト公式解説書
著者 Mickey Williams
と言う書籍に記載されています。
Javaに関しては、
Eclipse4.5ではじめるJavaプログラミング入門Eclipse4.5Mars対応
出帆 秀和システム
著者 掌田 津耶乃
と言う書籍に書かれています。
加えて、以下の書籍にも書かれています。
プログラミング
Visual Basic.NET Vol.1 基礎編 マイクロソフト公式解説書
発行 日経BPソフトプレス
著者 Francwsco Balena
プログラミング Visual Basic.NET Vol.2活用編 マイクロソフト公式解説書
発行 日経BPソフトプレス
著者 Francwsco Balena
に、Closeの前に、かならず、Floshして下さいと書かれています。
改めて他の書籍も探しましたところ、
出帆 インプレス
C# 実践プログラミング
著者 アクロバイト監修/鶯谷 好輝
には、Closeだけで、処理するルーチンがありました。→正確ではない記述だと僕は、信じています。この書籍のサンプルプログラムは、動作しないプログラムが多かったので信頼できないのです。- 編集済み Wupu One 2019年4月27日 7:27
-
それらの書籍は仕様書ではなく、著者の解釈による解説書なので、「しなければならない」と主張するための根拠として弱いと思います。「した方が良いとする書籍がある」とするならわかりますが・・・。
「しなければならない」とするためには、.NET Framework をリリースしている Microsoft 自身が公開しているドキュメント、あるいは実装内容など、オフィシャルの情報が必要でしょう。
現行の .NET Framework のオフィシャルなドキュメントは docs.microsoft.com で公開されています。
なお、この投稿は、私はこう考えるという意図の発露であり、責める意図や回答を求めるものではありません。
話題の StreamWriter.Flush や StreamWriter.Close を読むと "Flushing the stream will not flush its underlying encoder unless you explicitly call Flush or Close." とあるので、Flush か Close を呼べば良いということになります。
この記載を出典とする限り、StreamWriter に対して「Close の前に Flush しなければならない」というセンテンスに対して賛同しづらく、「Flush、または Close しなければならない」には賛同できます。あるいは、「いろいろなプラットフォーム・クラスライブラリの違いに備える意識付けとして、念のために Flush して Close することを癖づけた方が良い」という主張なら理解できます。
そういう主張・考え方があると捉えていただければ。
(得るものがないというのであれば、放置して構いません。その場合は主義主張の平行線ということになりそうなので)- 編集済み AzuleanMVP, Moderator 2019年4月27日 8:32
-
わんくま同盟さんのWebサイト拝見させていただいております。
ドライブのセクター読み込みの処理ルーチンを探していた時に、あなた方のWebサイトを発見して、読ませていただきました。
全く、動作していない処理ルーチンでしたと言う事をご報告いたします。
もっと、ちゃんと書いて下さい。
誰にも質問せずに、ドライブのセクター読み込みの処理ルーチンは、僕のパソコンで動かす事に成功しております。
他のスレッドで、書き込み方法を質問している僕の書き込みを見て、物凄く、悔しかったのだと言う事が解りました。
それにしても、嫌がらせ、すさまじいとしか言いようがないですね。
-
まずJavaは言語及びランタイムが異なるため無関係として除外します。また挙げられた書籍はいずれも所有していないため、Amazonのなか見!検索で調べた範囲ですが…
プログラミング VisualC#.NETについては、原書での検索となりましたがflushで検索しヒットした8ヶ所いずれもClose前にflushを勧めてはいませんでしたし、ましてやWindowsが壊れるとは記述されていませんでした。
プログラミング Visual Basic.NET Vol.1 基礎編については、4ヶ所ヒットしましたが同様でした。それどころかP.493には
データはバッファに保存され、ストリームが閉じられたとき、またはプログラムによって明示的にFlushメソッドを発行したときに、最終的にディスクに書き込まれ、バッファがクリアされます。
とあり、Flushメソッドを発行したときだけでなく、ストリームが閉じられときにもデータがディスクに書き込まれることが明示されています。プログラミング Visual Basic .NET Vol.2 活用編については検索することができませんでしたが、Vol.1と矛盾する記述があるとは思えません。
Wupu Oneさんは「書き込んだ後の後処理に必ず、Flush();しないとWindowsが壊れます。」と主張されるのであれば、出典及び具体的な記述を引用して説明してください。
- 編集済み 佐祐理 2019年4月27日 8:53
-
StreamWriter.Flushのページ冒頭に「Clears all buffers for the current writer and causes any buffered data to be written to the underlying stream.」とあります。一応、念のために英語の文法も解説しておくと、clearsとcausesが動詞であって、三人称単数の形になっています。つまり、省略された主語があるわけですが、ここではFlushメソッドが主語であって、その動作を述べているものです。原型の動詞になっていないので、読者に命令しているものではないです。で、casuses以下の記述に留意しつつ・・・、
StreamWriter.Closeのページを調べます。冒頭にはCloseするとしか書かれていないのですが、注釈に「This implementation of Close calls the Dispose method passing a
true
value.」とあります。では、StreamWriter.Disposeのページを調べると、冒頭の動作定義に「Causes any buffered data to be written to the underlying stream, releases the unmanaged resources used by the StreamWriter, and optionally the managed resources.」とあります。先に留意していたFlushの動作と同じことが書かれています。
以上は、佐祐理さんのご説明及び示された実装と一致していますし、当初に小生がCloseの前にFlushする必要はないと主張した根拠です。(なお、Azuleanさんが引用した内容は、残念ながら小生は本件と無関係と考えています。StreamWriterのFlushメソッドと、StreamWriterに紐づけられたEncoderの状態変化のことを述べているだけかと。)
-
> "@C:\"を"C:\\"と
細かい話ですが、こちらは、 @ が文字列中に入っています。 こんなパスは無いですね。 @ は文字列の外 (@"c:\") で指定です。
flash()の件は、既に指摘がありますが、普通は書かない。 (昔は知らずに書いた事もあるが)
ただ、デバッグ等で、close()前に中断する事がある場合は、書くです。 書いた方が安全、という話は多々ありますが、その多くは無駄。 (実際のソースを見ても、close()の中に、flash()があります。)
根拠としては、例えば、この辺 (TextWriter.Close Method )でしょうか?
日本語凄く、怪しいですが、「flash または、close」を明示的に呼ばないと、書き込まれないと読めます。 -
こ但し、コンパイラにコピペして記述し、確認したところ、エラー表示された部分です。僕自身で、"@C:\"を"C:\\"と書き換えたのを記憶しています。
pepperleaf01さんが軽く触れられていますが、補足で。質問者さんが書いたコードは @"C:\" です。これは既に返信したように逐語的文字列リテラルであり正しいです。一方、Wupu Oneさんがコピペして試したと主張されたコードは "@C:\" のようです。これは通常の文字列リテラルで \" の部分は文字列終端を表す " がエスケープされてしまい、文字列が終端されていないことになります。結果、コンパイラーは構文エラーを報告します。つまり、Wupu Oneさんがコピペミスしたに過ぎません。
しかし、この部分の書き方が間違っているからと言って、この間違ったコードで動作しないと言う事はないと思います。
書き方の違いで、他方の書き方では動作しないでしかない事をここまで、猛烈に批判されなければならない理由ってなんですか?
ちょっと、おかしいと思います。2019年4月23日 5:31の私の投稿をよく読み返してください。コードの書き方が誤っているとは主張していません。
言語仕様としては @"C:\" と "C:\\" どちらも正しいです。その上で、質問者さんは @"C:\" と記述しました。何ら問題ありません。その上で、Wupu Oneさんは2019年4月18日 22:29の投稿で
> ofd.InitialDirectory = @"C:\"; ←間違ってます。
> ofd.InitialDirectory = "C:\\";に書き直して下さい。とされています。本来正しいはずの @"C:\" が「間違ってます」と主張されています。私はWupu Oneさんのこの主張が間違っており、 @"C:\" と "C:\\" どちらも正しいと指摘したに過ぎません。
つまり、どちらの記述も正しいはずなのに、一方を間違いだと断定され猛烈に批判されているは質問者さんであり、猛烈に批判しているのはWupu Oneさんご自身だということを自覚してください。
-
Wupu Oneさんとの価値観の違いを明確にすると良いのかもしれません。
Wupu Oneさんは、正しく動くコードの提示が最優先事項であり、正しく動くコードの提示が価値があり、それ以外は無価値と考えておられるようです。
正しく動くコードを提示できることが良いことには違いないです。しかし・・・、
Wupu Oneさんは仰天されるでしょうけれども、小生も、あと、小生の信じるところではWupu Oneさんに批判的コメント書いている他のみなさんも(僭越ながら、以下「小生ら」と書きます。ご異論あれば甘受します。)、正しく動くコードを提示することを最優先事項と捉えていません。過去の「回答」には「動作は検証していませんが、考え方としては、流れとしては、こんな感じ」というコードの提示や、コードは提示せずに言葉だけで考え方を提示したものが多数存在します。
小生らが最優先事項と考え、価値があると考えることは、どうしてそういうコードの書き方になるのか理解が普及することです。コードの一字一句の正しさのチェックはコンパイラがやってくれますので、ココでは実のところどうでも良いのです。コンパイルが通った後の実行時の動作や影響について、理由とともに正しい理解が普及することが重要と考えます。コードを提示する場合も、コンピュータに放り込むこと(動くかどうか)は二の次であって、ここの利用者自身が読んで理解することを第一に想定し、日本語で書くと面倒だし、論理がアヤフヤになるからです。したがって、Wupu Oneさんが「Windowsが壊れます」という事実だとすれば大変重要な内容を、理由を知らずに(Wupu Oneさん自身が仰っている)、出典を示さずに(書籍は示されても、どこにそう書いてあるか未だ示されていない)、主張されたことを小生は疑問視しているのです。
FlushせずにCloseすることでWindowsが壊れることがある理由を、少なくとも実例を、適切に示していただければ良いのです。できないなら、これはデマ(理由もなく誤った情報を伝えること)の類であって、上述の価値観に照らして小生らが最も避けたいこと(猛烈に批判する対象)になります。
本来の質問内容(ある拡張子だけに限定してファイル選択ダイアログの使い勝手を良くする方法)とは無関係なことをわざわざ提示されたのだから、Wupu Oneさんは重要なことだと考えられたわけですよね? それはそれで結構なのですが、なおさら「本当ですか?」という問いにさらされることになります。
.Net Frameworkに限らずWindowsの基本的な構造おいて、アプリケーションの不具合がWindowsのOS動作に影響しないようにする努力が払われています。アプリケーション独自のファイルへの書き出しが滞ったところで、WindowsのOS動作への影響はプログラマが心配する(責任を持つべき)ことではないです。(アプリケーションがシステムディスク容量を使い切るまでファイルを書いてしまう不具合は、プログラマの責任になります。メモリ、CPUタイム、通信回線等のリソースを圧迫するような事態はみなそうですが。)
- 編集済み 外池 2019年4月28日 1:33
-
僕が、最重要として、書き込んだ質問とは、関係ない記述に関する説明です。
最重要として書き込んだ回答は、著作権違反に関する助言です。
個人使用は、許されています。なので、ソフトウェアに使用していても全く問題ない事です。
また、商用仕様でも、公開されているプログラムを使用しても問題にはなりません。使用される事を前提に公開しているからです。
しかし、コピーしたプログラムを自分の著作物の様に著作権者を明示しないで公開すると問題になる恐れがあります。特に、使用用利用の場合は、注意を要する事です。
特許に抵触する技術は、特許法で規定されている通りになります。著作権も著作権法通りとなります。
貴方が、技術的に低いレベルかどうかと言う問題ではなくて、「お客さんが」と書いている事から、商用のプロである事がうかがえます。後で、「お客さんが」を訂正していますが、この訂正は、無視します。
格好付ける理由が無いからです。
僕は、貴方が販売しているソフトウエアを著作権違反だと言いたいのではありません。僕は、無断使用している可能性のある貴方のソフトウェアの著作権者ではありません。
著作権違反の警告も、訴訟もする権利を持っておりません。
あらぬ誤解を受けないようにしておく事が重要だと助言しただけです。
- 編集済み Wupu One 2019年4月28日 7:22