我有一個(gè)Active wave錄制wave-file.wav發(fā)生在Source文件夾中. 我需要使用新名稱wave-file-copy.wav將此文件復(fù)制到Destination文件夾.
錄制和復(fù)制應(yīng)該并行進(jìn)行. 我已經(jīng)實(shí)現(xiàn)了一個(gè)預(yù)定的作業(yè),它將每10分鐘運(yùn)行一次,并將源文件復(fù)制到目標(biāo).
private static void CopyWaveFile(string destinationFile, string sourceFile){
using (var fs = File.Open(sourceFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)){
using (var reader = new WaveFileReader(fs)){
using (var writer = new WaveFileWriter(destinationFile, reader.WaveFormat)){
reader.Position = 0;
var endPos = (int)reader.Length;
var buffer = new byte[1024];
while (reader.Position < endPos){
var bytesRequired = (int)(endPos - reader.Position);
if (bytesRequired <= 0) continue;
var bytesToRead = Math.Min(bytesRequired, buffer.Length);
var bytesRead = reader.Read(buffer, 0, bytesToRead);
if (bytesRead > 0){
writer.Write(buffer, 0, bytesRead);
}
}
}
}
}
}
即使源文件正在不斷更新,復(fù)制操作也能正常工作.
復(fù)制操作所花費(fèi)的時(shí)間在線性時(shí)間內(nèi)增加,因?yàn)槲颐看味紡?fù)制整個(gè)文件.
我正在嘗試實(shí)現(xiàn)一個(gè)新函數(shù)ConcatenateWavFiles(),它應(yīng)該使用最新的源記錄字節(jié)來(lái)更新目標(biāo)文件的內(nèi)容.
我嘗試過(guò)幾個(gè)示例代碼 – 我使用的方法是:
>讀取目標(biāo)文件元信息,并獲取長(zhǎng)度. >將目標(biāo)文件的長(zhǎng)度設(shè)置為reader.源文件waveReader的位置 >從位置開(kāi)始讀取源文件直到結(jié)束.
public static void ConcatenateWavFiles(string destinationFile, string sourceFile){
WaveFileWriter waveFileWriter = null;
var sourceReadOffset = GetWaveFileSize(destinationFile);
try{
using (var fs = File.Open(sourceFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
using (var reader = new WaveFileReader(fs))
{
waveFileWriter = new WaveFileWriter(destinationFile, reader.WaveFormat);
if (!reader.WaveFormat.Equals(waveFileWriter.WaveFormat)){
throw new InvalidOperationException(
"Can't append WAV Files that don't share the same format");
}
var startPos = sourceReadOffset - sourceReadOffset % reader.WaveFormat.BlockAlign;
var endPos = (int) reader.Length;
reader.Position = startPos;
var bytesRequired = (int)(endPos - reader.Position);
var buffer = new byte[bytesRequired];
if (bytesRequired > 0)
{
var bytesToRead = Math.Min(bytesRequired, buffer.Length);
var bytesRead = reader.Read(buffer, 0, bytesToRead);
if (bytesRead > 0)
{
waveFileWriter.Write(buffer, startPos, bytesRead);
}
}
}
}
}
finally{
if (waveFileWriter != null){
waveFileWriter.Dispose();
}
}
}
我能夠獲得新內(nèi)容.
是否可以將最新內(nèi)容附加到現(xiàn)有目標(biāo)文件?
如果可能,我在代碼中做錯(cuò)了什么?
我的代碼拋出以下異常 – 偏移量和長(zhǎng)度超出數(shù)組的范圍或計(jì)數(shù)大于從索引到源集合末尾的元素?cái)?shù). 解決方法: 我找不到使用NAudio Library進(jìn)行波形音頻文件復(fù)制的解決方案.
但我已經(jīng)使用C#MemoryStreams和FileStreams實(shí)現(xiàn)了一個(gè)解決方案.
>如果目標(biāo)文件不存在,則將源文件復(fù)制到目標(biāo). >將所有最新字節(jié)(在上次操作后記錄)附加到目標(biāo)文件. >修改Wave File Header以反映最后添加的字節(jié). (否則文件的持續(xù)時(shí)間不會(huì)更新,只會(huì)增加文件大小. >定期重復(fù)此追加操作.
public void ReplicateFile(string destinationFile, string sourceFile){
if (!Directory.Exists(GetRoutePathFromFile(sourceFile)))
return;
if (!File.Exists(sourceFile))
return;
if (Directory.Exists(GetRoutePathFromFile(destinationFile))){
if (File.Exists(destinationFile)){
UpdateLatestWaveFileContent(destinationFile, sourceFile);
}else{
CopyWaveFile(destinationFile, sourceFile);
}
}else{
Directory.CreateDirectory(GetRoutePathFromFile(destinationFile));
CopyWaveFile(destinationFile, sourceFile);
}
}
private static string GetRoutePathFromFile(string file){
var rootPath = Directory.GetParent(file);
return rootPath.FullName;
}
private static void CopyWaveFile(string destination, string source){
var sourceMemoryStream = new MemoryStream();
using (var fs = File.Open(source, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)){
fs.CopyTo(sourceMemoryStream);
}
using (var fs = new FileStream(destination, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.ReadWrite)){
sourceMemoryStream.WriteTo(fs);
}
}
private static void UpdateLatestWaveFileContent(string destinationFile, string sourceFile){
var sourceMemoryStream = new MemoryStream();
long offset = 0;
using (var fs = File.Open(destinationFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)){
offset = fs.Length;
}
using (var fs = File.Open(sourceFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)){
fs.CopyTo(sourceMemoryStream);
}
var length = sourceMemoryStream.Length - offset;
var buffer = sourceMemoryStream.GetBuffer();
using (var fs = new FileStream(destinationFile, FileMode.Append, FileAccess.Write, FileShare.ReadWrite)){
fs.Write(buffer, (int)offset, (int)length);
}
var bytes = new byte[45];
for (var i = 0; i < 45; i ){
bytes[i] = buffer[i];
}
ModifyHeaderDataLength(destinationFile, 0, bytes);
}
private static void ModifyHeaderDataLength(string filename, int position, byte[] data){
using (Stream stream = File.Open(filename, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite))
{
stream.Position = position;
stream.Write(data, 0, data.Length);
}
}
來(lái)源:https://www./content-1-275601.html
|