# Speicherplatz eines Strings?



## Verjigorm (2. Jan 2008)

Hallo, ich baue grad nen sehr grossen String zusammen (bis zu 500mb Dateigröße)
Das ganze steckt in einem Stringbuffer und ich würde gerne vorher wissen, wieviel Speicherplatz mein String im Filesystem verbrauchen wird (grobe Abschätzung reicht)

nun habe ich keine geeignete Methode von Stringbuffer selbst gefunden
und mir deswegen was aus logischen Zusammenhängen zusammengezimmert:


```
System.out.println(buffer.length()*16/8/1000/1000);
```

Idee war:
Anzahl der Zeichen im StringBuffer * CharGröße(16bit) / Größe auf Megabyte bezogen

Als Ausgabe krieg ich bei den ersten Tests ~30mb
wenn ich den String dann in ne Datei schreibe, ist die Datei aber nur 5,xx mb groß

Und nun die Frage, wie gehts besser bzw. richtig? 

gruß Verjigorm


----------



## tuxedo (2. Jan 2008)

Ähm ...



> length()
> Returns the length (character count).



Gilt denn "character count" == Anzahl Zeichen mit je 16 Bit (unicode)??
Wenn deine Datei im Unicode-Format gespeichert ist, dann kannst du denke ich so rechnen. Ansonsten würde ich sagen:

buffer.length() entspricht der Anzahl zeichen im StringBuffer. Und das würde bei einer nicht-Unicode-Speicherung doch der Anzajl Bytes des File entsprechen?

MegaByte wird mit 1024 und nicht mit 1000 gerechnet (wenn mich die ganze "neue" MiB und KiB Sache jetzt nicht allzusehr verwirrt hat).
Also sollte deine Rechnung doch so aussehen:


```
System.out.println("Länge in MB: "+(double)(buffer.length()/1024/1024));
```

Probiers und gibt bescheid was raus kommt.

- Alex


----------



## Verjigorm (2. Jan 2008)

Nun kommt Länge in MB: 15.0
wobei ich denke da fehlt noch /8, weil wir sind ja im Bitbereich und müssen erstmal auf Byte oder seh ich das falsch?

1000 oder 1024 fand ich jetzt nimmer so entscheidend, hast natürlich recht 

Windoof zeigt mir für die Datei jedoch 5,72MB an


edit: es kommt ja nicht auf die Kommastellen drauf an, deswegen hab ich den Wert auch nicht in double gecastet
grobe Richtigkeit vorm Komma (bei MB) würd reichen


----------



## tuxedo (2. Jan 2008)

Also laut API-Dok sind wir nicht im Bit-Bereich, sondern im Byte-Bereich. Geht eigentlich nur drum, ob Unicode (16 bit für ein Zeichen) oder nicht-unicode (8bit für ein Zeichen). "Character" wird in Java als UniCode behandelt und mit 16 Bit belegt. Wenn deine Datei auf kein UniCode hat, dann sollte sie 8 Bit/Zeichen haben. Und 8Bit = 1 Byte. 

Was spuckt denn ein einfaches "buffer.length()" aus? Ohne Berechung?

- Alex


----------



## Verjigorm (2. Jan 2008)

16.000.000 (generierte Länge zu Testzwecken)
hab auchmal andere Größen versucht, aber selbes Spiel


----------



## tuxedo (2. Jan 2008)

Was heisst generierte Länge? 16Mio darf da nicht stehen wenn deine File 5,27MB groß ist.

- Alex


----------



## Verjigorm (2. Jan 2008)

hm ich hab das mal nen bissl einheitlicher gemacht:

1Mio mal "a" in die datei geschrieben -> 1Mio Bytes -> ~1MB
lese ich nun die Datei in einen StringBuffer aus und mache
buffer.length(), dann kommt da 2Mio raus ... wieso denn das?


----------



## SlaterB (2. Jan 2008)

Java hat intern einen anderen Zeichensatz (Unicode, 2 Byte) als in der Datei (Betriebssystemabhängig, anscheinend nur 1 Byte)

z.B.
 CP 1252 
Zeichensatz "Codepage 1252" (256 Zeichen, auch WinLatin 1 genannt); 
Standardzeichensatz unter Windows, beinhaltet die ersten 128 Zeichen vom ASCII-Zeichensatz 

http://wap-pool.math.uni-bayreuth.de/prog/java_native2ascii.html


----------



## tuxedo (2. Jan 2008)

Keine Ahnung was du machst, aber das hier funzt 1a (abgesehen davon dass ich, faul wie ich eben auf die schnelle war, immer wieder ein "new String()" mache). Der SB ist exakt so groß wie die File selbst. Windows sagt mir, die File wäre 

6,02 MB (6.317.843 bytes)

groß. Und Das Programm gibt aus:

In File: 6317843
In StringBuffer: 6317843


```
public static void main(String[] args) throws IOException {
		StringBuffer sb = new StringBuffer(1);
		
		FileInputStream fis = new FileInputStream(new File("c:/test.txt"));
		
		
		
		byte[] b = new byte[512];
		
		int bytesCurrentlyRead = 0;
		int bytesReadTotally = 0;
		
		while (bytesCurrentlyRead>=0){
			
			bytesCurrentlyRead = fis.read(b);
			
			if (bytesCurrentlyRead>=0) {
				bytesReadTotally+=bytesCurrentlyRead;
				sb.append(new String(b,0,bytesCurrentlyRead));
			}
			
			
		}

		System.out.println("In File: "+bytesReadTotally);
		System.out.println("In StringBuffer: "+sb.length());
```

- Alex


----------



## ARadauer (2. Jan 2008)

zeig mal wie du ließt und schreibst

hat wahrscheinlich mit der encodierung zu tun...


----------



## The_S (3. Jan 2008)

alex0801 hat gesagt.:
			
		

> MegaByte wird mit 1024 und nicht mit 1000 gerechnet (wenn mich die ganze "neue" MiB und KiB Sache jetzt nicht allzusehr verwirrt hat).



Ne, genau andersrum  . Mega, Kilo, Giga, ... gibt es ja nicht nur in der Informatik, sondern sind allgemeingültige Bezeichnungen, die auf 10er Basis beruhen => wenn du in der Metzgerei n Kilo Wurst bestellst, bekommst du ja auch 1000 Gramm und nicht 1024. Diese "neuen" Bezeichnungen stehen für "Binär", also basierend auf 2er-Basis. Damit bist du dann wieder bei den 1024 (2^10).


----------



## tuxedo (3. Jan 2008)

Ähm, das war ja die "verwirrung" in den letzten Jahren. MB, KB, GB wurden doch "fälschlicherweise" mit 1024 gerechnet. Und da es manche dann doch wieder "genau" genommen haben, haben sie mit 1000 gerechnet. Das hat dazu geführt dass Festplattenkapazitäten immer mal wieder anders waren. Je nachdem wie der Hersteller gerechnet hat. Und erst wegen diesem Irrtum wurden die Binäreinheiten eingeführt, damit Kilo endlich wieder 1000 und nicht 1024 ist....


----------



## The_S (3. Jan 2008)

äh ... ich glaub ich hab mich bei deiner ersten Aussage verlesen ... dachte du hast gemeint, dass Megabyte (ohne i  ) 1024 sind, und die mit i 1000


----------

