Problem z odczytem plików binarnych w JUCE.

0

Cześć.
Mam problem z odczytem plików i przesłaniem ich do komponentu TextEditor w JUCE. Wczytywać coś tam wczytuje ale zajmuje to koszmarnie dużo czasu (2 MB parę minut).

Kod to mniej więcej to:

class MainComponent  : public juce::Component
{
public:
  juce::TextButton open_button{"Open"};
  juce::TextEditor texteditor;

MainComponent()
    {   
        setSize (700, 500);
        close_button.setBounds(0,0,200,50);
        addAndMakeVisible(open_button);
        text_editor.setBounds(0,60,500,350);
        addAndMakeVisible(text_editor);
        text_editor.setMultiLine(true,true);

open_button.onClick = [this](){

/* utworzenie komponentu fileChooser */

fChooser = std::make_unique<juce::FileChooser>("Choose file", 
defaultDirectory, "*.*", true, false, this);

auto folderChooserFlags = juce::FileBrowserComponent::openMode 
| juce::FileBrowserComponent::canSelectDirectories | 
juce::FileBrowserComponent::canSelectFiles;

/* uruchomienie fileChooser*/

fChooser->launchAsync(folderChooserFlags, [this](const juce::FileChooser& chooser)
{
   juce::File chosenFile = chooser.getResult();
   juce::String tmp_path= chosenFile.getFullPathName();
   oldPath=tmp_path; 
   char file_path[555];
   // zmienne do odebrania zmiennej z fgetc i wskazniki do plikow
   int tmp_int;
   FILE *file_1,*file_2;

   strcpy(file_path,tmp_path.toRawUTF8());
    
   juce::FileInputStream input_stream{chosenFile};
   juce::int64 size_of_file;
   juce::String new_tmp_string;
   juce::String new_output_string="";

   // pobranie rozmiaru pliku (gdyby zaszla koniecznosc utworzenia dynamicznej tablicy do przechowania zawartosci pliku)
   size_of_file=input_stream.getTotalLength();
   juce::String str = juce::String(size_of_file);
    
   // tworzy plik zeby mozna było sprawdzic czy sciezka pliku jest rozmiar sa odpowiednie
    
   file_1=fopen("K:\\a.txt","w");           
   fprintf(file_1,"%s%s%s",file_path,",",str);            
   fclose(file_1);
    
   file_2=fopen(file_path,"rb");
    
   //wczytuje binarnie zawartosc zamienia to na ciagi znakow w systemie dziesietnym
   //i tworzy lancuch ktory zostanie zaladowany do komponentu textEditor
        
    while(!feof(file_2)){ 
            tmp_int=fgetc(file_2);
            new_tmp_string=juce::String(tmp_int);   
            new_output_string+=new_tmp_string;
            new_output_string+=" , ";}
      
    fclose(file_2);
  
    // wczytywanie zawartosci pliku do TextEditor
    text_editor.setText(new_output_string,true);    
        
    // ustawienie textu na przycisku zeby pokazal rozmiar wybranego pliku 
    open_button.setButtonText(str);               
        
    // ustawienie nowego folderu domyslnego ktory byl uzywany przez uzytkownika
    defaultDirectory=oldPath;                        

});
//..
}

Wczytywać coś tam wczytuje ale pracować to się na tym nie da. WinHex pokazywał bez przycinania całe partycje, Paragon Partition Menager tak samo, i to 10 lat temu.

1

Człowieku! Wczytaj plik jednym ciurkiem! W normalnym C++:

string load_file(char const *filepath)
{
    ifstream src(filepath);
    ostringstream buf;
    buf<<src.rdbuf();
    return buf.str();
}

Jeżeli ten juce nie pozwala ci na tak prosty kod to może wywal go w cholerę.
Używasz obsługę pliku rodem z C doprawdy?
W pętli po znakach pliku masz:

  new_tmp_string=juce::String(tmp_int);   
  new_output_string+=new_tmp_string;

Czy rozumiesz że masz tu koszt kwadratowy?

0

@_13th_Dragon: To aukrat mi podpowiedział ktoś na juce forum. Ja tam normalnie użyłem fgetc ale różnicy nie było. Próbowałem kilku wersji. Na początku zrobiłem tak jak Borland uczy. Strasznie poważnie traktujesz te bzdety, może idź się prześpij.

2

Masz dla juce::String - znalazłem w kilka sekund.

juce::String load_file(char const *filepath)
{
    ifstream src(filepath);
    ostringstream buf;
    buf<<src.rdbuf();
    return juce::String(buf.str());
}
0

Masz Ty moja "sekundo"

Rozpoczęto kompilację...
1>------ Kompilacja rozpoczęta: Projekt: NewProject_App, Konfiguracja: Debug x64 ------
1>Main.cpp
1>K:\juce\zzz\NewProject\Source\MainComponent.h(93,43): warning C4840: nieprzenośne użycie klasy „juce::String” jako argumentu funkcji ze zmienną liczbą argumentów
1>K:\juce\zzz\NewProject\Source\MainComponent.h(93,43): message : element „juce::String::String” nie jest trywialny
1>C:\Users\juzio\Downloads\juce-7.0.3-windows\modules\juce_core\text\juce_String.h(62,5): message : zobacz deklarację „juce::String::String”
1>K:\juce\zzz\NewProject\Source\MainComponent.h(93,43): message : konstruktor i destruktor nie zostaną wywołane; kopia bitowa klasy zostanie przekazana jako argument
1>C:\Users\juzio\Downloads\juce-7.0.3-windows\modules\juce_core\text\juce_String.h(52,17): message : zobacz deklarację „juce::String”
1>K:\juce\zzz\NewProject\Source\MainComponent.h(93,20): warning C4477: „fprintf”: ciąg formatu „%s” wymaga argumentu typu „char *”, ale argument 3 ze zmienną liczbą argumentów ma typ „juce::String”
1>K:\juce\zzz\NewProject\Source\MainComponent.h(99,6): error C2065: "ifstream": niezadeklarowany identyfikator
1>K:\juce\zzz\NewProject\Source\MainComponent.h(99,15): error C2146: błąd składniowy: brakuje „;” przed identyfikatorem „src”
1>K:\juce\zzz\NewProject\Source\MainComponent.h(99,19): error C2065: "filepath": niezadeklarowany identyfikator
1>K:\juce\zzz\NewProject\Source\MainComponent.h(99,15): error C3861: "src": identyfikatora nie odnaleziono
1>K:\juce\zzz\NewProject\Source\MainComponent.h(100,5): error C2065: "ostringstream": niezadeklarowany identyfikator
1>K:\juce\zzz\NewProject\Source\MainComponent.h(100,19): error C2146: błąd składniowy: brakuje „;” przed identyfikatorem „buf”
1>K:\juce\zzz\NewProject\Source\MainComponent.h(100,19): error C2065: "buf": niezadeklarowany identyfikator
1>K:\juce\zzz\NewProject\Source\MainComponent.h(101,5): error C2065: "buf": niezadeklarowany identyfikator
1>K:\juce\zzz\NewProject\Source\MainComponent.h(101,10): error C2065: "src": niezadeklarowany identyfikator
1>K:\juce\zzz\NewProject\Source\MainComponent.h(113,37): error C2065: "buf": niezadeklarowany identyfikator

Jeszcze lepszy był ten koleś z JUCE forum, po tym co mi napisał to kompilator coś chciał przeładowywać na gorąco, jakieś okna z plikami nagłówkowymi wyświetlił ale też dajesz rade. xD

0

Na Builderze jak zrobię to tak :

struct tabs{
            char *elem;
            };
{
FILE *file_4,*file_5;
int tmp;
unsigned int bb=0;
unsigned int bs=0;
unsigned int f_size=0;
unsigned int new_size=0;
int pos;

file_4=fopen("K:\\2.exe","rb");
while(!feof(file_4)){tmp=fgetc(file_4);f_size++;


};
fclose(file_4);

ShowMessage("Size expected is : "+IntToStr(f_size)+".");

tabs *tabliczka=new tabs[f_size];
pos=f_size/100;
ShowMessage(IntToStr(pos));


file_4=fopen("K:\\2.exe","rb");
file_5=fopen("K:\\tmp_tekst.txt","wb");


ProgressBar1->Position=0;
ShowMessage("Start writing new file.");
while(!feof(file_4)){tmp=fgetc(file_4);
char tmp_tab[8]={'\0','\0','\0','\0','\0','\0','\0','\0',};
AnsiString l=IntToStr(tmp)+" , ";
strcpy(tmp_tab,l.c_str());
tabliczka[bb].elem=new char[8];

strcpy(tabliczka[bb].elem,l.c_str());
new_size=new_size+8;
fprintf(file_5,"%s",tabliczka[bb].elem); bb++;
bs++;
if(bs==pos){bs=0;ProgressBar1->Position++;};
};
fclose(file_5);
fclose(file_4);

ShowMessage("New file written.");


char *main_table=new char[new_size];

file_5=fopen("K:\\tmp_tekst.txt","rb");

ShowMessage("Start reading new file.");

bb=0;
bs=0;
ProgressBar1->Position=0;
while(!feof(file_4)){
tmp=fgetc(file_5);

main_table[bb]=(char)tmp;
bb++;
bs++;
if(bs==pos){bs=0;ProgressBar1->Position++;};};

fclose(file_5);
ShowMessage("New file read.");

//ShowMessage(tabliczka[0].elem);
ShowMessage("Setting Memo1 text");


Memo1->Text=main_table;


ShowMessage("Removing temporary data.");


delete []  main_table;
for(unsigned int p=0;p<f_size;p++){delete [] tabliczka[0].elem; }

ShowMessage("Done.");
}

To działa perfekcyjnie.

2
infinityhost napisał(a):

@_13th_Dragon: To aukrat mi podpowiedział ktoś na juce forum. Ja tam normalnie użyłem fgetc ale różnicy nie było. Próbowałem kilku wersji. Na początku zrobiłem tak jak Borland uczy. Strasznie poważnie traktujesz te bzdety, może idź się prześpij.

Na każdym forum ludzie pomagają najlepiej względem swoich możliwości.
Jako, że ludzie mają różne możliwości, to dostaniesz zawsze odpowiedzi różnej jakości.
Dziwne, że delikwent nie został "naprostowany" na forum tematycznym Juce.

Pierwszy raz słyszę o Juce, ale minutka googlania wystarczyła by dostać coś takiego:

JUCE: Tutorial: File reading

Reading a whole file into a string

While the File class is designed primarily to store and manipulate paths to files, there are a few convenient functions for reading files in really simple ways. For example, the File::loadFileAsString() function does exactly what it says: it reads a whole file into a String object. Of course, if the file selected isn't a text file then the result may be impossible to make sense of (although JUCE won't crash). This function can detect and read both UTF-8 and UTF-16 formats:

void readFile (const juce::File& fileToRead)
{
    if (! fileToRead.existsAsFile()) // [1]
        return;
    auto fileText = fileToRead.loadFileAsString();
    textContent->setText (fileText);
}

Notice that we check to see if the file chosen actually exists [1]. Since we chose the file from the operating systems then this shouldn't fail, but it's good practice to make these kinds of checks when dealing with files. Run the app and load the juce.txt text file provided in the Resources directory of the demo project. The result will be as shown in the following screenshot:

Reading and displaying a text file

There is an equivalent function—File::loadFileAsData()—to read an entire file into a MemoryBlock object.

I jest to oczywiście najbardziej sensowne rozwiązanie.

Moja rada zanim zadasz pytanie na jakimkolwiek forum, najpierw pogrzeb w oficjalnej dokumentacji, potem google.
Odpowiedzi na wszelkich forach i na Stackoverflow należy traktować sceptycznie, bo w każdym miejscu kompetentni stanowią mniej niż 5%.
Z czasem nauczysz się odróżniać, dobre odpowiedzi o kiepskich.

1 użytkowników online, w tym zalogowanych: 0, gości: 1