Questão Abriu uma imagem JPG com o bloco de notas, colou todo o “texto” em um novo arquivo de bloco de notas, mudou para .JPG e não abre mais. Por quê?


Este fenômeno tem me deixado perguntas a fazer.

Aqui está a experiência detalhada, meu sistema operacional é o Windows 7 x64 SP1:

  • Eu mudei um arquivo de imagem (JPG) para TXT simplesmente mudando sua extensão (ou poderia apenas escolher abrir o JPG com o bloco de notas, a mesma coisa)

Deveria ter esta aparência, estranhamente procurando sequências de textos, e alguns deles (muito raros) são realmente significativos, como na imagem abaixo "creator: dg-jpeg v1.0 ..."

Sample JPG text

  • Eu desabilitei o wrapping e selecionei todo o texto usando Ctrl + A (para ter certeza de que nada foi perdido)
  • Eu colei o texto copiado em outro arquivo TXT em branco e o salvei como JPG, eu comparei o novo tamanho do arquivo com o JPG original. Todos eles (o JPG original, o arquivo TXT convertido e o arquivo TXT recém-criado) são da exato mesmo tamanho, para bytes.

Quando tentei abrir, o Windows diria "O Windows Photo Viewer não pode abrir esta imagem porque o arquivo parece estar danificado, corrompido ou muito grande".

Eu até tentei testá-lo usando outro método: abri o JPG com o notepad, cortei 1 personagem conhecido de um local fácil de lembrar (como o primeiro caractere da segunda linha), em seguida, salve o arquivo. O visualizador mostraria a mesma mensagem. Então eu abri novamente e colei o personagem ao EXATO localização (o Bloco de Notas lembra seu estado de saída como posição do Windows, quebra automática, tamanho de fontes ... então não tenho nenhum problema em fazer isso direito)

E ainda o mesmo erro. Você pode tentar isso para ter a idéia, lembre-se de escolher uma imagem pequena que o Bloco de Notas agirá como um velho homem enferrujado.

O que poderia ter sido a causa desse fenômeno?


80


origem


Experimente o comando fc. abra um prompt cmd e faça C:\blah>fc file1 file2   É possível que os arquivos sejam do mesmo tamanho, mas diferentes. (embora geralmente alguma mudança aleatória não tenda a deixar um arquivo do mesmo tamanho, mas facilmente poderia). O comando fc será muito útil para você investigar o que está acontecendo. Você também pode usar o comando xxd, isso é no cygwin e também vem com o vim7. xxd -p file1 Isso irá despejar o hex de um arquivo. Você pode comparar o hex dos dois arquivos com isso e fc. Ou até mesmo abra o hex no bloco de notas e clique entre as duas janelas do bloco de notas com a tecla Alt-Tab. - barlop
Você está tentando ler um arquivo binário com um editor de texto simples como o bloco de notas. Não será capaz de ler corretamente a codificação ANSI e, portanto, irá convertê-la. Quando você salvá-lo, o arquivo não será mais binário e, portanto, o analisador não poderá ler os dados dentro do arquivo. (Pesquise a diferença entre o salvamento de arquivos com base em XML e o salvamento de arquivos binários, o que é um tópico interessante.) Se você tentasse a mesma experiência com o Notepad ++, conseguiria o que estava tentando. - woutervs
possível duplicata de Por que um arquivo exe não aparece como uns e zeros em um editor de texto como o Bloco de Notas? - allquixotic
Para o interessado: Você pode editar imagens no Vim: No entanto, o truque é que o Vim converte o arquivo no XPM formato, que é simples ASCII. - Boldewyn
Resumindo, o Bloco de Notas modifica seu arquivo antes de exibi-lo para você. - Derek 朕會功夫


Respostas:


Dependendo da codificação usada para abrir o arquivo, você poderá ver um comportamento diferente. O meu bloco de notas do Windows 7 permite abrir um arquivo em ANSI, UTF-8, Unicode ou Unicode big endian.

