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 é mais aberto. Por quê?


82

Esse fenômeno tem me deixado perguntas a serem feitas.

Aqui está o experimento detalhado, meu sistema operacional é o Windows 7 x64 SP1:

  • Alterei um arquivo de imagem (JPG) para TXT simplesmente alterando sua extensão (ou alguém pode simplesmente optar por abrir o JPG com o bloco de notas, a mesma coisa)

Ele deve ter esta aparência, seqüências de textos com aparência estranha e algumas delas (muito raras) são realmente significativas, como na captura de tela abaixo "criador: dg-jpeg v1.0 ..."

Exemplo de texto JPG

  • Desativei o agrupamento e selecionei todo o texto usando Ctrl + A (para garantir que nada falte)
  • Colei o texto copiado em outro arquivo TXT em branco e o salvei como JPG. 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) têm exatamente o mesmo tamanho, em 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" .

Até tentei testá-lo usando outro método: Abri o JPG com o bloco de notas, cortei UM caractere conhecido em um local fácil de lembrar (como o primeiro caractere da 2ª linha) e salve o arquivo. O visualizador, é claro, exibirá a mesma mensagem. Em seguida, abri-o novamente e colei o caractere no local EXATO (o Bloco de Notas lembra seu estado de saída, como posição da janela, quebra automática, tamanho das fontes ... então não tenho problema em acertar)

E ainda o mesmo erro. Você pode tentar fazer isso para ter uma idéia. Lembre-se de escolher uma imagem pequena. Caso contrário, o Bloco de Notas funcionará como um velho enferrujado.

Qual poderia ter sido a causa desse fenômeno?


4
Experimente o comando fc. abra um prompt do cmd e faça- C:\blah>fc file1 file2 É possível que os arquivos tenham o mesmo tamanho, mas sejam diferentes. (embora geralmente algumas alterações aleatórias não tendam a deixar um arquivo do mesmo tamanho, mas poderiam facilmente). O comando fc será muito útil para investigar o que está acontecendo. Você também pode usar o comando xxd, que está no cygwin e também vem com o vim7. xxd -p file1 Isso irá despejar o hexadecimal de um arquivo. Você pode comparar o hexadecimal dos dois arquivos com isso e fc. Ou até mesmo abra o hexadecimal no bloco de notas e passe levemente entre as duas janelas do bloco de notas com a tecla alt-tab.
barlop

22
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 a codificação ANSI corretamente e, portanto, a converterá. Quando você o salvar, 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 salvar arquivos com base em XML e salvar arquivos binários, é um tópico interessante.) Se você tentar o mesmo experimento com o Notepad ++, terá sucesso no que estava tentando.
woutervs


3
Para os interessados: Você pode editar imagens no Vim: No entanto, o truque é que o Vim converta o arquivo no formato XPM , que é ASCII simples.
Boldewyn

4
Para encurtar a história, o Bloco de Notas modifica seu arquivo antes de exibi-lo.
Derek朕會功夫

Respostas:


81

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

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

Substituir novamente no editor hexadecimal todos os 20 por 00 restaura o formato da imagem.

Pesquisei um pouco no Google e não encontrei nenhuma referência que explique por que isso acontece. Apenas uma referência a uma postagem que avisa sobre isso (link do 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 às conversões de caracteres de byte único em seqüências de 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, a BOM .


22
0x00 é um terminador de seqüência de caracteres em 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

25
Duvido que o notepad.exe seja um executável .NET.
amigos estão dizendo sobre knittl

10
A string AC do @Bakuriu 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 é nativa, não .NET. Dito isto, o bloco de notas não grava seqüências terminadas em nulo em arquivos.
Carey Gregory

4
@Bakuriu: Os programas do Windows geralmente não são escritos em .Net. É C / C ++ e nativo no centro. Um dos aplicativos .Net desenvolvidos pela microsoft era o live writer, que agora está descontinuado.
Bhathiya-perera

5
@ SJuan76 Hein? C ++ não define um tipo de dados chamado byte. Talvez você esteja pensando em alguma outra língua. E os desenvolvedores de aplicativos podem lidar com dados binários da maneira que acharem melhor, incluindo o uso de strings C, se assim o desejarem. Como eu disse antes, posso pensar em vários formatos de arquivos binários que contêm seqüências C.
Carey Gregory

37

Por que falha:

O bloco de notas cria (ASCII code 32)caracteres de espaços para caracteres como NUL (ASCII code 0) porque a caixa de texto da API do Windows permite apenas char * ASCIIZ terminado em nulo (matriz de caracteres, ponteiro). É cortado no primeiro NUL.

Isso acontece porque a API do Windows é escrita principalmente na linguagem C e as seqüências terminadas nulas são um dos recursos comuns. Mesmo quando o Windows e Unicode modernos são considerados, as mesmas seqüências terminadas nulas ocorrem. Então, o bloco de notas simplesmente substitua-os por espaço para que você possa ver o arquivo completo.

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

cadeias terminadas wikipedia-null


Como fazer mais pesquisas:

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

comparação hexadecimal

Nota : (20) 16 = (32) 10


O motivo do 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 primitivas como o bloco de notas). Eles apenas renderizam caracteres especiais de maneira diferente. E eles usam técnicas avançadas de buffer.


Examinando o Notepad.exe (XP de 32 bits)

(Presumo que ele ainda esteja escrito em C ++ ou pelo menos use um vinculador comparável )

