Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
und zwar handelt es sich um ca. 1,6gb große dateien,die am ende ca. 10 zu entfernende dateien haben - und zwar ohne dass die ganze datei kopiert wird oder ähnliches. das ganze sollte also nicht länger,als 20ms dauern.
die anzahl der zu entfernenden zeilen,sowie die anzahl der nicht zu entfernenden zeilen ist bekannt.
ist das möglich und wenn ja,womit am besten?
mit random access file kann man ja gezielt zeilen anspringen.
ich arbeite gerade ziemlich unter hochdruck an einem programm,was bis morgen abend fertig zu sein hat
und momentan sind noch viele baustellen zu fixen..deswegen wollte ich jetzt nicht erst ewig rumprobieren,sondern gleihc nachfragen und erst rumtesten,wenn ich die gewissheit habe dass es geht.
Lege einen Puffer (byte[]) an, lies dann via RandomAccessFile die Datei häppchenweise von hinten (also rückwärts durch den Puffer) und zähle die Zeilenumbrüche (\n, \r, \n\r oder \r\n). Wenn du dabei den Index verfolgst, kommst du so schnell an die letztendliche Größe der Datei und kannst mit setLength(long) die Dateilänge festlegen; Datei schließen, fertig.
Das geht allerdings nur, wenn die Zeilenumbrüche auch eindeutig wie oben beschrieben byteweise(!) kodiert sind (wie z. B. in ASCII oder UTF-8).
Eine andere Variante, die aber u. U. viel länger dauert: Einfach vorwärts schreiten und Zeilenumbrüche z. B. mit einem Reader zählen.
Aber warum soll das alles so wahnsinnig schnell gehen? ôo
Ark
EDIT: Andere Variante, die aber Vorarbeit benötigt: passend zu der Datei einen Index anlegen.
Und noch eine andere Variante: nicht die Datei so groß werden lassen, sondern z. B. nach 100000 Zeilen (hängt davon ab, wie lang sie sind) eine zweite Datei anlegen usw.
die erzeugte aussagenlogische formel ist gerade bei großen sudokus sehr lang ( 81x81 sudoku ergibt eine datei von ca. 1,6gb)
wenn interesse besteht,lade ich den code mal hoch.
ich werde mich morgen erst um die methode zum zeilen entfernen kümmern.
es würde mir wahnsinnig viel helfen,wenn du evtl mal aus der kalten deinen lösungsansatz in form von code niederschreiben könntest. das würde mir viel zeit sparen,da ich mich momentan noch garnicht mit den puffern auskenne und erst belesen müsste.
anhand von codeschnipseln würde das auf jeden fall schneller gehn
wär nett..wenn nicht,ist es aber auch nicht so schlimm
Momentan interessiert mich, wie du die Informationen in der Datei organisierst. Außerdem wäre es interessant zu erfahren, ob es bestimmte Einschränkungen bzw. Muster in der Datei gibt (z. B. "alle Zeilen sind genau soundso lang").
die kodierte datei enthält dann also eine bestimmte anzahl "feste" regeln (die für jedes sudoku gelten)
und hinten dran kommen dann dynamisch erzeugte regeln (die anhand des vorgegebenen ungelösten sudokus erzeugt werden). nachdem es dann gelöst wurde,sollen diese regeln wieder entfernt werde,damit die "festen" regeln für das nächste sudoku weiterverwendet werden können.
diese dynamisch angehangenen regeln sind von der form
Es wäre noch schon, wenn du uns sagen würdest, was was bedeuten soll und in welchem Wertebereich das alles liegt. Außerdem ist der worst case interessant.
All diese Informationen können nötig sein, um z. B. Redundanzen zu erkennen und zu eliminieren. Dies löst noch nicht direkt das Problem, bestimmte Informationen am Ende zu entfernen, könnte aber die Datei gewaltig schrumpfen lassen, und so kann man zumindest das Zeitproblem in den Griff kriegen. :shock:
Gibt es bei diesen Informationen auch irgendwie eine Art Anfang eines Blockes? Was ist mit dem, was gelöscht werden soll? Fängt dies immer an einer ganz bestimmten Stelle an und ist an einer ganz bestimmten Stelle zu Ende?
Bei einer Organisation, wie du sie uns hier präsentierst, wundert nicht, dass die Datei so gigantisch groß wird. :shock:
die datei,die ich hier wieder "sauber" machen will,ist noch total unberührt (abgesehen von den angehangenen regeln,die vom gegebenen ungelösten sudoku erzeugt werden)
alles was danach kommt,wäre hier total überflüssig.
ich habe mir wirklich viele gedanken gemacht. alles weitere würde jetzt viel zu viel zeit in anspruch nehmen. das projekt läuft jetzt schon über 4 monate.es würde mich wundern,wenn du jetzt noch große,zeitersparende kenntnisse einbringen könntest
ich bin mir relativ sicher,dass mein programm schon sehr gut funktioniert. (81x81 sudokus benötigen auf einem relativ guten rechner ca. 30sekunden, 49x49 sudokus auf einem rechner mit hyperthreading ca. 8sekunden)
es widerspricht zwar dem allgemeinen verständnis..aber erweiterte kodierungen sind um ca. 90% schneller zu lösen,als "minimale" kodierungen.meist ist es sogar so,dass "minimale" kodierungen nicht gelöst werden können.
hier geht es also schon lang nicht mehr darum,die dateien kleiner zu machen,sondern wirklich um das problem, welches ich in meinem ausgangspost geschildert habe.
wenn du dich wirklich dafür interessierst,dann gebe ich dir gern die restlichen materialien. immerhin sind sudokus ein begehrtes thema in der informatik
momentan herrscht bei mir leider nach wie vor extremer zeitdruck.heute abend sind die programme einzureichen und ich würde gern an den offensichtlichen ansatzpunkten noch etwas zeit sparen.
Wenn ich das richtig aus deinem Beispiel lese, benötigst du lediglich die Ziffern 0 bis 9, ein Leerzeichen und einen Zeilenumbruch. Das sind also insgesamt nur 12 Zeichen. So benötigt man rein theoretisch nur rund 45% des bisher angelegten Speicherplatzes. Wenn die 0 am Ende jeder Zeile höchstens nur einen Wert zwischen 0 und 4 inklusive darstellt und diese Zahl wirklich nur am Ende einer Zeile auftritt, können wir uns sogar den Zeilenumbruch sparen. Dann gibt es nämlich genau 16 verschiedene Zeichen und die passen in 4 Bits. So oder so kann man den Speicherverbrauch um mindestens 50% reduzieren. Grundlage für diese Überlegungen ist gepacktes(!) BCD: http://de.wikipedia.org/wiki/Binary_Coded_Decimal
Code:
// 8-Bit-breites Zeichen x mit RandomAccessFile raf an einer
// beliebigen Position i aus der Datei lesen:
raf.seek(i);
x = raf.read();
// 8-Bit-breites Zeichen x mit RandomAccessFile raf an einer
// beliebigen Position i in die Datei schreiben:
raf.seek(i);
raf.write(x);
// 4-Bit-breites Zeichen x mit RandomAccessFile raf an einer
// beliebigen Position i aus der Datei lesen:
raf.seek(i>>1);
int temp = raf.read();
x = ((i & 1) == 0) ? (temp>>>4) : (temp & 0x0F);
// 4-Bit-breites Zeichen x mit RandomAccessFile raf an einer
// beliebigen Position i in die Datei schreiben:
raf.seek(i>>1);
int temp = raf.read();
raf.seek(i>>1);
raf.write(((i & 1) == 0) ? (temp & 0x0F | x<<4) : (temp & 0xF0 | x));
Natürlich muss man nicht jedes mal seek(long) aufrufen usw., es gilt, alles zu nutzen, was an Informationen im Hauptspeicher bereits vorhanden ist. Deswegen sollten ja auch Puffer zum Einsatz kommen. Lediglich die Leserichtung ist etwas sonderbar.
Die Verkleinerung der Datei könnte einen erheblichen Geschwindigkeitszuwachs bedeuten, da Festplatten ja bekanntlich sehr langsam sind.
Ein Index scheint sich bei diesen kurzen Zeilen wohl nicht zu lohnen.
Ansonsten ist nach wie vor mein Vorschlag: Benutze einen Puffer (siehe read(byte[], int, int)), steuere mit seek(long) stückchenweise (so groß, wie der Puffer eben ist) den Zeiger rückwärts durch die Datei, fülle den Puffer und werte die Daten aus. Dann brauchst du mit setLength(long) nur noch den Rest abzuschneiden und schon bist du fertig.
Ark
EDIT:
Code:
import java.io.*;
public final class BackwardsFileInput{
private File in;
private int bufsize;
private byte[] buf;
private int left;
private long pointer;
private RandomAccessFile raf;
public BackwardsFileInput(File in,int bufsize){
this.in=in;
this.bufsize=bufsize;
buf=new byte[bufsize];
raf=new RandomAccessFile(in,"r");
raf.seek(raf.length()-raf.length()%bufsize);
left=raf.read(buf,0,bufsize);
}
public int read(){
if(left<=0){
pointer-=bufsize;
if(pointer<0) return -1;
raf.seek(pointer);
left=raf.read(buf,0,bufsize);
}
return buf[--left];
}
public long getPointer(){
return pointer+left;
}
}
Ich habe keine Ahnung, ob das funktioniert. Gib im Konstruktor für in die Datei und bufsize eine anständige Größe (z. B. 8192) an. Mit read() sollte dann ein Wert wie in java.io.InputStream zurückkommen, allerdings eben die Datei rückwärts und nicht vorwärts gelesen; bei -1 ist man dann an den Anfang der Datei gestoßen. Dann zählst du einfach alle \n-Vorkommen und lässt dir vorher (oder nachher um 1 verschoben) mit getPointer() sagen, wo dieses \n auftrat. Damit hast du dann die Ziellänge der Datei und kannst mit setLength(long) einfach den Rest abschneiden.
Reicht das?
(Immer diese Möchtegern-Informatiker-Studenten … von nix 'ne Ahnung, wenn's ums Praktische geht … :roll: … Das ist nur gerade mein Eindruck.)
Ark
EDIT: Eine Kleinigkeit habe ich noch am Code geändert.
weiss aber nicht,was das mit dem möchtegerninformatikstudenten soll?! wie ich oben schon geschrieben habe,fehlt mir einfach die zeit, um mich damit auseinanderzusetzen. mehr nicht.
ich weiss ja nicht,ob du ahnung von einem informatikstudium hast. da geht es aber bei weitem um MEHR, als ein bisschen java oder C zu können. also spar dir bitte deine mutmaßungen.
ich weiss ja nicht,ob du ahnung von einem informatikstudium hast. da geht es aber bei weitem um MEHR, als ein bisschen java oder C zu können. also spar dir bitte deine mutmaßungen.
.
Nein, hat er nicht. Er denkt, mit seinem einstudierten, geschwollenem Gerede, nimmt ihn jemand ernst. Lass dir deshalb keine grauen Haare wachsen. :wink:
ich weiss ja nicht,ob du ahnung von einem informatikstudium hast. da geht es aber bei weitem um MEHR, als ein bisschen java oder C zu können. also spar dir bitte deine mutmaßungen.
.
Nein, hat er nicht. Er denkt, mit seinem einstudierten, geschwollenem Gerede, nimmt ihn jemand ernst. Lass dir deshalb keine grauen Haare wachsen. :wink:
ich hab auch das mit nem kleinen trick gelöst
einfach von anfang an eine zeile am dateianfang reservieren
und diese dann immer mit random access file beschreiben,bzw. das geschriebene wieder durch leerzeichen ersetzen
genau so ist das. eine fixe länge.
ist mir auch erst nach ein paar mal überlegen eingefallen,dass man da ja garnicht viel traha machen muss,da die zeile immer gleich lang ist