[Ajuda] Arquivo de 8gb
Gostaria de uma ajuda de vocês, tenho um arquivo csv de 8gb, precisaria ler e dividir em arquivos menores, como posso fazer isso sem dar erro de memoria? Pode ser em qualquer linguagem.
Isso é um caso simples de buffering e streaming. Vou dar um exemplo de como faria com c++ já que esse foi meu trabalho de estrutura de dados
int main(){
data_auxiliar data_struct;
string linha;
string csvNomeArquivo = "call911_1.csv";
int tamanho_arquivo = ContarLinhas(csvNomeArquivo);
fstream file_input, file_output;
file_input.open(csvNomeArquivo, ios::in);
file_output.open("output.bin", ios::binary | ios::out | ios::app);
if (file_input && file_output){
getline(file_input, linha);
for (int i = 0; i < tamanho_arquivo; i++){
cout << "[OK]: Convertendo linha: " << i << " do arquivo " << csvNomeArquivo << "\r";
cout.flush();
getline(file_input >> ws, linha);
file_output.write(reinterpret_cast<char*>(&data_struct), sizeof(data_struct));
}
cout << endl;
}
Gostaria de lembrar que este código é incompleto para seu caso e foi retirado exclusivamente do meu repositório que foi criado exclusivamente para converter arquivos .csv
Então poderia precisar de um work around.
Mas teoricamente a prática é a mesma, tu conta o número de linhas e utiliza um for-loop com um getline para pegar cada linha e salvar depois processar e salvar
Como disse que pode ser qualquer linguagem vou dar a dica de usar Node, que é a que tenho experiencia, inclusive em problemas parecidos, usando NodeJs Streams, aqui tem um tutorial básico de por onde começar:https://www.youtube.com/watch?v=O37n35XUxj0, caso queira algo em ptBr tem os videos do Erick Wendell: https://www.youtube.com/watch?v=rcQgqerZ48E&list=PLNCllnjAH50ziJVC-CJg_UrJcZ72jRTVl
pdw, se você utiliza alguma distribuição Linux, caso possa, veja se o comando seguinte apresenta erro de esgotamento de memória. Se seu propósito é apenas dividir o bigfile em arquivos menores para poder acessá-lo por partes mais facilmente, fica a dica!
![WARNING] Devido o comando criar muitos arquivos no diretório, dependendo dos parâmetros que você definir, só o execute após realmente saber como ele funciona, se há espaço em disco suficiente etc.. ![WARNING]
split --lines=10000000 --unbuffered arquivo.csv
ou
split --lines=10000000 arquivo.csv
Supondo que seu arquivo CSV contém muitas linhas e cada registro é uma delas (com todas as suas colunas), ao executar o comando split
acima, serão criados vários arquivos menores (xaa, xab, xac, etc. ou segundo a máscara que você deve definir), todos contendo apenas 10.000.000 linhas ou o número de linhas que você definir no lugar do 10000000. O último arquivo gerado poderá ter um pouco menos caso o número de linhas não seja múltiplo do parâmetro (10000000).
Qualquer dúvida sobre o comando split
, digite no terminal man split
. Costumo utilizar esse comando split
para arquivos binários e hoje vi que é possível separar por linhas quando se trata de um arquivo texto.
PS: Existe outra alternativa utilizando o comando dd
, mas se trata de uma extração mais bruta.