Compare si dos archivos son iguales a través de Internet -- # campo con file campo con http-headers campo con youtube-api campo con windows-store-apps camp Relacionados El problema

Compare if two file are the same over the internet


6
vote

problema

Español

Aquí está mi escenario, tengo una aplicación de Windows Store. Tengo un archivo local, y un enlace a un archivo en Internet. ¿Hay alguna forma en que puedo verificar si estos dos archivos son los mismos, sin descargando el archivo del enlace?

El código utilizado para obtener el archivo es este:

  private static async void SetImage(PlaylistItem song, string source, string imageName) {      HttpClient client = new HttpClient();      HttpResponseMessage message = await client.GetAsync(source);      StorageFolder myfolder = Windows.Storage.ApplicationData.Current.LocalFolder;     StorageFile sampleFile = await myfolder.CreateFileAsync(imageName, CreationCollisionOption.ReplaceExisting);     byte[] byteArrayFile = await message.Content.ReadAsByteArrayAsync();      await FileIO.WriteBytesAsync(sampleFile, byteArrayFile);      song.Image = new BitmapImage(new Uri(sampleFile.Path));  }   
Original en ingles

Here is my scenario - I have a windows store app. I have a local file, and a link to a file on the internet. Is there a way I can check if these two files are the same, WITHOUT downloading the file from the link?

The code used to get the file is this:

private static async void SetImage(PlaylistItem song, string source, string imageName) {      HttpClient client = new HttpClient();      HttpResponseMessage message = await client.GetAsync(source);      StorageFolder myfolder = Windows.Storage.ApplicationData.Current.LocalFolder;     StorageFile sampleFile = await myfolder.CreateFileAsync(imageName, CreationCollisionOption.ReplaceExisting);     byte[] byteArrayFile = await message.Content.ReadAsByteArrayAsync();      await FileIO.WriteBytesAsync(sampleFile, byteArrayFile);      song.Image = new BitmapImage(new Uri(sampleFile.Path));  } 
              
         
         

Lista de respuestas

7
 
vote
vote
La mejor respuesta
 

La solución habitual es mantener un hash del archivo en la nube en algún lugar, generalmente en los metadatos del archivo y compararlo con el hash de su archivo local. Las sumas de comprobación no son adecuadas para esta operación porque tienen una probabilidad de colisión muy alta (es decir, diferentes archivos que tienen la misma suma de comprobación).

La mayoría de los servicios de almacenamiento (Almacenamiento de Blob Azure, Amazon S3, Cloudfiles) en realidad usan el hash MD5 o SHA de un archivo como ETAG, el valor utilizado para detectar cambios en un archivo para fines de almacenamiento en caché y concurrencia. Normalmente, una operación de la cabeza en el archivo devolverá sus encabezados y valor ETAG.

Si tiene la opción de elegir su propio algoritmo, elija SHA256 o superior a medida que estos algoritmos estén altamente optimizados y su tamaño de bloque grande significa que calcular los hashes para archivos grandes es mucho más rápido. SHA256 es en realidad mucho más rápido que el algoritmo MD5 más antiguo.

¿Qué servicio de almacenamiento está usando?

editar

Si solo desea verificar los archivos para evitar descargarlos nuevamente, puede usar la ETAG directamente. Etag fue creado para este propósito. Solo tiene que almacenarlo junto con su archivo cuando lo descargue la primera vez. Así es como los proxies y los cachés saben enviarle una versión en caché de una imagen en lugar de golpear el servidor de destino.

De hecho, probablemente puede simplemente hacer una sesión en el archivo con los encabezados Etag / IF-None-Match. Los proxies intermedios y el servidor web final devolverán un código de estado 304 si el archivo de destino no ha cambiado. Esto reducirá a la mitad la cantidad de solicitudes que necesita para descargar todas las imágenes en su lista.

Una alternativa es almacenar el último valor del encabezado modificado para el archivo y usar el encabezado IF modificado desde obtener

Editar 2

Menciona que el encabezado Etag es NULL, aunque su código no muestra cómo lo recupera.

httpresponsemessage tiene múltiples propiedades de encabezados, tanto en el mensaje en sí y su Contenido . Debe usar la propiedad adecuada para recuperar el valor ETAG.

También puede verificar con Fiddler para asegurarse de que el servidor realmente devuelva una ETAG.

edit 3

¡Finalmente encontré una manera de obtener una etag de YouTube! La respuesta viene de " Cómo conseguir la miniatura de ¿Enlace de video de YouTube utilizando API de YouTube? "

Hacer una cabeza o obtener una miniatura de YouTube de ytimg.com no devuelve el Etag o los encabezados de última hora.

