Olvasgatom a java fájlkezeléséről szóló infókat. Eddig ami lejött: vannak szöveges fájlok, amikben szöveg van és vannak bináris fájlok, amikben számok (durván). Olyan nincs, hogy egy fájlban egyszerre szöveg és szám? Bár gondolom, ezt valahogy bináris formátumban kellene elkészíteni.
- 5008 megtekintés
Hozzászólások
Ennek a kérdésnek nem sok köze van a java-hoz....
- A hozzászóláshoz be kell jelentkezni
Konzervatív embereknek: s/fájl/file/g, s/bájt/byte/g
Valójában fájlból csak egyféle van: bájtsorozat.
Hogy ezt a bájtsorozatot esetleg (valamilyen kódolás szerinti, pl. UTF-8) "betűsorozatnak" (=szöveges fájl) vagy bináris értékek sorozatának tekinted-e, az már teljesen rajtad múlik. Ahogyan azt a kollégák pontosan leírták, ugyanazt a dolgot, pl. az ASCII 'A' betűt tekintheted 65-nek is. És mivel a fájlok nem típusosak, sosem lehet tudni, hogy az író mit is akart mondani.
Fuszenecker_Róbert
- A hozzászóláshoz be kell jelentkezni
"betűsorozat": betű, számjegyek, írásjelek, soremelés karakter(ek), mindenféle hieroglifák...
Fuszenecker_Róbert
- A hozzászóláshoz be kell jelentkezni
Az OK, hogy egy fájlban technikailag mi van. A Java viszont attól függően, hogy mit akarok kiolvasni, kétféle lehetőséget kínál fel - vagy bináris halmazként, vagy karakterhalmazként tekinti azt. Azóta viszont megkaptam a választ a problémámra.
--
Fight / For The Freedom / Fighting With Steel
- A hozzászóláshoz be kell jelentkezni
Egyetertek az elottem szoloval, annyit tennek hozza, hogy jo otlet lenne masik java konyvet olvasgatni akkor.
- A hozzászóláshoz be kell jelentkezni
Ok, majd keresek, hátha van.
--
Fight / For The Freedom / Fighting With Steel
- A hozzászóláshoz be kell jelentkezni
Kezdésnek ajánlom: :)
http://docs.oracle.com/javase/tutorial/essential/io/
- A hozzászóláshoz be kell jelentkezni
Na, ezt köszönöm!
--
Fight / For The Freedom / Fighting With Steel
- A hozzászóláshoz be kell jelentkezni
Java-ra vonatkozóan: két féle blokkoló I/O-t különít el: a byte alapút (ez a InputStream/OutputStream család) és a karakter alapút (ezek a Reader-ek és Writer-ek). A két library (időben először voltak a Stream-ek és talán 1.1-től vannak Writerek, valaki majd kijavít) viszonylag szépen ki vannak találva és jól meg vannak szerkesztve, a Reader/Writer családra konvertálhatók a Stream-ek (InputStreamReader, OutputStreamWriter).
Ami az igazi különbség a kettő között (és ez szépen látszik az ISR és OSW konstruktoraiból), hogy a Reader/Writer család egy adott karakterkódolás szerint értelmezi a bájthalmot, ha nem adsz meg mást, akkor az OS/locale-től függő karakterkódolással - rosszul.
Ez már mondjuk nem tartozik a kérdéshez, de ne magadtól kelljen rájönnöd: az egész API a decorator mintára épül, a néhány "végső" Stream/Reader/Writer (fájl, socket, memória, standard cuccok) köré tudsz kiegészítőket pakolni, pl. buffered olvasás (BufferedInputStream, BufferedReader, ...)
Szerk.: Ja, igen, és hogy a kérdésedet meg is válaszoljuk. Bőven tudsz olyat csinálni, hogy mondjuk 10 bináris bájt után 6 UTF-8 karakter (így ugye egy rekord min. 16 max 34 byte), felolvasod az InputStream-ről a 10 byte-ot, utána ugyanarra a FileInputStream-re aggatott Reader-ből a 6 karaktert.
BlackY
--
"en is amikor bejovok dolgozni, nem egy pc-t [..] kapcsolok be, hanem a mainframe-et..." (sj)
- A hozzászóláshoz be kell jelentkezni
Ah, na ez még jobb. Kezd már körvonalazódni a dolog (meg ami miatt kérdeztem is).
--
Fight / For The Freedom / Fighting With Steel
- A hozzászóláshoz be kell jelentkezni
És egy példakód is:
import java.io.*; /* File[In|Out]putStream, OutputStreamWriter, InputStreamReader */
import java.nio.charset.Charset;
import java.util.*; /* Arrays */
class Test {
public static void main(String args[]) throws Exception {
/* Kiírás */
FileOutputStream fileOut = new FileOutputStream("test.dat");
Writer writer = new OutputStreamWriter(fileOut, Charset.forName("UTF-8"));
fileOut.write(new byte[] { 1, 2, 3, 4 });
writer.write("Hello!", 0, "Hello!".length());
writer.close();
fileOut.close();
/* Beolvasás */
byte array[] = new byte[4];
char msg[] = new char[6];
FileInputStream fileIn = new FileInputStream("test.dat");
Reader reader = new InputStreamReader(fileIn, Charset.forName("UTF-8"));
fileIn.read(array); /* Remélhetőleg 4 byte-ot be is olvasunk, illik ellenőrizni */
System.out.println(Arrays.toString(array));
reader.read(msg, 0, 6);
reader.close();
fileIn.close();
System.out.println(new String(msg));
}
}
(Persze az összes inicializálás szebb lenne try-with-resource blokkal, most ennyire futotta :))
BlackY
--
"en is amikor bejovok dolgozni, nem egy pc-t [..] kapcsolok be, hanem a mainframe-et..." (sj)
- A hozzászóláshoz be kell jelentkezni
Aham. És ha sorrendben egy karakter, egy szám és két bit van, akkor
int number;
char character;
boolean bool[]=new boolean[2];
reader.read(character);
fileIn.read(number);
fileIn.read(bool);
(Most a paraméterlistától tekintsünk el...)
--
Fight / For The Freedom / Fighting With Steel
- A hozzászóláshoz be kell jelentkezni
A primitív típusok közül csak byte-ot és char-t tudsz olvasni, a többinél játszanod kell (pl. int-nél beolvasol négy bájtot, és shifteled aztán or-ozod őket, boolean-nél valami bájtot meg kell feleltetned a két értéken). Itt már érdemes lehet a képbe hozni a NIO-t (Java 1.5-ös fejlemény), egész pontosan a ByteBuffer-t. Ezzel egyszerűen meg tudod csinálni a konverziót byte tömbbé, azt pedig már tudod kezelni a Stream-ben (Igazából az egész NIO egy nagyon erős library, de amíg nincs rá kifejezetten szükséges [pl. aszinkron I/O-t akarsz csinálni Java-ból], szerintem kerüld el :) ):
ByteBuffer buffer = ByteBuffer.allocate(6); /* 4 byte az int-nek, egy-egy bool-nak */
buffer.putInt(123456);
buffer.put(bool[0] ? (byte) 1 : (byte) 0); /* Nincs putBool */
buffer.put(bool[1] ? (byte) 1 : (byte) 0);
fileOut.write(buffer.array());
És a visszaolvasás:
byte data[] = new byte[6];
fileIn.read(data);
ByteBuffer buffer = ByteBuffer.wrap(data);
System.out.println(buffer.getInt());
System.out.println(buffer.get() == 0 ? true : false);
System.out.println(buffer.get() == 1 ? true : false);
BlackY
--
"en is amikor bejovok dolgozni, nem egy pc-t [..] kapcsolok be, hanem a mainframe-et..." (sj)
- A hozzászóláshoz be kell jelentkezni
Aha, ez már jobban hangzik. Bár szerintem elég egyetlen byte is a tároláshoz, mivelhogy két bájttal a 0-3 intervallumot fedjük le.
--
Fight / For The Freedom / Fighting With Steel
- A hozzászóláshoz be kell jelentkezni
Elégnek elég (akár 8 booleannak is vagy 2 null-ható Boolean-nek), csak az ilyen szintű bittologatás nekem már nagyon C :)
BlackY
--
"en is amikor bejovok dolgozni, nem egy pc-t [..] kapcsolok be, hanem a mainframe-et..." (sj)
- A hozzászóláshoz be kell jelentkezni
Nem feltétlenül kell bittologatás, csak nekem sajnos az asztali gépben még mindig 40G HDD van, úgyhogy ott spórolok, ahol tudok. :)
--
Fight / For The Freedom / Fighting With Steel
- A hozzászóláshoz be kell jelentkezni
commons-io FTW!
http://commons.apache.org/proper/commons-io/apidocs/org/apache/commons/…
http://commons.apache.org/proper/commons-io/apidocs/org/apache/commons/…
___________________________
http://lorem.hu
Az emberi tudás mindenkié!
- A hozzászóláshoz be kell jelentkezni