bloco de anotações

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

O PEiD pode ser encontrado empacotado na pasta bin do Universal Extractor

Eu extraí o bloco de notas. ex_ do Windows XP iso obviamente. Experimente. É um extrato de arquivo de táxi usando 7z.

Aviso ! O seu antivírus pode detectar o Universal Extractor / PEiD como ferramentas de hacker ou vírus. Não confie nele, não faça o download !!


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 parâmetro para especificar o comprimento da cadeia, e sempre se supõe que as cadeias terminem em nulo. Você sempre pode criar uma caixa de texto personalizada com uma mensagem personalizada que especifique o tamanho da string, mas o Bloco de Notas e a maioria dos outros programas não o fazem razoavelmente. Além disso, a função SetWindowText também não fornece um parâmetro de comprimento.


1
É um pouco estranho que você mostre a folha de propriedades de um executável do Bloco de Notas fornecido com uma versão do Windows XP, mas, a julgar pelo tema da janela, você está claramente executando uma versão do Windows 8. Isso explicaria por que o executável foi vinculado a 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, sem dúvida, será compilada com uma versão mais recente das ferramentas do SDK.
Cody Gray

2
Não é apenas a caixa de texto; WM_SETTEXTem geral, não fornece parâmetro para especificar o comprimento da string, e sempre se supõe que as strings terminem em nulo. Você sempre pode criar uma caixa de texto personalizada com uma mensagem personalizada que especifique o tamanho da string, mas o Bloco de Notas e a maioria dos outros programas não o fazem razoavelmente.
Jason C

@BhathiyaPerera Porque estou satisfeito com o nível de trabalho que fiz adicionando informações em um comentário. Você pode melhorar sua resposta com essas informações, se desejar.
Jason C

28

O bloco de notas não preserva todos os caracteres especiais / estendidos exatamente como estão. Não tenho uma referência para esse comportamento imediatamente à mão, mas descobri que esse é o caso, por exemplo, do final de linha do estilo UNIX LF, que o Bloco de Notas converterá em CRLF e nulo (0x00), que será ignorado. Em um arquivo binário como um JPG, é provável que ocorram ocorrências aleatórias do (s) caractere (s) que o Bloco de Notas não preserva. Experimente o seu experimento com um editor compatível com HEX e ele deve funcionar. Atualizarei minha resposta se encontrar uma boa referência e depois de testar um editor HEX.

Atualização: Tentei alguns editores de programadores conhecidos, mas apenas um deles funcionou imediatamente, HxD , de Maël Hörz . Eu nunca usei o HxD antes, mas o encontrei graças a uma resposta a este artigo da Stack, um plug-in de visualizador / editor hexadecimal para o Notepad ++ .

Os outros editores que não funcionaram após alguns minutos foram o Notepad ++, Notepad2 e UltraEdit (v17.3, versão mais antiga). Alguns deles tiveram problemas com a copiar / colar dos primeiros bytes, o número mágico da assinatura de arquivo JPEG FF D8 FF. Talvez eles trabalhem com um pouco mais de brincadeira do que tenho tempo no momento.


O texto sublime (2/3) abre automaticamente um arquivo binário, mostrando-o no formato hexadecimal. Como exemplo, o início do arquivo JPEG, basta clicar em "abrir": puu.sh/aaAVx/bd08dab46e.png
tomsmeding

3
Na verdade, mais frequentemente do que o bloco de notas converte LF para CRLF, ele deixa o LF do jeito que está e exibe o texto como se não houvesse quebra de linha!
Moshe Katz

6

Você costumava fazer isso com o Write de volta no dia. Era um programa padrão no Windows 3.1, mas não me lembro se o Windows 95 o incluía. A gravação permitiria a edição binária segura de qualquer arquivo que ele pudesse abrir (provavelmente um tamanho muito limitado). O bloco de notas definitivamente não é binário seguro (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 muito antigo) e tente sua experiência novamente!

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


5

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. Portanto, 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 os não- caracteres imprimíveis.

Ao selecionar todo o texto exibido e copiá-lo para a área de transferência, você copia apenas os caracteres imprimíveis, incluindo os espaços reservados. Assim, convertendo automaticamente caracteres nulos em espaços e ignorando completamente outros caracteres não imprimíveis.

Então, basicamente, você perde o conteúdo dessa maneira. Se você usar um editor hexadecimal, ele copiará todo o conteúdo.


Atualização: A resposta de Bhathiya Pereras está certa: 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.


Todo arquivo é "basicamente um fluxo de bytes".
Jason C

1
@ JasononC eu discordo. Embora cada arquivo possa 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 seria válido até o final do arquivo ter sido lido. Um corte no meio jpg ainda é válido e pode ser exibido. Falta apenas metade da imagem.
Sbecker

Não há realmente espaço para discordância sobre isso. :) XML é um fluxo de bytes como qualquer outra coisa, e XML (junto 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 pode ser analisado como XML.
Jason C

@JasonC Não posso discutir com isso, na verdade. :) Touché!
Sbecker 29/07

2

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

Mas o Bloco de Notas tratará os dados como texto ANSI por padrão, portanto, 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

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

O que significa que, se você editar e salvar os dados como texto, ele mudará o jpeg no melhor dos casos e o tornará inutilizável no pior.


"ANSI" não é tecnicamente correto , embora seja comumente entendido.
Jason C
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.