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

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

新規登録して質問してみよう
ただいま回答率
87.20%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

解決済

【C#】dialog.FileNameで取得した文字列で作成ファイル名を決定したい

gontya
gontya

総合スコア3

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

2回答

1評価

2クリップ

259閲覧

投稿2022/06/22 02:43

編集2022/06/23 13:22

前提・実現したいこと

お世話になります。
aes暗号化した際に出力されるファイル名をdialog.FileNameで取得した文字列で決定したいと考えています。

aes暗号化はできているため、作成ファイルの文字列を自由に設定できるようにする部分をご教授いただけますと幸いです。

試したこと

aes暗号化した際の出力ファイル設定を下記のように試しております。

  1. 出力パスを"C:/Users/Documents/test.aes"に設定

問題なくtestのaesファイルが作成される(ファイル名が可変ではないため要修正)

2 . 出力パスを System.IO.Path.GetFileNameで入力された文字列を読み取り、var aesName = filename.Replace("zip", "aes");で拡張子をaesに変更
暗号化ファイルが作成されない

文字列自体は1と同じだと思うので、ファイルが作成されない理由が分かりません。

該当コード

C#

//AES暗号化 private void AesSaveAsButton_Click(object sender, RoutedEventArgs e) { var dialog = new SaveFileDialog(); dialog.Filter = "zip|*.zip"; if (dialog.ShowDialog() == true) { var filename = System.IO.Path.GetFileName(dialog.FileName); var entryName = filename.Replace("zip", "json"); //var aesName = filename.Replace("zip", "aes"); //作成されないため一旦コメントアウト var json = JsonConvert.SerializeObject(_data, Formatting.Indented); // JSON 文字列からエンコーディング UTF-8 でバイト列を作成 var bytes = Encoding.UTF8.GetBytes(json); using (var ms = new MemoryStream()) { // メモリストリーム上にZipArchiveを作成する using (var zipArchive = new ZipArchive(ms, ZipArchiveMode.Create, true)) { var entry = zipArchive.CreateEntry(entryName); using (var es = entry.Open()) { // エントリにバイナリを書き込む es.Write(bytes, 0, bytes.Length); } } // MemoryStream からバイト列を取得してファイルを作成 byte[] zipBytes = ms.ToArray(); File.WriteAllBytes(dialog.FileName, zipBytes); Encode(dialog.FileName, "C:/Users/ユーザ名/Documents/test.aes"); //Encode(dialog.FileName, aesName); //出力されない } } } //AES複合化 private void AesOpenAsButton_Click(object sender, RoutedEventArgs e) { var dialog = new OpenFileDialog(); if (dialog.ShowDialog().Value) { Decode(dialog.FileName, "C:/Users/ユーザ名/Documents/test.aes");//←こちらも可変にする予定 var file = dialog.FileName; try { var reader = new StreamReader(file); var json = File.ReadAllText(dialog.FileName); reader.Close(); _data = JsonConvert.DeserializeObject<ObservableCollection<ManagementUnitData>>(json); } catch (Exception error) { if (error.Message != null) Debug.WriteLine(error.Message); } if (_data != null) { DataContext = _data; } } } //aes暗号化 /// <summary> /// 共有キー /// </summary> private const string AES_KEY = "-SENJU MURAMASA-"; /// <summary> /// バッファサイズ /// </summary> private const int BUFFER_SIZE = 1024 * 4; /// <summary> /// 共有キービットサイズ /// </summary> private const int KEY_SIZE = 128; /// <summary> /// 暗号操作のビットサイズ /// </summary> private const int BLOCK_SIZE = 128; /// <summary> /// 暗号化 /// </summary> /// <param name="src">入力ファイルパス</param> /// <param name="dst">出力ファイルパス</param> static public void Encode(string src, string dst) { //aes暗号化 using (AesManaged aes = new AesManaged()) { //AESインスタンスのパラメータ設定 aes.KeySize = KEY_SIZE; aes.BlockSize = BLOCK_SIZE; aes.Mode = CipherMode.CBC; aes.Key = Encoding.UTF8.GetBytes(AES_KEY); //初期ベクターの生成 aes.GenerateIV(); //暗号化オブジェクトの生成 ICryptoTransform ct = aes.CreateEncryptor(aes.Key, aes.IV); //出力ファイルストリーム using (FileStream outFs = new FileStream(dst, FileMode.Create, FileAccess.Write)) { //初期ベクター書き込み outFs.Write(aes.IV, 0, aes.IV.Length); //暗号変換のストリーム(暗号化) using (CryptoStream cs = new CryptoStream(outFs, ct , CryptoStreamMode.Write)) { //Deflateアルゴリズムを使用したストリーム(圧縮) using (DeflateStream ds = new DeflateStream(cs, CompressionMode.Compress)) { //入力ファイルストリーム using (FileStream inFs = new FileStream(src, FileMode.Open, FileAccess.Read)) { byte[] buf = new byte[BUFFER_SIZE]; for(int size = inFs.Read(buf, 0, buf.Length); size>0; size = inFs.Read(buf, 0, buf.Length)) { //出力ファイルへの書き込み ds.Write(buf, 0, size); } } } } } } } /// <summary> /// 複合化 /// </summary> /// <param name="src">入力ファイルパス</param> /// <param name="dst">出力ファイルパス</param> static public void Decode(string src, string dst) { // 高度暗号化標準(AES) using (AesManaged aes = new AesManaged()) { // AESインスタンスのパラメータ設定 aes.KeySize = KEY_SIZE; aes.BlockSize = BLOCK_SIZE; aes.Mode = CipherMode.CBC; aes.Key = Encoding.UTF8.GetBytes(AES_KEY); // 入力ファイルストリーム using (FileStream inFs = new FileStream(src, FileMode.Open, FileAccess.Read)) { // 初期化ベクター(IV)読込 byte[] iv = new byte[aes.IV.Length]; inFs.Read(iv, 0, iv.Length); aes.IV = iv; // 複合化オブジェクト生成 ICryptoTransform ct = aes.CreateDecryptor(aes.Key, aes.IV); // 暗号変換のストリーム(複合化) using (CryptoStream cs = new CryptoStream(inFs, ct, CryptoStreamMode.Read)) { // Deflateアルゴリズムを使用したストリーム(圧縮解除) using (DeflateStream ds = new DeflateStream(cs, CompressionMode.Decompress)) { // 出力ファイルストリーム using (FileStream outFs = new FileStream(dst, FileMode.Create, FileAccess.Write)) { // 複合化した結果を書き込む byte[] buf = new byte[BUFFER_SIZE]; for (int size = ds.Read(buf, 0, buf.Length); size > 0; size = ds.Read(buf, 0, buf.Length)) { outFs.Write(buf, 0, size); } } } } } } }

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

