0

This question already has an answer here:

In your code, when you open the FileMp3Reader, uses the word Action and then placed inside by using a Lambda expression, a method.

What does the keyword Action? Inside the file.Create method what is being done?

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();
}


  • Its a type that represents a method that has a single parameter and does not return a value. - Khan
  • You need to learn about lambda expressions and delegate types. - SLaks
  • It's a delegate: msdn.microsoft.com/en-us/library/… - Guffa
  • It's not a keyword. It's just the name of a type. - Servy

1 답변


1

As noted in the comments, Action here is a delegate type. Which, given it's placement in the variable declaration, probably could have been inferred by many readers from the context. :)

The code in the File.Create() method simply generates a new file name based on the splitI index.

Ironically, in this particular case, the use of Action is superfluous. The code really should not have been written this way, as the delegate just makes it harder to read. A better version looks like this:

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();
    }
}

That way, the work to create a new FileStream instance is only ever needed in one place.

Even if it were really required to call it from two different places, IMHO this particular scenario would call for named method instead. The code would have been more readable that way, than using the delegate instance.


  • I thought you were doing something different than you were, nvm. - Servy
  • I would have many questions about this code, but especially now I have: Output with this line of code what would it be? Path.ChangeExtension(mp3File,(++splitI).ToString("D4") + ".mp3"))); - missenna
  • @missenna: sorry, I don't understand the question. That line of code is copied verbatim from the original code. It's does the same thing in my example as it did in the original code. - Peter Duniho
  • Yes, you're right, but the problem is I do not understand either in the original code:) - missenna
  • Ah. Well, that seems like a whole different question. But the short version is: there is a counter maintained (splitI), which is used to create file names of the form <original name>XXXX.mp3 where <original name> is of course the name of the original file, XXXX is the four-digit, zero-padding index of the segment being written, and of course .mp3 is the extension. This allows the loop to write out the original single file, as partial segments, each an MP3 clip no longer than splitLength in seconds. If you need more than that, you should post another question asking for specifics - Peter Duniho

Linked


Related

Latest