Por que não consigo alterar o nome de um arquivo que está sendo lido no Windows, como no Linux / Mac?

23

Uma das coisas que me intrigou desde que comecei a usar o Linux é o fato de permitir alterar o nome de um arquivo ou até excluí-lo enquanto ele está sendo lido. Um exemplo é como tentei excluir acidentalmente um vídeo enquanto ele estava sendo reproduzido. Consegui e fiquei surpreso ao saber que você pode alterar praticamente qualquer coisa em um arquivo sem se importar se está sendo usado no momento ou não.

the_midget_17
fonte
2
Renomear um arquivo bloqueado não é um problema no Windows. A exclusão geralmente ocorre, existem poucos programas que abrem um arquivo com a opção FILE_SHARE_DELETE ativada.
Hans Passant
Na verdade, você não o excluiu, apenas o desvinculou do diretório em que estava. O arquivo ainda existe, mas pode não ter nenhum nome no sistema de arquivos. (Embora ainda tenha um nome no /procsistema de arquivos através do programa que o abriu.) Um arquivo só pode ser verdadeiramente excluído se não houver referências a ele, e isso acontece automaticamente.
David Schwartz

Respostas:

36

Sempre que você abre ou executa um arquivo no Windows, o Windows bloqueia o arquivo no local (isso é uma simplificação, mas geralmente é verdade.) Um arquivo bloqueado por um processo não pode ser excluído até que o processo o libere. É por isso que sempre que o Windows precisa se atualizar, é necessário reiniciar o computador para que ele entre em vigor.

Por outro lado, sistemas operacionais do tipo Unix, como Linux e Mac OS X, não bloqueiam o arquivo, mas os setores de disco subjacentes. Isso pode parecer uma diferenciação trivial, mas significa que o registro do arquivo no índice do sistema de arquivos pode ser excluído sem perturbar qualquer programa que já tenha o arquivo aberto. Portanto, você pode excluir um arquivo enquanto ele ainda está em execução ou em uso e ele continuará existindo no disco enquanto algum processo tiver um identificador aberto, mesmo que sua entrada na tabela de arquivos tenha desaparecido.

Andrew Lambert
fonte
2
Obrigado por esta resposta. Isso explica a diferença para mim muito mais. Também ajuda a explicar por que carregar arquivos / vídeos grandes não ocupa imensa quantidade de RAM. Caso contrário, a reprodução de um vídeo grande pode atolar todo o sistema.
Jerry Saravia
4
Se você excluiu um arquivo que estava em uso e desejava recuperá-lo no Linux, poderia encontrar a entrada do arquivo em / proc, conforme descrito nesta pergunta .
Ken Bloom
2
Isso é uma generalização - nem todas as atualizações do Windows hoje em dia (no Windows 7) exigem uma reinicialização, e eu fiz bastante isso no Linux.
12773 Alan B
10

O Windows assume como padrão o bloqueio automático e obrigatório de arquivos. O UNIX padrão é o bloqueio manual e cooperativo de arquivos. Nos dois casos, os padrões podem ser substituídos, mas nos dois casos geralmente não são.

Muitos códigos antigos do Windows usam a API C / C ++ (funções como fopen) em vez da API nativa (funções como CreateFile). A API C / C ++ não permite especificar como o bloqueio obrigatório funcionará, para que você obtenha os padrões. O "modo de compartilhamento" padrão tende a proibir operações "conflitantes". Se você abrir um arquivo para gravação, presume-se que as gravações entrem em conflito, mesmo que você nunca grave no arquivo. O mesmo vale para renomear.

E aqui é onde fica pior. Além da abertura para leitura ou gravação, a API C / C ++ não fornece nenhuma maneira de especificar o que você pretende fazer com o arquivo. Portanto, a API deve assumir que você executará qualquer operação legal. Como o bloqueio é obrigatório, um openque permita que uma operação conflitante seja recusada, mesmo que o código nunca pretenda executar a operação conflitante, mas esteja apenas abrindo o arquivo para outra finalidade.

Portanto, se o código usar a API C / C ++ ou usar a API nativa sem pensar especificamente sobre esses problemas, eles impedirão o conjunto máximo de operações possíveis para cada arquivo que abrirem e não conseguirão abrir um arquivo, a menos que sejam possíveis todas as operações possíveis. pode executar nele uma vez aberto é sem conflito.

Na minha opinião, o método Windows funcionaria muito melhor do que o método UNIX se todos os programas escolhessem seus modos de compartilhamento e modos abertos, com sabedoria e sanidade, lidando com casos de falha. O método UNIX, no entanto, funciona melhor se o código não se importar em pensar sobre esses problemas. Infelizmente, a API básica do C / C ++ não é bem mapeada para a API de arquivos do Windows de uma maneira que lida com os modos de compartilhamento e os conflitos se abrem bem. Portanto, o resultado líquido é um pouco confuso.

David Schwartz
fonte
0

Esta é uma pergunta muito interessante e me fez pensar em uma resposta viável. Espero que outros possam fornecer backup aqui.

Eu uso o Windows e Linux e notei isso também. Eu também sou usuário do vim. O Vim lerá um arquivo de texto em um 'buffer' ou na RAM e não tocará no arquivo real até que você salve. O Linux pode estar executando esse tipo de ação em geral com todos os arquivos.

Pegue o seu vídeo, por exemplo, ele lê o vídeo, tudo se possível, na RAM e, em seguida, você tem uma cópia do vídeo que é facilmente acessível, procurável e saltável. Se o arquivo for muito grande, você poderá ter problemas porque o Linux pode não ler o vídeo inteiro, talvez apenas uma grande parte. Quando o player chegar ao final do vídeo em buffer, ele tentará ler o arquivo novamente. Se você excluiu o vídeo, isso é péssimo para você.

O Windows é um sistema operacional muito mais "seguro" em alguns casos, porque não permitirá que você faça isso. Ele pode armazenar em buffer os arquivos da mesma maneira que o Linux, mas também adiciona o bloqueio de arquivos para impedir que você ou outros programas alterem os arquivos nos quais você está trabalhando ou visualizando. Isso ajuda a manter o arquivo intacto e evita que você ou outros programas substituam as alterações um do outro.

Jerry Saravia
fonte
Você não pode realmente excluí- lo. Basta movê-lo e renomeá-lo.
Daniel Beck
2
Você pode 'rm'. Está perto o suficiente para excluí-lo.
Chris Moore