Uso de la API de datos de YouTube y haciendo una OBTENER gdata.youtube.com Por otro lado, devuelve una gran cantidad de información sobre el video. Se incluye un valor Etag, aunque sospecho que lo cambió cuando el video cambia. Esto puede estar bien, si solo desea descargar una imagen cuando cambie el video, o no desea descargar la imagen una segunda vez más.

El código que utilicé fue:

  var url = "http://gdata.youtube.com/feeds/api/videos/npvJ9FTgZbM?v=2&prettyprint=true&alt=json";  using(var  client = new HttpClient()) {     var response = await client.GetAsync(url);     var etag1 = response.Headers.ETag;     var content = await response.Content.ReadAsStringAsync();     ... }   
 

The usual solution is to keep a hash of the cloud file somewhere, usually in the file's metadata and compare it with the hash of your local file. Checksums are unsuitable for this operation because they have a very high chance of collision (ie different files having the same checksum).

Most storage services (Azure Blob storage, Amazon S3, CloudFiles) actually use a file's MD5 or SHA hash as its ETag, the value used to detect changes to a file for caching and concurrency purposes. Typically, a HEAD operation on the file will return its headers and ETag value.

If you have the option of picking your own algorithm, choose SHA256 or higher as these algorithms are highly optimized and their large block size means that calculating hashes for large files is much faster. SHA256 is actually much faster than the older MD5 algorithm.

What storage service are you using?

EDIT

If you only want to check files to avoid downloading them again, you can use the ETag directly. ETag was created for exactly this purpose. You just have to store it together with your file when you download it the first time. That's how proxies and caches know to send you a cached version of a picture instead of hitting the destination server.

In fact, you can probably just do a GET on the file with the ETag/If-None-Match headers. The intermediate proxies and the final web server will return a 304 status code if the destination file hasn't changed. This will halve the number of requests you need to download all images in your list.

An alternative is to store the Last-Modified header value for the file and use the If-Modified-Since header in GET

EDIT 2

You mention that the ETag header is null, although your code doesn't show how you retrieve it.

HttpResponseMessage has multiple Headers properties, both on the message itself and its Content. You need to use the proper property to retrieve the ETag value.

You can also check using Fiddler to ensure the server does actually return an ETag.

EDIT 3

Finally found a way to get an ETag from Youtube! The answer comes from "How to get thumbnail of YouTube video link using YouTube API?"

Doing a HEAD or GET on a YouTube thumbnail from ytimg.com does NOT return the ETag or Last-Modified headers.

Using YouTube's Data API and doing a GET on gdata.youtube.com on the other hand, returns a wealth of information about the video. An ETag value is included, although I suspect it changes whenever the video changes. This may be OK though, if you only want to download an image when the video changes, or you don't want to download the image a second time again.

The code I used was:

var url = "http://gdata.youtube.com/feeds/api/videos/npvJ9FTgZbM?v=2&prettyprint=true&alt=json";  using(var  client = new HttpClient()) {     var response = await client.GetAsync(url);     var etag1 = response.Headers.ETag;     var content = await response.Content.ReadAsStringAsync();     ... } 
 
 
     
     
1
 
vote

Podría calcular un hash de los contenidos de archivos como lo hace GIT. Utilice MD5 o similar. Luego solo necesita verificar si los archivos tienen el mismo hash.

 

You could calculate a hash of the file contents like git does. Use MD5 or similar. Then you only need to check if files have the same hash.

 
 
     
     
1
 
vote

Si desea hacer una comparación sin descargar y usted es el que ha colocado el archivo a través de Internet. Luego, idealmente, debe colocar una suma de comprobación del archivo cargado. Luego, antes de cargar una nueva, puede verificar verificar la comprobación del archivo local y el del servidor. Si no es igual proceder con la carga de la carga, cancele.

 

If you want to do a comparison without downloading and you are the one who has placed the file over the internet. Then ideally you should place a checksum of the file uploaded. Then before uploading a new one you can just check the checksum of local file and the one on the server. if it is not equal proceed with the upload else cancel it.

 
 
0
 
vote

directamente? No. Si el archivo en línea también se proporciona con un hash, puede obtener una alta probabilidad de verificar con éxito la igualdad de los archivos.

 

Directly? No. If the file online is also provided with a Hash, you can get a high probability of successfully checking the equality of the files, though.

 
 
0
 
vote

Ahora con su actualización, es un poco claro cuál hace su código: descarga una imagen de una URL dada y lo almacena en la carpeta de datos de su aplicación en el nombre de archivo dado. Quieres descargar cualquier imagen solo una vez.

Todavía no me está claro cómo llame a este código, pero la solución para mí parece que solo necesita una traducción de "URL TO FILENAME". Entonces, en Psuedo:

  BitmapImage GetImage(string sourceURL) {     string filename = GetFilenameForURL(sourceURL);      BitmapImage image;      if (!FileExists(filename))     {         image = DownloadAndSaveImage(sourceURL, filename);     }     else             {                image = ReadImageFile(filename);     }      return image; }   