Eu testei esse problema com uma pequena imagem JPEG de 2x2 pixels criada com o gimp e abrindo e salvando o arquivo de imagem com a codificação ANSI. Abrindo o original e a imagem salva com um editor hexadecimal, vejo que todas as 00 seqüências (dois dígitos hexadecimais, Caractere de controle NUL) foram convertidos para 20 (caractere de espaço).

Substituindo de volta no editor hexadecimal todos os 20 por 00 restaura o formato da imagem.

Eu pesquisei um pouco e não encontrei nenhuma referência que explique por que isso acontece. Somente uma referência a um post que avisa sobre isso (link de cache do google, a página não está disponível).

Se você salvar / abrir o arquivo como UTF-8, parece que ele ainda converte caracteres NUL em espaços, mas também aumenta o tamanho do arquivo resultante devido a conversões de caracteres de byte único para seqüências de bytes múltiplos UTF-8.

Se você salvar / abrir o arquivo como Unicode, parece que ele ainda converte caracteres NUL em espaços, mas também adiciona um byte ao início do arquivo. BOM.


79



0x00 é um terminador de seqüência de caracteres em seqüências de caracteres C. Eles podem tê-los substituído, pois um arquivo de texto não deve contê-los. O bloco de notas é um programa muito antigo. - Zonder
Eu duvido que notepad.exe é um executável .net. - knittl
@Bakuriu Uma string C certamente pode existir em um arquivo; Eu posso pensar em vários formatos de arquivo que os contêm. E a grande maioria dos aplicativos fornecidos com aplicativos do Windows são nativos, não .NET. Dito isso, o bloco de notas não grava strings terminadas em nulo em arquivos. - Carey Gregory
@Bakuriu: Os programas do Windows geralmente não são escritos em .Net. É C / C ++ e nativo no núcleo. Um dos aplicativos .Net desenvolvidos pela microsoft foi o live writer, que agora está descontinuado. - Bhathiya Perera
@ SJuan76 Huh? C ++ não define um tipo de dados chamado byte. Talvez você esteja pensando em algum outro idioma. E os desenvolvedores de aplicativos podem lidar com dados binários da maneira que acharem melhor, incluindo o uso de strings C, se assim desejarem. Como eu disse antes, posso pensar em vários formatos de arquivos binários que contêm strings C. - Carey Gregory


Por que isso falha?

Bloco de notas cria espaços (ASCII code 32) personagem para personagens como NUL  (ASCII code 0) porque a caixa de texto da API do Windows permite apenas terminação nula char *  ASCIIZ (matriz de caracteres, ponteiro). Fica cortado na primeira NUL. 

Isso acontece porque API do Windows é principalmente escrito em C linguagem e sequências terminadas em null são uma das características comuns. Mesmo quando o Windows moderno e o Unicode são considerados iguais, ocorrem sequências terminadas por nulo. Assim, o bloco de notas simplesmente os substitui por espaço para que você possa visualizar o arquivo completo.

Então, quando você salva o arquivo, ele está corrompido.

sequências terminadas em wikipedia-null


Como fazer mais pesquisas:

Você pode usar um comparador como além de comparar (comercial, julgamento) para ver o efeito de substituição de caracteres. Veja também outras ferramentas de comparação binária.

hex comparison

Nota : (20)16 = (32)10


Razão para o bloco de notas atua lentamente em arquivos grandes

 Ele verifica cada caractere e substitui caracteres especiais por espaços. Outros softwares não fazem conversões na memória (pelo menos não primitivo como o notepad). Eles apenas processam caracteres especiais de forma diferente. E eles usam técnicas avançadas de buffering.


Olhando para Notepad.exe (XP 32 bits)

(Eu estou supondo que ainda está escrito em C + + ou pelo menos usar um comparável semelhante linker )

notepad

