recientemente he trabajado en un problema en el que nos encontramos con una situación como la siguiente:
Usted está trabajando en una solución utilizando SQL Server Integration Services (Visual Studio 2005). Está extrayendo datos de su base de datos y tratando de colocar los resultados en un archivo plano (.CSV) en formato UTF-8. La solución exporta los datos perfectamente y conserva los caracteres especiales en el archivo porque ha utilizado 65001 como página de códigos.
Sin embargo, el archivo de texto cuando lo abre o intenta cargarlo en otro proceso, dice que el archivo es ANSI en lugar de UTF-8. Si abre el archivo en el bloc de notas y hace un GUARDAR COMO y cambia la codificación a UTF-8 y luego su proceso externo funciona, pero este es un trabajo manual tedioso.
Lo que he encontrado que cuando especifica la propiedad Página de códigos del administrador de conexión de archivos planos, genera un archivo UTF-8. Sin embargo, genera una versión del archivo UTF-8 que omite algo que llamamos Marca de Orden de Byte.
Si tiene un archivo CSV que contiene el carácter AA, la lista de materiales para UTF8 será 0xef, 0xbb y 0xbf. Aunque el archivo no tiene BOM, sigue siendo UTF8.
Desafortunadamente, en algunos viejos sistemas legados, las aplicaciones buscan la lista de materiales para determinar el tipo de archivo. Parece que su proceso también está haciendo lo mismo.
Para solucionar el problema, puede utilizar el siguiente fragmento de código en la tarea de secuencia de comandos que se puede ejecutar después del proceso de exportación.
using System.IO;
using System.Text;
using System.Threading;
using System.Globalization;
enter code here
static void Main(string[] args)
{
string pattern = "*.csv";
string[] files = Directory.GetFiles(@".\", pattern, SearchOption.AllDirectories);
FileCodePageConverter converter = new FileCodePageConverter();
converter.SetCulture("en-US");
foreach (string file in files)
{
converter.Convert(file, file, "Windows-1252"); // Convert from code page Windows-1250 to UTF-8
}
}
class FileCodePageConverter
{
public void Convert(string path, string path2, string codepage)
{
byte[] buffer = File.ReadAllBytes(path);
if (buffer[0] != 0xef && buffer[0] != 0xbb)
{
byte[] buffer2 = Encoding.Convert(Encoding.GetEncoding(codepage), Encoding.UTF8, buffer);
byte[] utf8 = new byte[] { 0xef, 0xbb, 0xbf };
FileStream fs = File.Create(path2);
fs.Write(utf8, 0, utf8.Length);
fs.Write(buffer2, 0, buffer2.Length);
fs.Close();
}
}
public void SetCulture(string name)
{
Thread.CurrentThread.CurrentCulture = new CultureInfo(name);
Thread.CurrentThread.CurrentUICulture = new CultureInfo(name);
}
}
cuando se va a ejecutar el paquete encontrará que todos los CSV en la carpeta designada serán convertidos en un formato UTF8 que contiene la marca de orden de bytes.
De esta manera, su proceso externo podrá funcionar con los archivos CSV exportados.
si está buscando sólo para carpeta en particular ... enviar esa variable a la tarea de la escritura y el uso por debajo de uno ..
string sPath;
sPath=Dts.Variables["User::v_ExtractPath"].Value.ToString();
string pattern = "*.txt";
string[] files = Directory.GetFiles(sPath);
Espero que esto ayude !!
OK - parece haber encontrado una solución aceptable en [SQL Server Forums] (http://social.msdn.microsoft.com/forums/en-us/sqlintegrationservices/thread/9B68C357-A5B4-47BF-8EFD -A05945210CA2). Esencialmente tuve que crear dos archivos de plantilla UTF-8, usar una tarea de archivo para copiarlos a mi destino y luego asegurarme de que estaba agregando datos en lugar de sobrescribirlos. – Neil
No dude en responder a su pregunta y luego márquela. – Sam