Esto no cuenta con imágenes que se hayan actualizado en el servidor. Si desea hacerlo, debe guardar los metadatos en la llamada if-none-match1 , por ejemplo, el if-none-match62 mencionado o last-modified Fecha.

Luego, para ahorrar ancho de banda, puede hacer un 9988777664 o Condicionado GET con un if-none-match o if-modified-since Encabezado Antes de la llamada a ReadImageFile() para verificar si hay una versión más nueva disponible.

 

Now with your update, it's kind of clear what your code does: it downloads an image from a given URL and stores it in your application data folder under the given filename. You want to download any image only once.

It's still unclear to me how you call this code, but the solution to me looks like you just need an "URL to filename" translation. So, in psuedo:

BitmapImage GetImage(string sourceURL) {     string filename = GetFilenameForURL(sourceURL);      BitmapImage image;      if (!FileExists(filename))     {         image = DownloadAndSaveImage(sourceURL, filename);     }     else             {                image = ReadImageFile(filename);     }      return image; } 

This does not account for images that have been updated on the server. If you want to do that, you need to save metadata in the DownloadAndSaveImage() call, for example the mentioned ETag or last-modified date.

Then to save bandwidth, you can do a HEAD or conditional GET request with an if-none-match or if-modified-since header before the call to ReadImageFile() to check if a newer version is available.

 
 

Relacionados problema

0  Aplicación UWP: ¿Cómo puedo implementar el archivo JSON actualizable?  ( Uwp app how can i deploy updatable json file ) 
¿Cómo puedo empaquetar un archivo JSON con mi aplicación WIN10 para que aparezca como un archivo independiente en la carpeta localState (o sub)? Necesito que ...

1  ¿Cómo agregar el archivo PFX de autenticación web en aplicaciones de metro de Windows 8?  ( How to add web authentication pfx file in windows 8 metro apps ) 
My Shop Web Services son el certificado autenticado y tengo un archivo PFX para esto ¿Cómo integro este archivo PFX en la aplicación Windows 8 Store para golp...

0  Adcontrol no muestra anuncios  ( Adcontrol not show ads ) 
En mi solicitud, tengo el siguiente código: <UI:AdControl x:Name="ban2" Grid.Row="1" ApplicationId="xx" AdUnitId="xx" ...

3  Teclado emergente en pantalla en el evento de enfoque de la caja de texto en la aplicación Windows Store  ( Popup on screen keyboard on text box focus event in windows store app ) 
I M Trabajo en la aplicación de Metro Windows 8.1, esta aplicación está trabajando en la máquina Kiosk y no hay un teclado físico. Tengo un poco de caja de te...

0  ¿Es la aplicación Windows Store Compateresults.transactionid, lo mismo que la ID de PRODTRECEIPT->?  ( Is windows store app purchaseresults transactionid the same as receipts product ) 
¿Alguien puede saberlo, cuando lo hace: - (NSImage *)imageProperty { if (!self.purgeableImage || ![self.purgeableImage beginContentAccess]) { i...

2  Apps de Windows Store: detecta el primer lanzamiento de la aplicación  ( Windows store apps detect first launch of the app ) 
Necesito mostrar una "pantalla de bienvenida" (algo así como una licencia) cuando el usuario inició primero la aplicación. Esta pantalla debe mostrarse solo u...

3  Guardar lienzo de la aplicación de Windows Store como archivo de imagen  ( Save canvas from windows store app as image file ) 
Estoy buscando una forma de guardar el lienzo de la aplicación Windows Store, he encontrado: sys.getdefaultencoding()3 Pero ese método no funcionará en ...

1  ¿Es posible configurar el acceso asignado para una aplicación Win 8.1 Store en Windows 10?  ( Is it possible to set up assigned access for a win 8 1 store app on windows 10 ) 
Puedo ejecutar con éxito una aplicación Windows 8.1 Store sin problemas sin embargo, sin embargo, no puedo hacer que funcione con el acceso asignado en Window...

0  No se pueden utilizar notificaciones push en la aplicación de la tienda de ventanas  ( Unable to use push notifications in window store app ) 
Soy nuevo en el desarrollo de la aplicación de Windows 8. Estoy usando xaml y c # para ello. Tengo un escenario donde me enfrentan a cargas de dificultades. B...

0  Aplicación de Windows 8 de cambio de color de fondo global usando MVVMlight  ( Global background color change windows 8 app using mvvmlight ) 
Estoy buscando una solución simple para cambiar el color de fondo de mi aplicación en todas las páginas de varios puntos en los modelos VER. Estoy usando la p...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos