Ir para conteúdo
Fórum Script Brasil
  • 0

Arquivos Binários


Andersonjb

Pergunta

E aiii pessoal, beleza? Bem to com uma duvida de arquivos aqui. Bem, eu queria fazer o seguinte:

Eu queria pegar um arquivo binário qualquer, pegar um arquivo texto, e substituir o texto do arquivo binário por um texto normal, a partir de um determinado ponto. Por exemplo, eu tenho o offset do arquivo, que e a variavel que eu defino aonde esta uma determinada letra no arquivo, por ordem sequencial a partir do zero. Por exemplo:

Jaba

Offset de J = 0

Offset de a = 1

Offset de b = 2

Offset de a = 3

So que eu estou com duvida de como fazer isso. Até agora eu fiz o seguinte, li o arquivo binário, li o arquivo normal, define o ponto de substituição, so que não sei como montar meu laço For, olhem só:

        Dim arquivosaida As FileStream = New FileStream(nomerom, FileMode.Create, FileAccess.Write)
        Dim binariosaida As BinaryWriter = New BinaryWriter(arquivosaida, System.Text.Encoding.GetEncoding(28591))
        Dim leia As New IO.StreamReader(nomescript)
        Dim letra, script As String
        Dim qt As Double = 0
        Dim marca As Boolean

        For Each letra In 
            MsgBox(script = leia.Read)
            If qt = 256 Then
                marca = True
            End If
            If marca = True Then
                binariosaida.Write(Asc(letra))
                qt = qt + 1
            End If
            If qt = 260 Then
                marca = False
            End If
        Next
        arquivosaida.Close()
        binariosaida.Close()

alguém ai pode me dar uma esclarecida?

Link para o comentário
Compartilhar em outros sites

Posts Recomendados

  • 0

O laço for é pra poder substituir as palavras. Minha lógica e essa: a variavel qt é o meu offset, ele indica a posição das letras, então passou uma letra, ele contou um, certo? Quando qt chegar na posição 256, ele vai começar a substituir as letras do arquivo binário pelo do arquivo texto, entendeu? Eu usei o For pra chegar na letra que eu quero substituir... Mas se você tiver uma idéia melhor de como você pode fazer isso, eu agradeço, hehe! E sim, digamos que eu queira colocar a palavra jaba no arquivo, voce pode perceber que eu coloquei ate a condição de 256 a 260, 4 letras, pra ela entrar certinho! Falows!

Link para o comentário
Compartilhar em outros sites

  • 0

Eu acho bem mais prático ler o arquivo para um array de bytes e acessar as posições diretamente. Veja um exemplo abaixo:

        Dim nomearq As String = "c:\arquivo.exe"

        Dim arquivo As New StreamReader(nomearq, System.Text.Encoding.Default)
        Dim conteúdo As String = arquivo.ReadToEnd()
        arquivo.Close()

        Dim b() As Byte = System.Text.Encoding.Default.GetBytes(conteúdo)

        b(256) = Asc("J")
        b(257) = Asc("a")
        b(258) = Asc("b")
        b(259) = Asc("a")

        Dim gravar As New StreamWriter("c:\teste.exe", False, System.Text.Encoding.Default)
        gravar.Write(System.Text.Encoding.Default.GetString(b))
        gravar.Close()

Sacou? ;) Veja que isso é só um **exemplo** e é óbvio que você *pode* (mas acho que nem precisa, uma vez que você sabe o offset inicial) precisar de um laço For para ir trocando os bytes, a diferença é que você não vai precisar *caminhar* com o For até lá.

Abraços,

Graymalkin

Link para o comentário
Compartilhar em outros sites

  • 0

Gray, eu te amo, ne que o negócio aqui deu certo? valeu mesmo, hehe! Antes o arquivo era modificado e fica com 0 bytes, mó estranho. Agora só falta dar um jeito dele pegar um arquivo externo, e inserir as palavras daquele arquivo no binário. Mais eu tenho algumas duvidas:

1º - Quando você fes isto:

Dim b() As Byte = System.Text.Encoding.Default.GetBytes(conteúdo)

Você fez uma matriz de bytes, correto?

2º - Porque aquele parâmetro false no Stream Writer?

3º - E porque você não usou um FileStream e um BinaryWriter, eles não servem para fazer isso?

Link para o comentário
Compartilhar em outros sites

  • 0
1º - Quando você fes isto:
Dim b() As Byte = System.Text.Encoding.Default.GetBytes(conteúdo)

Você fez uma matriz de bytes, correto?

Sim, exatamente.

2º - Porque aquele parâmetro false no Stream Writer?