Estou usando o PEiD ferramenta (que parou o desenvolvimento com a introdução de PE + / 64 exes)

PEiD pode ser encontrado na pasta bin do Extrator Universal

Eu extraí o bloco de notas. ex_ arquivo do iso do Windows xp, obviamente. Experimente. É um extrato de arquivo cab usando 7z.

Atenção ! Seu scanner de vírus pode detectar o Universal Extractor / PEiD como ferramentas de hackers ou vírus. Não confie, não baixe !!


Mais informações sobre a API do Windows

créditos:Jason C

Não é apenas a caixa de texto; WM_SETTEXT em geral, não fornece nenhum parâmetro para especificar o comprimento da cadeia, e as cadeias são sempre assumidas como terminadas em nulo. Você sempre pode criar uma caixa de texto personalizada com uma mensagem personalizada que especifique o tamanho da seqüência de caracteres, mas o Bloco de Notas e a maioria dos outros programas não o fazem. Também a função SetWindowText não fornece um parâmetro de comprimento também.


35



É um pouco estranho que você mostre a folha de propriedades de um executável do Notepad junto com uma versão do Windows XP, mas a julgar pelo tema da janela, você está claramente executando alguma versão do Windows 8. Isso explicaria porque o executável estava vinculado versão 7.1 do conjunto de ferramentas - foi o que eles usaram para compilar o Windows XP e os utilitários associados. A versão do Windows 8 do Bloco de Notas será, sem dúvida, compilada com uma versão mais recente das ferramentas do SDK. - Cody Gray
Não é apenas a caixa de texto; WM_SETTEXTem geral, não fornece nenhum parâmetro para especificar o comprimento da cadeia, e as cadeias são sempre assumidas como terminadas em nulo. Você sempre pode criar uma caixa de texto personalizada com uma mensagem personalizada que especifique o tamanho da seqüência de caracteres, mas o Bloco de Notas e a maioria dos outros programas não o fazem. - Jason C
@BhathiyaPerera Porque estou satisfeito com o nível de trabalho que fiz adicionando informações em um comentário. Você está convidado a melhorar sua resposta com essa informação, se quiser. - Jason C


O bloco de notas não preserva todos os caracteres especiais / estendidos exatamente como eles são. Eu não tenho uma referência para esse comportamento imediatamente à mão, mas descobri que este é o caso, por exemplo, com o fim de linha de estilo UNIX LF que o Notepad irá converter em CRLF e null (0x00), que ele irá ignorar. Em um arquivo binário, como um JPG, é provável que ocorram ocorrências aleatórias dos caracteres que o Bloco de Notas não preserva. Experimente o seu experimento com um editor sensível ao HEX e ele deve funcionar então. Vou atualizar minha resposta se encontrar uma boa referência e depois de testar um editor HEX.

Update: Eu tentei alguns editores de programadores bem conhecidos, mas apenas um deles trabalhou logo de cara, HxD por Maël Hörz. Eu nunca usei o HxD antes, mas achei isso graças a uma resposta a este artigo do Stack, Um plugin hexadecimal para visualizador / editor para o Notepad ++.

Os outros editores que não trabalharam depois de alguns minutos foram o Notepad ++, Notepad2 e UltraEdit (v17.3, versão mais antiga). Alguns deles tiveram problemas com a cópia / colagem dos primeiros bytes, o JPEG número mágico de assinatura de arquivo FF D8 FF. Talvez eles trabalhassem com um pouco mais de mexer do que eu tenho tempo para no presente.


28



Sublime Text (2/3) abre automaticamente um arquivo binário, mostrando-o em formato hexadecimal. Como exemplo, o início do arquivo JPEG, basta clicar em "abrir": puu.sh/aaAVx/bd08dab46e.png - tomsmeding
Na verdade, com mais freqüência do que o notepad converterá LF para CRLF, ele deixará o LF como está e exibirá o texto como se não houvesse nenhuma quebra de linha! - Moshe Katz


