2009-07-17 6 views
0

J'essaye d'écrire un fichier audio en utilisant le System.IO.BinaryWriter class de C#.Ecriture de fichier en utilisant System.IO.BinaryWriter

Il fonctionne très bien quand je joue cette action:

File.WriteAllBytes(@"C:\TestFile\File1", br.ReadBytes((int)br.BaseStream.Length)); 

Cependant, il ne fonctionne pas quand je fais ce qui suit:

Encoding e = Encoding.ASCII; 
char[] reslts = e.GetChars(br.ReadBytes((int)br.BaseStream.Length)); 
br.BaseStream.Position = 0; 
File.WriteAllBytes((@"C:\TestFile\File2",e.GetBytes(reslts)); 

J'ai vérifié les tableaux d'octets, dans les deux cas le tableau contenait les mêmes valeurs (j'ai copié leur valeur dans un fichier Excel séparé et vérifié pour voir s'il y a des différences, il n'y en a pas).

Dans les deux cas, la position de flux de base est fixé à 0.

Le code lui-même fonctionne, le fichier est créé avec succès. Le problème se produit lorsque j'ouvre le fichier, le premier fichier fonctionne correctement, le deuxième fichier n'est pas reconnu par Windows Media Player.

Est-ce que quelqu'un a des idées de ce que je pourrais faire de mal?

Répondre

1
Encoding e = Encoding.ASCII; 

Cela semble suspect. Je ne connais pas de format audio encodé en ASCII.

1

Jamais, jamais lire des données binaires arbitraires comme si c'était du texte. Ça va toujours mal, parce que ce n'est pas la même chose. De plus, ne comptez pas sur la longueur d'un flux - il pourrait changer, ou il pourrait ne pas supporter de le récupérer quand même.

Vous voulez quelque chose comme ceci:

public static byte[] CopyStream(Stream input, Stream output) 
{ 
    byte[] buffer = new byte[16*1024]; 
    int read; 
    while ((read = input.Read(buffer, 0, buffer.Length)) > 0) 
    { 
     output.Write(buffer, 0, read); 
    } 
} 

Ensuite, il suffit d'ouvrir un FileStream à l'endroit où vous voulez écrire les données, et appelez

CopyStream(inputStream, outputFile); 

Vous ne l'avez pas montré où vous obtenez l'entrée de, mais fondamentalement, vous n'avez pas vraiment besoin de BinaryReader. Ce n'est pas comme si vous utilisiez BinaryReader pour son but normal, qui est de lire des valeurs primitives individuelles, des chaînes avec préfixes de longueur, etc. Vous voulez juste copier les données mot pour mot - et un Stream est bien pour cela.

+0

"Jamais, jamais lu des données binaires arbitraires comme si c'est du texte" - si vous dites presque jamais je suis d'accord. Mais j'ai vu des cas où cela est utile, par ex. envoi de messages via un port série composé de caractères de contrôle et de texte ASCII. Dans ce cas, il peut être plus facile de traiter le message comme une chaîne. – Joe

1

Avec la plupart des encodages, y compris Encoding.ASCII, la conversion d'octets en caractères et en retour ne vous rendra pas les mêmes données. Par exemple, IIRC Encoding.ASCII mappe tous les octets dans la plage 128-255 au '?' personnage. Ensuite, lorsque vous convertissez à nouveau en octets, ils vont tous revenir à la même valeur. Une exception est le codage Latin1 alias ISO-8859-1 Code de la page, qui mappera tous les octets avec des valeurs hexadécimales comprises entre 0 et 255 au caractère Unicode ayant la même valeur hexadécimale. Ce qui suit devrait donner le résultat souhaité:

Encoding e = Encoding.GetEncoding(28591); 
// or either of the following is equivalent 
// Encoding.GetEncoding("Latin1"); 
// Encoding.GetEncoding("ISO-8859-1"); 

char[] reslts = e.GetChars(br.ReadBytes((int)br.BaseStream.Length)); 
br.BaseStream.Position = 0; 
File.WriteAllBytes((@"C:\TestFile\File2",e.GetBytes(reslts)); 

Néanmoins, sauf si vous avez une bonne raison de le faire, je ne convertirait octets à caractères de cette façon.

0

Le codage est utilisé pour coder une chaîne en octets, puis de nouveau dans une chaîne.

Vous l'utilisez à l'envers, décodant quelque chose qui n'était pas une chaîne pour commencer.

Questions connexes