|
Sistemas de Información
|
Java
|
Archivos |
|
Archivos
El uso de archivos en Java se simplifica mucho mediante el uso de bibliotecas que ofrecen métodos prefabricados y ya preparados para su uso, con nivel superior al de las primitivas disponibles en el propio lenguaje. Por esta razón se ha construido AuxText, una biblioteca de métodos adecuada para la creación de programas capaces de, entre otras cosas, importar y exportar archivos con formato de texto. AuxText
no hace uso de hilos (Thread
) pero este defecto se puede subsanar. La lista de métodos creados es la siguiente:
- public String readString(File f)
- public boolean writeString(String str, File f)
- public boolean writeList(String [] list, File f)
- public String[] readList(File f) {
- public boolean writeDelimitedTable(String[][] table, String delimiter, File f)
- public boolean writeColumnarTable(String[][] table, int[] lengths, File f)
- public boolean writeColumnarTable(String[][] table, int[] lengths)
- public String[][] readDelimitedTable(String delimiter, File f)
- public String[][] readColumnarTable(int[] field_length, File f)
Los nombres son razonablemente inteligibles; esta clase supondrá un gran ahorro de tiempo, como decimos, a la hora de importar o exportar información. La combinación de los métodos de esta clase con los expuestos en el apartado dedicado a Listas bastan para visualizar bases de datos con relativa facilidad, tras importar información de archivos de disco. Si se añade mysql
(Paquetes para Mac OS X, Linux, Mac OS X, Windows), se dispondrá de todo los necesario para generar un gestor de bases de datos razonablemente sofisticado y potente.
AuxText.java
package com.coti.tools;
/*
*@author coti
*@version 1.1 - not final (will it ever be?)
* This version is not static; it will take a Component through
* its constructor and all error dialogs shall belong to it.
* Thus we get centerede error dialogs.
*
*/
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.BufferedWriter;
import java.security.AccessController;
import java.util.StringTokenizer;
import java.util.Vector;
import java.awt.Component;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import java.io.*;
import java.nio.*;
import java.nio.channels.*;
public class AuxText {
Component owner;
public AuxText(Component o) {
owner = o;
}
/*
lineSeparator will adapt to whatever OS you are using.
In owner way we make sure that files we create will be
understood correctly by text editors that expect their
own kind of new line
*/
public String lineSeparator = System.getProperty("line.separator");
/*
int temp = new char[(int)f.length()];
try
{
br.read(temp,0,temp.length);
}
catch(Exception e)
{
JOptionPane.showMessageDialog( this,
e.toString(),
"Reading error",
JOptionPane.ERROR_MESSAGE);
}
*/
public String readString(File f)
{
if (null == f)
{
JOptionPane.showMessageDialog( owner,
"null File",
"Sorry, File needed",
JOptionPane.ERROR_MESSAGE);
return null;
}
FileInputStream fis = null;
InputStreamReader isr = null;
BufferedReader br = null;
int i = 0; /* Used as index into the list */
try
{
if (f.exists())
fis = new FileInputStream(f);
}
catch(Exception e)
{
JOptionPane.showMessageDialog( owner,
e.toString(),
"Error when opening " + f.getName() ,
JOptionPane.ERROR_MESSAGE);
return null;
}
isr = new InputStreamReader(fis);
br = new BufferedReader(isr);
/* Now we do the actual reading */
char[] temp = new char[(int)f.length()];
try
{
br.read(temp,0,temp.length);
}
catch(Exception e)
{
JOptionPane.showMessageDialog( owner,
e.toString(),
"Reading error",
JOptionPane.ERROR_MESSAGE);
}
try
{
br.close();
}
catch(Exception e)
{
JOptionPane.showMessageDialog( owner,
e.toString(),
"Error when closing " + f.getName(),
JOptionPane.ERROR_MESSAGE);
return null;
}
return new String(temp);
}
public boolean writeString(String str, File f)
{
if (null == str)
{
JOptionPane.showMessageDialog( owner,
"null list",
"Sorry, that list is empty",
JOptionPane.ERROR_MESSAGE);
return false;
}
if (null == f)
{
JOptionPane.showMessageDialog( owner,
"null File",
"Sorry, File needed",
JOptionPane.ERROR_MESSAGE);
return false;
}
FileOutputStream fos;
OutputStreamWriter osw;
BufferedWriter bw;
int i = 0; /* Used as index into the list */
/* We append info - no information is destroyed */
try
{
if (f.exists())
fos = new FileOutputStream(f.getName(), true);
else
fos = new FileOutputStream (f.getName());
}
catch(Exception e)
{
JOptionPane.showMessageDialog( owner,
e.toString(),
"Error when opening " + f.getName() + "(appending)",
JOptionPane.ERROR_MESSAGE);
return false;
}
osw = new OutputStreamWriter(fos);
bw = new BufferedWriter(osw);
/* Now we do the actual writing */
try
{
bw.write(str);
bw.write(lineSeparator);
}
catch(Exception e)
{
JOptionPane.showMessageDialog( owner,
e.toString(),
"Error when writing ",
JOptionPane.ERROR_MESSAGE);
return false;
}
try
{
bw.close();
}
catch(Exception e)
{
JOptionPane.showMessageDialog( owner,
e.toString(),
"Error when closing " + f.getName(),
JOptionPane.ERROR_MESSAGE);
return false;
}
return true;
}
public boolean writeList(String [] list, File f)
{
/*
We will return true if no exceptions take place.
Otherwise we will return false.
A more detailed behaviour would return an integer
constant, thus facilitating error checking.
*/
String name = null;
if (null == list)
{
JOptionPane.showMessageDialog( owner,
"null list",
"Sorry, that list is empty",
JOptionPane.ERROR_MESSAGE);
return false;
}
if (null == f)
{
JOptionPane.showMessageDialog( owner,
"null File",
"Sorry, File needed",
JOptionPane.ERROR_MESSAGE);
return false;
}
FileOutputStream fos;
OutputStreamWriter osw;
BufferedWriter bw;
int i = 0; /* Used as index into the list */
/* We append info - no information is destroyed */
try
{
if (f.exists())
fos = new FileOutputStream(f.getName(), true);
else
fos = new FileOutputStream (f.getName());
}
catch(Exception e)
{
JOptionPane.showMessageDialog( owner,
e.toString(),
"Error when opening " + f.getName() + "(appending)",
JOptionPane.ERROR_MESSAGE);
return false;
}
osw = new OutputStreamWriter(fos);
bw = new BufferedWriter(osw);
/* Now we do the actual writing */
try
{
for(i=0;i<list.length;i++)
{
if (null != list[i])
{
bw.write(list[i]);
bw.write(lineSeparator);
}
}
}
catch(Exception e)
{
JOptionPane.showMessageDialog( owner,
e.toString(),
"Error when writing line " +i+" : "+list[i],
JOptionPane.ERROR_MESSAGE);
return false;
}
try
{
bw.close();
}
catch(Exception e)
{
JOptionPane.showMessageDialog( owner,
e.toString(),
"Error when closing " + f.getName(),
JOptionPane.ERROR_MESSAGE);
return false;
}
return true;
}
public String[] readList(File f) {
String[] templist = null;
String temp = null;
Vector v = new Vector();
FileInputStream fir;
InputStreamReader ir;
BufferedReader br;
if (!f.canRead())
{
JOptionPane.showMessageDialog( owner,
"Cannot read",
"Sorry, can't read file " + f.getName(),
JOptionPane.ERROR_MESSAGE);
return null;
}
try
{
fir = new FileInputStream(f);
}
catch(Exception fnf)
{
JOptionPane.showMessageDialog( owner,
"File not found",
"Sorry, file " + f.getName() + "was not found",
JOptionPane.ERROR_MESSAGE);
return null;
}
ir = new InputStreamReader(fir);
br = new BufferedReader(ir);
do
{
try
{
temp = br.readLine();
}
catch(Exception e)
{
JOptionPane.showMessageDialog( owner,
e.toString(),
"Error while reading - an empty line has been added",
JOptionPane.ERROR_MESSAGE);
temp = "";
}
if (temp!=null)
v.addElement(temp);
}
while(temp!=null);
templist = new String[v.size()];
v.toArray(templist);
try
{
br.close();
}
catch(Exception e)
{
JOptionPane.showMessageDialog( owner,
e.toString(),
"Error when closing after reading file " + f.getName(),
JOptionPane.ERROR_MESSAGE);
}
//System.out.println("Returning " + templist.length + " lines.");
return templist;
}
public boolean writeDelimitedTable(String[][] table, String delimiter, File f)
{
/*
We will return true if no exceptions take place.
Otherwise we will return false.
A more detailed behaviour would return an integer
constant, thus facilitating error checking.
*/
String name = null;
if (null == table)
{
JOptionPane.showMessageDialog( owner,
"null table",
"Sorry, that table is empty",
JOptionPane.ERROR_MESSAGE);
return false;
}
if (null == f)
{
JOptionPane.showMessageDialog( owner,
"null file",
"Sorry, no file passed for writing into",
JOptionPane.ERROR_MESSAGE);
return false;
}
FileOutputStream fos;
OutputStreamWriter osw;
BufferedWriter bw;
int i = 0,j = 0; /* Used as indices into the table */
/* We append info - no information is destroyed */
try
{
if (f.exists())
fos = new FileOutputStream(f.getName(), true);
else
fos = new FileOutputStream (f.getName());
}
catch(Exception e)
{
JOptionPane.showMessageDialog( owner,
e.toString(),
"Error when opening " + f.getName() + "for appending",
JOptionPane.ERROR_MESSAGE);
return false;
}
osw = new OutputStreamWriter(fos);
bw = new BufferedWriter(osw);
/* Now we do the actual writing */
int number_of_rows = table.length;
int number_of_columns = table[0].length;
try
{
for(i=0;i<number_of_rows;i++)
{
for(j=0; j<number_of_columns-1;j++)
{
bw.write(table[i][j]);
bw.write(delimiter);
}
bw.write(table[i][number_of_columns-1]);
bw.write(lineSeparator);
}
}
catch(Exception e)
{
JOptionPane.showMessageDialog( owner,
e.toString(),
"Error when writing element " + table[i][j],
JOptionPane.ERROR_MESSAGE);
return false;
}
try
{
bw.close();
}
catch(Exception e)
{
JOptionPane.showMessageDialog( owner,
e.toString(),
"Error when closing " + f.getName(),
JOptionPane.ERROR_MESSAGE);
return false;
}
return true;
}
public boolean writeColumnarTable(String[][] table, int[] lengths, File f)
{
String name = null;
if (null == table)
{
JOptionPane.showMessageDialog( owner,
"null table",
"Sorry, that table is empty",
JOptionPane.ERROR_MESSAGE);
return false;
}
if (null == f)
{
JOptionPane.showMessageDialog( owner,
"null file",
"Sorry, no file passed for writing into",
JOptionPane.ERROR_MESSAGE);
return false;
}
if (table[0].length != lengths.length)
{
JOptionPane.showMessageDialog( owner,
"not enough column lenghts",
"Sorry, the number of columns is not the same as the number of column lengths",
JOptionPane.ERROR_MESSAGE);
return false;
}
FileOutputStream fos;
OutputStreamWriter osw;
BufferedWriter bw;
int i = 0,j = 0; /* Used as indices into the table */
/* We append info - no information is destroyed */
try
{
if (f.exists())
fos = new FileOutputStream(f.getName(), true);
else
fos = new FileOutputStream (f.getName());
}
catch(Exception e)
{
JOptionPane.showMessageDialog( owner,
e.toString(),
"Error when opening " + f.getName() + "for appending",
JOptionPane.ERROR_MESSAGE);
return false;
}
osw = new OutputStreamWriter(fos);
bw = new BufferedWriter(osw);
/* Now we do the actual writing */
int number_of_rows = table.length;
int number_of_columns = table[0].length;
int wanted_length = 0;
StringBuffer temp = new StringBuffer();
try
{
for(i=0;i<number_of_rows;i++)
{
for(j=0; j<number_of_columns;j++)
{
temp.append(table[i][j]);
wanted_length=lengths[i];
if (temp.length() < wanted_length)
while (temp.length() != wanted_length)
temp.append(" ");
bw.write(temp.substring(0,wanted_length));
temp.delete(0,temp.length());
}
bw.write(lineSeparator);
}
}
catch(Exception e)
{
JOptionPane.showMessageDialog( owner,
e.toString(),
"Error when writing element " + table[i][j],
JOptionPane.ERROR_MESSAGE);
return false;
}
try
{
bw.close();
}
catch(Exception e)
{
JOptionPane.showMessageDialog( owner,
e.toString(),
"Error when closing " + f.getName(),
JOptionPane.ERROR_MESSAGE);
return false;
}
return true;
}
public boolean writeColumnarTable(String[][] table, int[] lengths)
{
String name = null;
if (null == table)
{
System.err.println("Sorry, that table is empty");
return false;
}
if (table[0].length != lengths.length)
{
JOptionPane.showMessageDialog( owner,
"not enough column lengths",
"Sorry, the number of columns is not the same as the number of column lengths",
JOptionPane.ERROR_MESSAGE);
return false;
}
int i = 0,j = 0; /* Used as indices into the table */
/* Now we do the actual writing */
int number_of_rows = table.length;
int number_of_columns = table[0].length;
int wanted_length = 0;
StringBuffer temp = new StringBuffer();
try
{
for(i=0;i<number_of_rows;i++)
{
for(j=0; j<number_of_columns;j++)
{
temp.append(table[i][j]);
wanted_length=lengths[j];
if (temp.length() < wanted_length)
while (temp.length() != wanted_length)
temp.append(" ");
System.out.print(temp.substring(0,wanted_length));
temp.delete(0,temp.length());
}
System.out.println("");
}
}
catch(Exception e)
{
JOptionPane.showMessageDialog( owner,
e.toString(),
"Error when writing element ["+i+"]["+j+"] = " + table[i][j],
JOptionPane.ERROR_MESSAGE);
return false;
}
return true;
}
public String[][] readDelimitedTable(String delimiter, File f)
{
String[] temp = null;
String[][] table = null;
StringTokenizer st = null;
int number_of_rows = 0, number_of_columns = 0;
int number_of_fields = 0;
temp = readList(f); /* We make use of our own methods */
if (null == temp)
{
JOptionPane.showMessageDialog( owner,
"could not read file",
"Error - readDelimitedTable did not get a valid file.",
JOptionPane.ERROR_MESSAGE);
return null;
}
number_of_rows = temp.length; /* As many rows as lines we have read */
if (0 == number_of_rows)
{
JOptionPane.showMessageDialog( owner,
"table is empty",
"number of rows equals 0.",
JOptionPane.ERROR_MESSAGE);
return null;
}
st = new StringTokenizer(temp[0], delimiter);/* Delimiters are not tokens */
number_of_columns = st.countTokens(); /* This is the number of fields */
table = new String[number_of_rows][number_of_columns];
for(int i=0;i<temp.length;i++)
{
st = new StringTokenizer(temp[i], delimiter);
number_of_fields = st.countTokens();
if (number_of_fields == number_of_columns)
{
for(int j=0;j<number_of_columns;j++)
table[i][j]=st.nextToken();
}
else
{
if (number_of_fields < number_of_columns)
{
for(int j=0;j<number_of_fields;j++)
table[i][j]=st.nextToken();
for(int j=number_of_fields;j<number_of_columns;j++)
table[i][j] = "";
JOptionPane.showMessageDialog( owner,
"line too short",
"Line "+i+" too short. Blank fields added",
JOptionPane.ERROR_MESSAGE);
}
else /* number_of_fields > number_of_columns */
{
for(int j=0;j<number_of_columns;j++)
table[i][j]=st.nextToken();
JOptionPane.showMessageDialog( owner,
"line too long",
"Line "+i+" was too long. Final fields omitted.",
JOptionPane.ERROR_MESSAGE);
}
}
}
return table;
}
public String[][] readColumnarTable(int[] field_length, File f)
{
String temp = null;
String[] list = null;
String[][] table = null;
StringTokenizer st = null;
int number_of_rows = 0, number_of_columns = 0;
int number_of_fields = 0;
list = readList(f);
if (null == list)
{
JOptionPane.showMessageDialog( owner,
"could not read from file",
"Error - readColumnarTable did not get a valid file.",
JOptionPane.ERROR_MESSAGE);
return null;
}
number_of_rows = list.length; /* As many rows as lines we have read */
if (0 == number_of_rows)
{
JOptionPane.showMessageDialog( owner,
"number of rows equals 0",
"Sorry, owner table is empty",
JOptionPane.ERROR_MESSAGE);
return null;
}
number_of_columns = field_length.length; /* This is the number of fields */
if (0 == number_of_columns)
{
JOptionPane.showMessageDialog( owner,
"no field widths given",
"Sorry, no field lengths found when reading columnar table",
JOptionPane.ERROR_MESSAGE);
return null;
}
table = new String[number_of_rows][number_of_columns];
int field_start = 0;
for(int i=0;i<list.length;i++)
{
field_start = 0;
temp = list[i];
for(int j=0;j<number_of_columns;j++)
{
try
{
table[i][j]=temp.substring(field_start,field_start+field_length[j]);
field_start += field_length[j];
}
catch(Exception e)
{
JOptionPane.showMessageDialog( owner,
e.toString(),
"Line "+i+" is too short for field " +j+". Field left empty.",
JOptionPane.ERROR_MESSAGE);
table[i][j]="";
}
}
}
return table;
}
}
Comentarios.- Conviene estudiar los métodos de esta clase con el doble objetivo de comprender su funcionamiento y apreciar sus limitaciones. Esto dará lugar, normalmente, a la creación de otros métodos que mejoren las capacidades de los existentes o su rendimiento. No se ha hecho esfuerzo alguno por optimizar estos métodos; se busca más una comprensión rápida que una ejecución mejorada. Será muy interesante comprobar los rendimientos reales de las mejoras propuestas; los métodos mejorados podrían, incluso, ser adoptados y aparecer en estas páginas, indicándose el autor de la mejora.