Você costumava fazer isso com Write back in the day. Era um programa padrão no Windows 3.1, mas não me lembro se o Windows 95 o incluiu. A gravação permitiria a edição segura e binária de qualquer arquivo que pudesse ser aberto (provavelmente com tamanho de arquivo muito limitado). O Bloco de Notas definitivamente não é seguro em binário (o texto permanece o mesmo, mas os bytes reais de caracteres que não são de texto [por exemplo, códigos de controle] podem mudar) e é por isso que o seu exemplo JPG não está funcionando. Tente obter uma cópia do Write (e do Windows antigo) e tente novamente.

De acordo com Artigo da Wikipedia "Windows Write" Escrever foi incluído até o Windows NT 3.5. Foi substituído pelo Wordpad no Windows 95 em diante. write.exe ainda estava presente no diretório do Windows, mas era simplesmente um invólucro para abrir o Wordpad.


6





Eu acho que não é tanto um problema de codificação, mas também de conjunto de caracteres. O formato JPG é basicamente um fluxo de bytes. Permitindo assim caracteres não imprimíveis como NUL, ETX, STX, SOH, DLE, etc.

O Bloco de notas da Microsoft não pode exibir esses caracteres não imprimíveis. Pode exibir espaços reservados de algum tipo como um espaço para um caractere nulo. Então, abrir o arquivo com o Bloco de Notas não mostra o conteúdo real, mas o conteúdo decodificado pela codificação selecionada (utf-8, utf-16, etc) e exibido por um determinado conjunto de caracteres (unicode, ascii, etc) excluindo o não caracteres imprimíveis.

Ao selecionar todo o texto exibido e copiar o texto na área de transferência, você só copia os caracteres imprimíveis, incluindo os espaços reservados. Assim convertendo automaticamente caracteres nulos para espaços e ignorando outros caracteres não imprimíveis inteiramente.

Então, basicamente, você só perde o conteúdo fazendo assim. Se você usar um editor hexadecimal, copiará todo o conteúdo.


Atualizar: Resposta Bhathiya Pereras está certo: https://superuser.com/a/782885/322784 Caracteres não imprimíveis não são ignorados ao copiar texto para a área de transferência.


5



Todo arquivo é "basicamente um fluxo de bytes". - Jason C
@JasonC eu discordaria. Enquanto cada arquivo pode ser lido como um fluxo de bytes. Arquivos estruturados como arquivos XML não são legíveis como um fluxo de dados. O conteúdo não será válido até que o final do arquivo seja lido. Um corte no meio jpg ainda é válido e pode ser exibido. Está faltando metade da foto. - sbecker
Não há espaço para desacordo sobre isso. :) XML é um fluxo de bytes como qualquer outra coisa, e XML (juntamente com a codificação de caracteres) define um formato para esses bytes. É certamente legível como um fluxo de dados. Abra-o em um editor hexadecimal, por exemplo. Esse fluxo de dados é apenas passível de ser analisado como XML. - Jason C
@JasonC Não posso discutir com isso, na verdade. :) Touché! - sbecker


O arquivo JPEG contém dados que não são de texto, exceto por alguns campos. Basicamente, qualquer valor de byte entre 0 e 255 será encontrado, especialmente na área que representa a imagem compactada codificada que contém dados quase pseudo-aleatórios.

Mas o Notepad tratará os dados como texto ANSI por padrão, então fará várias coisas que alterarão os dados originais, como:

  • substituir bytes mapeando caracteres especiais / indefinidos / proibidos, pois eles não fazem sentido para um texto ANSI válido

  • re codificar caracteres nulos, fim de linha e fim de seqüências de arquivos para convenções do Windows / DOS

O que significa que, se você editar e salvar os dados como texto, o jpeg será alterado no melhor dos casos, tornando-o inutilizável no pior dos casos.


2



"ANSI" não é tecnicamente correto, embora seja comumente entendido. - Jason C