O segundo parâmetro do construtor de um StreamWriter, naquele caso, se chama Append e define se você quer adicionar a um arquivo existente ou recriá-lo do zero. O False então diz que ele deve sempre recriar o arquivo e nunca gravar no final de um que já exista (se não fosse isso, na segunda vez que você executasse o arquivo ficaria com o dobro do tamanho porque ele mesmo seria adicionado ao destino).

3º - E porque você não usou um FileStream e um BinaryWriter, eles não servem para fazer isso?

É, também podem ser utilizados, mas StreamReader e StreamWriter são mais práticos porque leêm e gravam strings (sim, eu sei que BinaryWriter também faz isso, mas ele também exige a criação de um objeto Stream).

Abraços,

Graymalkin

Link para o comentário
Compartilhar em outros sites

  • 0

Então, Gray, vamos lá, eu encontrei uma brecha vital para o meu projeto:

Bem, ao fazer isso:

        Dim nomearq As String = "c:\arquivo.exe"

        Dim arquivo As New StreamReader(nomearq, System.Text.Encoding.Default)
        Dim conteúdo As String = arquivo.ReadToEnd()
        arquivo.Close()

        Dim b() As Byte = System.Text.Encoding.Default.GetBytes(conteúdo)

Eu estou carregando todo o conteudo do arquivo.exe na memória, certo? Só que o problema é que a maioria dos arquivos que eu vou manipular tem em média 700 MEGABYTES! E se esse código carrega todo o arquivo na memória (em um arraylist), isso não será possivel, correto? Então, o que eu posso fazer para burlar isso?

Link para o comentário
Compartilhar em outros sites

  • 0

Certo, e como eu faria isso? Digamos que o arquivo seja de 700 megas, ai eu leria em 7 blocos de 100, certo? So que isso traria varios problemas, por exemplo: E se o texto que eu quisesse modificar fosse um intermediario entre 200 e 300?

Link para o comentário
Compartilhar em outros sites

  • 0

Certo, e como eu faria isso? Digamos que o arquivo seja de 700 megas, ai eu leria em 7 blocos de 100, certo? So que isso traria varios problemas, por exemplo: E se o texto que eu quisesse modificar fosse um intermediario entre 200 e 300?

Você poderia ler do 250 ao 350, e iria continuar sendo 100. ;)

O ideal seria ler uma determinada quantidade que permitisse mostrar a barra de rolagem na DataGrid. Daí, ao detectar que a barra foi rolada para baixo você pegaria mais um pedaço. E assim por diante, até o final do arquivo.

Abraços,

Graymalkin

Link para o comentário
Compartilhar em outros sites

  • 0
Você poderia ler do 250 ao 350, e iria continuar sendo 100.

Certo, mais eu supus 100, o valor pode ser qualquer um.

O ideal seria ler uma determinada quantidade que permitisse mostrar a barra de rolagem na DataGrid. Daí, ao detectar que a barra foi rolada para baixo você pegaria mais um pedaço. E assim por diante, até o final do arquivo.

Hauhaua, mais eu não estou usando uma DataGrid, eu estou usando um RichTextBox.

Link para o comentário
Compartilhar em outros sites

  • 0
Você poderia ler do 250 ao 350, e iria continuar sendo 100.

Certo, mais eu supus 100, o valor pode ser qualquer um.

Sim, você pode especificar o valor que quiser. É claro que vai haver um valor ideal para visualização (uma determinada quantidade de bytes que preencha por completo a RichTextBox sem, por exemplo, acabar no meio de uma linha).

O ideal seria ler uma determinada quantidade que permitisse mostrar a barra de rolagem na DataGrid. Daí, ao detectar que a barra foi rolada para baixo você pegaria mais um pedaço. E assim por diante, até o final do arquivo.

Hauhaua, mais eu não estou usando uma DataGrid, eu estou usando um RichTextBox.

Tanto faz, a idéia ainda é a mesma... :P

Abraços,

Graymalkin

Link para o comentário
Compartilhar em outros sites

  • 0

Bem, eu sei que faiz tempo que não continuo essa duvida, mas vamos la:

Eu vi que se eu souber a quantidade de caracteres do arquivo eu posso coloca-lo em um For e ler caracter por caracter, usando somente o Método Read. Só que o problema é pegar a quantidade de caracteres sem passar o conteúdo do arquivo para uma variavel, já que eu estou tentando evitar isso. Bem, tem como pegar a quantidade de caracteres do arquivo sem colocar seu conteúdo em uma váriavel?

Link para o comentário
Compartilhar em outros sites

  • 0

Bem, eu sei que faiz tempo que não continuo essa duvida, mas vamos la:

Eu vi que se eu souber a quantidade de caracteres do arquivo eu posso coloca-lo em um For e ler caracter por caracter, usando somente o Método Read. Só que o problema é pegar a quantidade de caracteres sem passar o conteúdo do arquivo para uma variavel, já que eu estou tentando evitar isso. Bem, tem como pegar a quantidade de caracteres do arquivo sem colocar seu conteúdo em uma váriavel?

Você poderia simplesmente ir lendo byte por byte até chegar ao final do arquivo, utilizando um While. Mas, se você quer realmente saber quantos bytes o arquivo tem, basta olhar o tamanho dele, o que pode ser feito assim:

        Dim info As New IO.FileInfo("c:\teste.txt")
        Debug.WriteLine(info.Length)

Certo? ;)

Graymalkin

Link para o comentário
Compartilhar em outros sites

  • 0

Bem, isso ai deu certo Gray.

O meu método de como "rodar" o arquivo da certo tambem, então eu vou seguir ele mesmo. Só que eu estou com um problema: como eu faço para levar o Metodo Read para uma determinada posição do arquivo? Por exemplo, o tamanho do arquivo é 100, e eu tenho um laço com o contador, certo? Só que eu quero começar a ler a partir do dado 50, só que ele sempre vai ler do dado 0, como eu faço para que ele comece a ler do dado 50, por exemplo?

Link para o comentário
Compartilhar em outros sites

  • 0

Pelo método Seek(). No primeiro parâmetro você especifica quantos bytes a partir da posição determinada pelo segundo parâmetro (que pode ser início, atual ou fim):

obj.Seek(50, IO.SeekOrigin.Begin) 'pula 50 bytes a partir do início
obj.Seek(50, IO.SeekOrigin.End) 'vai para 50 bytes antes do fim

Certo? ;)

Graymalkin

Link para o comentário
Compartilhar em outros sites

  • 0

Bem, pro pessoal que as vezes acompanha o tópico ai, vai saber, né, eu vou postar como eu consegui fazer:

arquivo.BaseStream.Seek(x, IO.SeekOrigin.Begin)
Onde "x" é a variavel da posição do arquivo. Na verdade, o titio Gray que me ensinou. :P E gray, eu tenho outra duvida: bem, eu estou girando o arquivo em um For usando isto que você me passou, só que na hora de declarar a Stream de Leitura, está dando erro. Eu estou declarando asssim:
Dim arquivo As New IO.StreamWriter(nomerom, System.Text.Encoding.Default)
Só que da esse erro:
Overload resolution failed because no accessible 'New' can be called with these arguments: 'Public Sub New(path As String, append As Boolean)': Value of type 'System.Text.Encoding' cannot be converted to 'Boolean'. 'Public Sub New(stream As System.IO.Stream, encoding As System.Text.Encoding)': Value of type 'String' cannot be converted to 'System.IO.Stream'.
O que que é isso?? Bem, pro pessoal que as vezes acompanha o tópico ai, vai saber, né, eu vou postar como eu consegui fazer:
arquivo.BaseStream.Seek(x, IO.SeekOrigin.Begin)
Onde "x" é a variavel da posição do arquivo. Na verdade, o titio Gray que me ensinou. :P E gray, eu tenho outra duvida: bem, eu estou girando o arquivo em um For usando isto que você me passou, só que na hora de declarar a Stream de Leitura, está dando erro. Eu estou declarando asssim:
Dim arquivo As New IO.StreamWriter(nomerom, System.Text.Encoding.Default)

Só que da esse erro:

Overload resolution failed because no accessible 'New' can be called with these arguments:

'Public Sub New(path As String, append As Boolean)': Value of type 'System.Text.Encoding' cannot be converted to 'Boolean'.

'Public Sub New(stream As System.IO.Stream, encoding As System.Text.Encoding)': Value of type 'String' cannot be converted to 'System.IO.Stream'.

O que que é isso??

Link para o comentário
Compartilhar em outros sites

  • 0

Bem, pro pessoal que as vezes acompanha o tópico ai, vai saber, né, eu vou postar como eu consegui fazer:

arquivo.BaseStream.Seek(x, IO.SeekOrigin.Begin)
Onde "x" é a variavel da posição do arquivo. Na verdade, o titio Gray que me ensinou. :P E gray, eu tenho outra duvida: bem, eu estou girando o arquivo em um For usando isto que você me passou, só que na hora de declarar a Stream de Leitura, está dando erro. Eu estou declarando asssim:
Dim arquivo As New IO.StreamWriter(nomerom, System.Text.Encoding.Default)
Só que da esse erro:
Overload resolution failed because no accessible 'New' can be called with these arguments: 'Public Sub New(path As String, append As Boolean)': Value of type 'System.Text.Encoding' cannot be converted to 'Boolean'. 'Public Sub New(stream As System.IO.Stream, encoding As System.Text.Encoding)': Value of type 'String' cannot be converted to 'System.IO.Stream'.
O que que é isso??
Porque o segundo parâmetro é o append e não o encoding (que é o terceiro). E isso está escrito na mensagem de erro acima. Você deveria fazer assim:
Dim arquivo As New IO.StreamWriter(nomerom, False, System.Text.Encoding.Default)

Abraços,

Graymalkin

Link para o comentário
Compartilhar em outros sites

  • 0

E ai Gray, beleza? Bem, estou tendo mais problemas. :(

Bem, como você sabe, estou mechendo com arquivos binários, e no arquivo não pode ser implementada ou retirada nenhuma informação. Estou lendo o arquivo da seguinte maneira:

        Dim arquivo1 As New IO.FileStream(nomerom, IO.FileMode.Open, IO.FileAccess.ReadWrite)
        Dim arquivo As New IO.BinaryWriter(arquivo1, System.Text.Encoding.Default)
Mais acontece que o arquivo está sendo comropido, na hora de eu inserir os dados. Bem, para inserir o dado, eu levo o arquivo até a posição que eu quero:
arquivo.Seek(x, IO.SeekOrigin.Begin)
Depois, adiciono o dado:
                            Dim l As Char = caracteres(j)
                            arquivo.Write(l)

Bem, como pode ver eu tenho uma matriz, que eu pego de um indice, adiciono no arquivo, e mando gravar. Mas acontece que o arquivo se corrompe depois da gravação. O que eu fiz de errado?

Link para o comentário
Compartilhar em outros sites

  • 0

E ai Gray, beleza? Bem, estou tendo mais problemas. :(

Bem, como você sabe, estou mechendo com arquivos binários, e no arquivo não pode ser implementada ou retirada nenhuma informação. Estou lendo o arquivo da seguinte maneira:

        Dim arquivo1 As New IO.FileStream(nomerom, IO.FileMode.Open, IO.FileAccess.ReadWrite)
        Dim arquivo As New IO.BinaryWriter(arquivo1, System.Text.Encoding.Default)

Mais acontece que o arquivo está sendo comropido, so pelo simples fato de eu percorre-lo. Eu estou fazendo alguma coisa errada?

Só com este pedaço aí não dá pra dizer nada, já que aparentemente você está apenas abrindo o arquivo. O que você faz ao percorrê-lo?

Abraços,

Graymalkin

Link para o comentário
Compartilhar em outros sites

  • 0

Eu editei o Post acima Gray, mais a unica coisa que eu faço demais é comparar o caracter que eu quero inserir com uma lista de caracteres ( na matriz caracteres(j) ), e se estiver na lista, ele insere da maneira como editei acima. Alguma cagada?

Link para o comentário
Compartilhar em outros sites

  • 0

Eu editei o Post acima Gray, mais a unica coisa que eu faço demais é comparar o caracter que eu quero inserir com uma lista de caracteres ( na matriz caracteres(j) ), e se estiver na lista, ele insere da maneira como editei acima. Alguma cagada?

Em que sentido você diz que o "arquivo corrompe"? Você já verificou se o caracter inserido tem realmente apenas um byte?

Abraços,

Graymalkin

Link para o comentário
Compartilhar em outros sites

  • 0
O arquivo é um jogo. Ele roda normalmente, mais quando insiro e vou joga-lo, ele não pega. E como assim verificar se um o caracter tem somente 1 byte?

Um caracter, em Unicode, pode ter até 4 bytes, e não necessariamente apenas um. Você pode verificar se este caracter que você está escrevendo tem apenas um byte olhando se na posição posterior a qual ele é inserido permanece o mesmo byte que estava antes.

Abraços,

Graymalkin

Link para o comentário
Compartilhar em outros sites

  • 0

Putz, isso realmente acontece. Então quer dizer que eu estou gravando um dado em Unicode? E como faço para que isso não aconteça?

Isso depende de quais caracteres você está escrevendo. Certos caracteres, como o ŝ e o ŭ, por exemplo, só existem em Unicode. Mas, se você só trabalha mesmo com caracteres da tabela ASCII/ANSI, então pode descartar o byte de valor 0 que acompanha o código Unicode dos mesmos.

Abraços,

Graymalkin

Link para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,2k
    • Posts
      651,9k
×
×
  • Criar Novo...