Archivo Java y ByteArray o InputStream
Pregunta
Quiero utilizar JFugue para jugar un poco de música MIDI en un applet. Hay una clase para el patrón de MIDI - Pattern
- y el único método para cargar el patrón es de un archivo. Ahora, yo no sé cómo applets de archivos de carga y lo que no, pero yo estoy usando un marco (PulpCore) que hace que los activos de carga una tarea sencilla. Si tengo que agarrar un activo de un catálogo postal, puedo utilizar la clase Assets
que proporciona métodos y get()
getAsStream()
. get()
devuelve el activo dado como ByteArray
, el otro como un InputStream
.
Necesito JFugue para cargar el patrón de cualquiera ByteArray
o InputStream
.
En pseudo-código, me gustaría hacer esto:
Pattern.load(new File(Assets.get("mymidifile.midi")));
Sin embargo, no hay ningún constructor del archivo que tomaría un ByteArray. Sugerencias, por favor?
Solución
Es cierto que JFugue no permite a cualquier cosa, pero la carga de un archivo, lo cual es una lástima, porque impide nada de usar cualquier otro tipo de corriente:
public static final String TITLE = "Title";
public static Pattern loadPattern(File file) throws IOException {
InputStream in = new FileInputStream(file);
try {
return loadPattern(in);
} finally {
in.close();
}
}
public static Pattern loadPattern(URL url) throws IOException {
InputStream in = url.openStream();
try {
return loadPattern(in);
} finally {
in.close();
}
}
public static Pattern loadPattern(InputStream in) throws IOException {
return loadPattern(new InputStreamReader(in, "UTF-8")); // or ISO-8859-1 ?
}
public static Pattern loadPattern(Reader reader) throws IOException {
if (reader instanceof BufferedReader) {
return loadPattern(reader);
} else {
return loadPattern(new BufferedReader(reader));
}
}
public static Pattern loadPattern(BufferedReader bread) throws IOException {
StringBuffer buffy = new StringBuffer();
Pattern pattern = new Pattern();
while (bread.ready()) {
String s = bread.readLine();
if ((s != null) && (s.length() > 1)) {
if (s.charAt(0) != '#') {
buffy.append(" ");
buffy.append(s);
} else {
String key = s.substring(1, s.indexOf(':')).trim();
String value = s.substring(s.indexOf(':')+1, s.length()).trim();
if (key.equalsIgnoreCase(TITLE)) {
pattern.setTitle(value);
} else {
pattern.setProperty(key, value);
}
}
}
}
return pattern;
}
UPDATE (para loadMidi)
public static Pattern loadMidi(InputStream in) throws IOException, InvalidMidiDataException
{
MidiParser parser = new MidiParser();
MusicStringRenderer renderer = new MusicStringRenderer();
parser.addParserListener(renderer);
parser.parse(MidiSystem.getSequence(in));
Pattern pattern = new Pattern(renderer.getPattern().getMusicString());
return pattern;
}
public static Pattern loadMidi(URL url) throws IOException, InvalidMidiDataException
{
MidiParser parser = new MidiParser();
MusicStringRenderer renderer = new MusicStringRenderer();
parser.addParserListener(renderer);
parser.parse(MidiSystem.getSequence(url));
Pattern pattern = new Pattern(renderer.getPattern().getMusicString());
return pattern;
}
Otros consejos
Si no estoy equivocado, los archivos de patrones contienen texto sin formato. Cargar el archivo con getAsStream (), luego convertirlo en una cadena utilizando
BufferedReader br = new BufferedReader(new InputStreamReader(yourStream));
//...
String pattern = convertToString(br); // you should implement convertToString yourself. It's easy. Read the java.io APIs.
Donde yourStream es el InputStream devuelto por getAsStream (). A continuación, utilice el método add (String ... patrones) para cargar el patrón:
add(pattern);
Se puede utilizar este código (tomado de la aplicación del método Pattern.loadPattern()
):
InputStream is = ...; // Get a stream from the Asset object
// Prepare a pattern object
Pattern pattern = new Pattern();
// Now start reaing from the stream
StringBuffer buffy = new StringBuffer();
BufferedReader bread = new BufferedReader(new InputStreamReader(is));
while (bread.ready()) {
String s = bread.readLine();
if ((s != null) && (s.length() > 1)) {
if (s.charAt(0) != '#') {
buffy.append(" ");
buffy.append(s);
} else {
String key = s.substring(1, s.indexOf(':')).trim();
String value = s.substring(s.indexOf(':')+1, s.length()).trim();
if (key.equalsIgnoreCase(TITLE)) {
pattern.setTitle(value);
} else {
pattern.setProperty(key, value);
}
}
}
}
bread.close();
pattern.setMusicString(buffy.toString());
// Your pattern is now ready
Se podía leer la matriz de bytes y convertirlo en una cadena.
El problema será el InputStream. Hay una StringBufferInputStream, pero es utilizar para sustituirla por StringReader.
byte [] b = Assets.get();
InputStream is = new StringBufferInputStream(new String(b));
Pattern.load(is);
Usted no desea utilizar File
, que desea utilizar java.io.ByteArrayInputStream