0

この質問にはすでに答えがあります。

あなたのコードでは、あなたが開いたときFileMp3Readerという言葉を使うActionそして、メソッドであるLambda式を使用して内部に配置されます。

キーワードは何ですかAction? の中file.Create方法何が行われている?

var mp3Path = @"C:\Users\ronnie\Desktop\mp3\dotnetrocks_0717_alan_dahl_imagethink.mp3";
int splitLength = 120;


var mp3Dir = Path.GetDirectoryName(mp3Path);
var mp3File = Path.GetFileName(mp3Path);
var splitDir = Path.Combine(mp3Dir,Path.GetFileNameWithoutExtension(mp3Path));
Directory.CreateDirectory(splitDir);

int splitI = 0;
int secsOffset = 0;

using (var reader = new Mp3FileReader(mp3Path))
{   
    FileStream writer = null;      
    Action createWriter = new Action(() => {
        writer = File.Create(Path.Combine(splitDir,Path.ChangeExtension(mp3File,(++splitI).ToString("D4") + ".mp3")));
    });

    Mp3Frame frame;
    while ((frame = reader.ReadNextFrame()) != null)
    {           
        if (writer == null) createWriter();

        if ((int)reader.CurrentTime.TotalSeconds - secsOffset >= splitLength)
        {   

            writer.Dispose();
            createWriter();
            secsOffset = (int)reader.CurrentTime.TotalSeconds;              
        }

        writer.Write(frame.RawData, 0, frame.RawData.Length);
    }

    if(writer != null) writer.Dispose();
}


  • 単一のパラメータを持ち、値を返さないメソッドを表す型です。 - Khan
  • あなたはラムダ式とデリゲート型について学ぶ必要があります。 - SLaks
  • これは代理人です:msdn.microsoft.com/en-us/library/… - Guffa
  • キーワードではありません。これは単なる型の名前です。 - Servy

1 답변


1

コメントで述べたように、Actionこれがデリゲート型です。これは、変数宣言内での配置を考えると、おそらくコンテキストから多くの読者によって推論された可能性があります。 :)

のコードFile.Create()メソッドは単純に基づいて新しいファイル名を生成します。splitIインデックス。

皮肉なことに、この特定のケースでは、の使用Action余計です。デリゲートによって読みにくくなるため、コードは実際にはこのように書かれてはいけません。より良いバージョンはこのようになります:

using (var reader = new Mp3FileReader(mp3Path))
{
    FileStream writer = null;      

    try
    {
        Mp3Frame frame;
        while ((frame = reader.ReadNextFrame()) != null)
        {           
            if (writer != null &&
                (int)reader.CurrentTime.TotalSeconds - secsOffset >= splitLength)
            {   
                writer.Dispose();
                writer = null;
                secsOffset = (int)reader.CurrentTime.TotalSeconds;              
            }

            if (writer == null)
                writer = File.Create(Path.Combine(splitDir,
                    Path.ChangeExtension(mp3File,(++splitI).ToString("D4") + ".mp3")));

            writer.Write(frame.RawData, 0, frame.RawData.Length);
        }
    }
    finally
    {
        if(writer != null) writer.Dispose();
    }
}

そのようにして、新しいものをつくる仕事FileStreamインスタンスは一箇所でしか必要とされません。

たとえそれが2つの異なる場所からそれを呼び出すことが本当に必要であったとしても、私見この特定のシナリオは代わりに名前付きメソッドを要求するでしょう。このコードは、デリゲートインスタンスを使用するよりも読みやすくなっています。


  • 私はあなたがあなたとは違う何かをしていると思った、nvm。 - Servy
  • 私はこのコードについて多くの質問があるでしょうが、特に今私は持っています:このコード行で出力するとどうなるでしょうか?Path.ChangeExtension(mp3File,(++splitI).ToString("D4") + ".mp3"))); - missenna
  • @missenna:すみません、質問を理解できません。そのコード行は、元のコードから逐語的にコピーされます。私の例でも元のコードと同じことをしています。 - Peter Duniho
  • はい、あなたは正しいですが、問題は元のコードでも理解できないということです:) - missenna
  • ああ。まあ、それはまったく別の質問のようです。しかし、短いバージョンは:カウンターが維持されている(splitI)という形式のファイル名を作成するために使用されます。<original name>XXXX.mp3どこで<original name>もちろん元のファイルの名前です。XXXX書き込まれているセグメントの4桁のゼロ詰めインデックスであり、もちろん.mp3拡張子です。これにより、ループはオリジナルの単一のファイルを部分的なセグメントとして書き出すことができます。splitLengthすぐに。それ以上のものが必要な場合は、詳細を尋ねる別の質問を投稿してください。 - Peter Duniho

リンクされた質問


関連する質問

最近の質問