Prefácio
A partir deste artigo, começaremos a aprender o sistema Java IO, que está essencialmente lendo e escrevendo arquivos. Parece simples, mas não é fácil. O sistema de IO da Java tem melhorado e melhorado, e projetou um grande número de classes. Somente entendendo o significado desses tipos e seus respectivos cenários de aplicação podemos melhorar o entendimento do arquivo IO.
Portanto, o primeiro passo é resolver o problema de como representar um arquivo. No mundo Java, "tudo é um objeto" e como corresponder a um arquivo de disco ou diretório real para um objeto Java é o nosso principal problema.
O arquivo é usado no Java para abstrair um arquivo, seja um arquivo normal ou um diretório, pode corresponder a um objeto de arquivo. Eu acho que todos devem ser precisos no posicionamento do tipo de arquivo: ele simplesmente representa um arquivo ou diretório no disco e, na verdade, se baseia em uma classe de sistema de arquivos local independente da plataforma, e o arquivo não pode executar nenhuma operação de leitura e gravação no conteúdo do arquivo que ele representa (é isso que o Stream faz).
Construir uma instância de arquivo
Antes de apresentar o método do construtor da instância do arquivo, precisamos dar uma olhada em seus vários membros importantes do atributo.
Sistema de arquivos estático privado FS = defaultFilesystem.getFilesystem ();
Este é o membro mais central da classe de arquivo, que é representado como a API do sistema de arquivos do sistema atual. Todas as operações emitidas para o disco são baseadas nesta propriedade.
Caminho final de string privado;
O caminho representa o nome do caminho completo da instância atual. Se a instância atual do arquivo representar um diretório, o valor do caminho será o nome completo do diretório. Se ele representa um arquivo puro, o valor desse caminho será igual ao caminho completo do arquivo + o nome do arquivo.
public static final char separatorchar = fs.getSeparator (); public static final char pathseparatorchar = fs.getPathSeparator ();
O separador representa o separador entre os diretórios e o PathSeparatorchar representa o separador sob diferentes caminhos. Esses dois valores são diferentes em diferentes plataformas do sistema. Por exemplo, os valores desses dois no Windows são: "" e ";", onde a proibição é usada para separar vários caminhos diferentes.
A classe de arquivo fornece quatro construtores diferentes para instantar um objeto de arquivo, mas apenas três são mais comumente usados. Também nos concentramos em aprender os três primeiros construtores.
Arquivo público (nome da string PathName)
Esta é a maneira mais comum de instanciar um objeto de arquivo. O valor do nome do caminho pode ser um diretório ou um nome de arquivo simples. Por exemplo:
Arquivo de arquivo = novo arquivo ("c: // usuários // yanga // desktop"); arquivo file1 = new File ("c: //users//yanga//desktop//a.txt"); arquivo file2 = new file ("a.txt");Obviamente, você também pode especificar explicitamente um caminho pai:
Arquivo público (String pai, String Child)
Dentro do construtor, o programa consumirá um caminho completo de arquivo para nós, por exemplo:
Arquivo de arquivo = novo arquivo ("c: // usuários // yanga // desktop", "a.txt"); arquivo file1 = new file ("c: // usuários // yanga // desktop", "java");O terceiro construtor é essencialmente o mesmo que o segundo, exceto que adiciona um processo de encapsulamento da instância do arquivo pai:
Arquivo público (arquivo de arquivo, String Child)
Situações semelhantes não serão explicadas. Não nos aprofundamos na implementação específica interna desses construtores aqui. Não é que seja simples. Em vez disso, o arquivo depende muito do sistema de arquivos local e a implementação de muitos métodos não pode ser vista diretamente. Portanto, para o aprendizado do arquivo, basta ser proficiente no domínio, e a implementação específica não pode ser aprendida em profundidade por enquanto.
Obter informações relacionadas ao nome do arquivo ou caminho
O método getName pode ser usado para obter o nome do arquivo:
public String getName () {int index = path.LastIndexOF (separatorchar); if (índice <prefixlength) de retorno. Return Path.Substring (índice + 1);}Lembra o que nosso separador representa?
Ele é representado como um separador de caminho, o símbolo "" no Windows é armazenado no atributo do caminho e o nome completo do caminho da instância atual do arquivo, para que todos os caracteres após a última ocorrência devem ser o nosso nome de arquivo.
É claro que você deve ter descoberto que, para arquivos puros, esse método pode retornar o nome simples do arquivo, enquanto para um diretório, o valor de retorno será o nome de diretório mais recente. Por exemplo:
Arquivo arquivo = novo arquivo ("c: //users//yanga//desktop//a.txt"); system.out.println (file.getName ()); arquivo file1 = new File ("c: // usersname (yanga // desktop"); system.out.println (file1.getname;A saída não vai surpreendê -lo:
A.TXTDESKTOP
O método getParent é usado para retornar o diretório pai do arquivo atual. Se você é um arquivo simples ou um diretório, eventualmente terá seu diretório pai (é claro, os arquivos temporários gerados pela máquina virtual não são, é claro).
public String getParent () {int index = PATH.LASTIndexOF (separatorchar); if (índice <prefixLength) {if ((prefixLength> 0) && (path.length ()> prefixLength)) caminho de retorno.substring (0, prefixLength); retornar nulo; } Return Path.substring (0, índice);}A implementação do método é muito simples, por isso não entrarei em detalhes.
O método getPath pode retornar o nome completo do arquivo da instância atual do arquivo:
public String getPath () {Return Path;}A seguir, estão algumas operações relacionadas relacionadas a diretórios, que são relativamente simples de implementar. Aqui está uma breve lista:
Aqui precisamos explicar alguma explicação do getCanonicalPath, o que é um caminho padrão, e existe alguma diferença entre um caminho absoluto?
De um modo geral, "../" significa o diretório anterior do diretório em que o arquivo de origem está localizado "../../" significa o diretório anterior do diretório em que o arquivo de origem está localizado e assim por diante. O método Getabsolutepath não executa essas operações de conversão, enquanto o método GetCanonicalPath reconhece esses caracteres especiais e leva a semântica apropriada.
Por exemplo:
Arquivo arquivo = novo arquivo ("..// a.txt"); system.out.println (file.getabsolutepath ()); system.out.println (file.getCanonicalPath ());Resultado da saída:
C:/usuários/yanga/desktop/java/workspace2017/testfile /../ a.txt
C: /users/yanga/desktop/java/workspace2017/a.txt
O primeiro usará "../a.txt" como parte do nome do caminho do arquivo, enquanto o último pode reconhecer que "../a.txt" significa que "A.Txt" está localizado no diretório superior do diretório atual. Essa é a maior diferença entre os dois, adequada para diferentes situações.
Obtenha as informações de atributo do arquivo
A operação desta parte do arquivo é realmente muito simples, nada mais é do que algumas perguntas sobre permissões de arquivo, seja legível, seja gravável, seja um arquivo oculto, etc. Vamos dar uma olhada nesses métodos em detalhes:
Deve -se notar que o método de comprimento pode retornar corretamente o número total de bytes do arquivo para um arquivo puro, mas para um diretório, o valor de retorno será um valor "não especificado", que não é o número total de bytes de todos os arquivos no diretório nem zero, mas é apenas um valor não especificado, que não tem significado.
Operação de arquivo
A operação de arquivos nada mais é do que "adição, exclusão, modificação e pesquisa". Vamos dar uma olhada juntos.
Obviamente, ao lidar com as duas novas operações simples de criação e exclusão, a classe de arquivos também fornece as chamadas operações de "consulta", que precisamos aprender com cuidado. Por exemplo:
public String [] List () {SecurityManager Security = System.getSecurityManager (); if (segurança! = null) {Security.CheckRead (caminho); } if (isInValid ()) {return null; } retorna fs.list (this);}Este método recuperará todos os nomes simples de "arquivos puros" e "diretório" no diretório representado pela instância atual. Por exemplo:
Arquivo de arquivo = novo arquivo ("c: // usuários // yanga // desktop"); string [] list = file.list (); para (String str: list) {System.out.println (str);}O resultado da saída do programa imprimirá os nomes simples de todos os arquivos no diretório da área de trabalho do meu computador, para que não o mostre.
Uma coisa a observar é que, se nossa instância de arquivo não corresponder a um diretório, mas um arquivo simples, a lista retornará NULL.
Em seguida, vejamos um método para recuperar arquivos de diretório:
public string [] list (fileNameFilter filtro) {string nomes [] = list (); if ((nomes == null) || (filtro == null)) {retorna nomes; } List <tring> v = new ArrayList <> (); for (int i = 0; i <names.length; i ++) {if (filter.accept (this, nomes [i])) {v.add (nomes [i]); }} Retorne v.toArray (new String [v.Size ()]);}Esse método é na verdade uma versão sobrecarregada da lista, que permite que você passe um filtro para filtrar apenas os arquivos e diretórios de que precisamos ao pesquisar diretórios.
Mas a definição da interface FileNameFilter é tão simples:
interface pública FileNameFilter {boolean Acep (arquivo dir, nome da string);}Você só precisa substituir esse método de aceitação. Toda vez que a lista de loop obtém um arquivo ou diretório, ele tentará chamar esse método de filtragem primeiro. Se você passar na filtragem, o nome simples do arquivo atual será adicionado à coleção de retorno.
Portanto, a reescrita deste método de aceitação determina quais arquivos podem passar na filtragem e quais não. Vejamos um exemplo:
Os arquivos na pasta de teste na minha área de trabalho são os seguintes:
Arquivo de arquivo = novo arquivo ("c: // usuários // yanga // desktop // test"); String [] list = file.list (new FileNameFilter () {@Override public boolean Acep (arquivo de arquivo, nome da string) {// O objeto de arquivo atual representado por dir // nome é o nome simples do item de arquivo atualmente atravessado se (! Name.endswith (". Txt")) retornar false; mais true}}); para (String str: list) {System.out.println (str); }Aqui, usamos a classe interna anônima para criar uma instância de subclasse do FileNameFilter e, em seguida, implementamos seu método de aceitação. A implementação específica é muito simples, filtrando todos os diretórios e retirando os nomes simples de todos os arquivos simples.
O resultado final da saída é o seguinte:
3.txt
4.txt
Obviamente, também existem dois métodos de lista "mutados" na classe de arquivos, como:
Eles não retornam mais os nomes simples de "arquivos puros" e "diretórios" no diretório de destino, mas retornam o objeto de arquivo correspondente. De fato, não é nada. O diretório de destino + um nome simples pode criar essas instâncias de arquivo.
Portanto, essencialmente, o método da lista não atravessará todos os arquivos no diretório de destino, ou seja, os arquivos no subdiretório do diretório de destino não serão acessados e atravessados.
Portanto, você deve pensar em como atravessar todos os arquivos no diretório de destino, incluindo arquivos profundos nos subdiretórios de primeiro nível. A resposta será dada no final do artigo.
Os próximos dois métodos estão relacionados à criação de pastas:
Ambos são baseados na instância atual do arquivo para criar pastas. Em relação às suas diferenças, vamos primeiro olhar para um pedaço de código:
Arquivo arquivo = novo arquivo ("c: // usuários // yanga // desktop // test2"); system.out.println (file.mkdir ()); arquivo file2 = new File ("c: // users // yanga // desktop // test3/hello); system.out.println (file2.mkdirEntre eles, o teste2 e o teste3 não existem até que o programa seja executado.
O resultado da saída é o seguinte:
verdadeiro
falso
Por que o último não conseguiu criar?
Isso se deve ao fato de que o método MKDIR pode criar apenas uma pasta por vez, o que causará falha na criação se o pai ou um diretório pai ou maior do diretório especificado existir um diretório não criado.
O método MKDIRS é usado para resolver essa situação. Ele criará todos os diretórios não criados no caminho de destino, consulte o código:
Arquivo file3 = novo arquivo ("c: // usuários // yanga // desktop // test3 // hello // 231"); system.out.println (file3.mkdirs ());Mesmo que nossa pasta Test3 não exista, após a execução do programa, as três pastas Test3, Hello e 231 serão criadas.
Além disso, o arquivo também possui um método para criar arquivos temporários. Os chamados arquivos temporários são: eles existem durante o tempo de execução e são destruídos quando a máquina virtual é desligada. Você pode estudá -lo sozinho. É relativamente simples de usar, então não vou entrar em detalhes aqui.
Nesse ponto, aprendemos aproximadamente o arquivo do tipo de arquivo. Acredito que todos sentirão mais ou menos que o design de representar arquivos e diretórios puros que usam o mesmo tipo parece um pouco confuso e irracional. Sei que o JDK1.7 Sun lançou arquivos e caminho para separar arquivos e diretórios, e aprenderemos mais sobre isso nos artigos futuros.
Todos os códigos, imagens e arquivos no artigo são armazenados na nuvem no meu github:
(https://github.com/singleyam/overview_java)
Você também pode optar por baixar localmente.
Resumir
O acima é o conteúdo inteiro deste artigo. Espero que o conteúdo deste artigo tenha certo valor de referência para o estudo ou trabalho de todos. Se você tiver alguma dúvida, pode deixar uma mensagem para se comunicar. Obrigado pelo seu apoio ao wulin.com.