Zuishin

2022/06/22 03:04 編集

> "C:/Users/Documents/test.aes" エスケープしてませんが、これで > →問題なくtestのaesファイルが作成される(ファイル名が可変ではないため要修正) なのでしょうか? まあ本題はディレクトリ名部分をなぜか削除しているところだと思いますが。
dodox86

2022/06/22 03:10

提示のコードが > var entryName = filename.Replace("zip", "json"); > //var aesName = filename.Replace("zip", "aes"); //作成されないため一旦コメントアウト ... > var entry = zipArchive.CreateEntry(entryName); ... > Encode(dialog.FileName, "C:/Users/Documents/test.aes"); > //Encode(dialog.FileName, aesName); //出力されない などとなっていて、ところどころ利用している変数名が合致していないような気がします。 確認用に変更しているだけかもしれませんが、実はそこを間違っていた、なんてことはないですか。
gontya

2022/06/22 03:34

> まあ本題はディレクトリ名部分をなぜか削除しているところだと思いますが。 仰る通り、ディレクトリを一部消去しておりました。(コード上では入っています。) 下記を編集し追加させていただきます。 "C:/Users/ユーザ名/Documents/test.aes"
Zuishin

2022/06/22 03:43 編集

そうではなく、System.IO.Path.GetFileName を使ってディレクトリ名を削除しているという意味です。 filename は結局このコードでは捨てられていますが、おそらく本番では使われているんでしょう?
Zuishin

2022/06/22 03:52

よく読んでいませんでした。entryname として zip に登録するのに使われているのでディレクトリ名は要りませんね。
gontya

2022/06/22 04:53

>Zuishinさん アドバイスいただきありがとうございます。 System.IO.Path.GetFileNameの仕様を勘違いしておりました。 ディレクトリ名を削除しないGetDirectoryName()メソッドを使用するべきでした。
dekaaki

2022/06/22 09:45

ちょっと補足です。 回答者さんのソースで拡張子を変更したいことは分かるのですが、単純な置換を使用すると"zip"という文字が含まれるファイル名(例えばZipper.zip)を選択された場合に誤った変換になると思います。 拡張子の変換メソッドが用意されてますのでそちらを使用する方がいいと思います。 https://dobon.net/vb/dotnet/file/changeextension.html
gontya

2022/06/23 04:22 編集

>dekaakiさん そうですね、汎用的な形にするのであればこちらの方が有効ですね。 補足ありがとうございます!

まだ回答がついていません

会員登録して回答してみよう

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

ただいまの回答率
87.20%

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

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

質問する

関連した質問

同じタグがついた質問を見る

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。