001: // serverFileUtils.java
002: // -------------------------------------------
003: // (C) by Michael Peter Christen; mc@anomic.de
004: // first published on http://www.anomic.de
005: // Frankfurt, Germany, 2004
006: // last major change: 05.08.2004
007: //
008: // This program is free software; you can redistribute it and/or modify
009: // it under the terms of the GNU General Public License as published by
010: // the Free Software Foundation; either version 2 of the License, or
011: // (at your option) any later version.
012: //
013: // This program is distributed in the hope that it will be useful,
014: // but WITHOUT ANY WARRANTY; without even the implied warranty of
015: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
016: // GNU General Public License for more details.
017: //
018: // You should have received a copy of the GNU General Public License
019: // along with this program; if not, write to the Free Software
020: // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
021: //
022: // Using this software in any meaning (reading, learning, copying, compiling,
023: // running) means that you agree that the Author(s) is (are) not responsible
024: // for cost, loss of data or any harm that may be caused directly or indirectly
025: // by usage of this softare or this documentation. The usage of this software
026: // is on your own risk. The installation and usage (starting/running) of this
027: // software may allow other people or application to access your computer and
028: // any attached devices and is highly dependent on the configuration of the
029: // software which must be done by the user of the software; the author(s) is
030: // (are) also not responsible for proper configuration and usage of the
031: // software, even if provoked by documentation provided together with
032: // the software.
033: //
034: // Any changes to this file according to the GPL as documented in the file
035: // gpl.txt aside this file in the shipment you received can be done to the
036: // lines that follows this copyright notice here, but changes must not be
037: // done inside the copyright notive above. A re-distribution must contain
038: // the intact and unchanged copyright notice.
039: // Contributions and changes to the program code must be marked as such.
040:
041: package de.anomic.server;
042:
043: import java.io.BufferedOutputStream;
044: import java.io.BufferedReader;
045: import java.io.ByteArrayInputStream;
046: import java.io.ByteArrayOutputStream;
047: import java.io.File;
048: import java.io.FileInputStream;
049: import java.io.FileOutputStream;
050: import java.io.IOException;
051: import java.io.InputStream;
052: import java.io.InputStreamReader;
053: import java.io.OutputStream;
054: import java.io.PrintWriter;
055: import java.io.Reader;
056: import java.io.Writer;
057: import java.util.HashSet;
058: import java.util.Iterator;
059: import java.util.Map;
060: import java.util.Set;
061: import java.util.StringTokenizer;
062: import java.util.TreeSet;
063: import java.util.zip.GZIPInputStream;
064: import java.util.zip.GZIPOutputStream;
065: import java.util.zip.ZipEntry;
066: import java.util.zip.ZipOutputStream;
067:
068: import de.anomic.kelondro.kelondroRow;
069: import de.anomic.kelondro.kelondroRowSet;
070: import de.anomic.tools.nxTools;
071:
072: public final class serverFileUtils {
073:
074: private static final int DEFAULT_BUFFER_SIZE = 4096;
075:
076: public static long copy(InputStream source, OutputStream dest)
077: throws IOException {
078: return copy(source, dest, -1);
079: }
080:
081: /**
082: * Copies an InputStream to an OutputStream.
083: * @param source InputStream
084: * @param dest OutputStream
085: * @param count the total amount of bytes to copy
086: * @return Total number of bytes copied.
087: *
088: * @see #copy(InputStream source, File dest)
089: * @see #copyRange(File source, OutputStream dest, int start)
090: * @see #copy(File source, OutputStream dest)
091: * @see #copy(File source, File dest)
092: */
093: public static long copy(InputStream source, OutputStream dest,
094: long count) throws IOException {
095: byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
096: int chunkSize = (int) ((count > 0) ? Math.min(count,
097: DEFAULT_BUFFER_SIZE) : DEFAULT_BUFFER_SIZE);
098:
099: int c;
100: long total = 0;
101: while ((c = source.read(buffer, 0, chunkSize)) > 0) {
102: dest.write(buffer, 0, c);
103: dest.flush();
104: total += c;
105:
106: if (count > 0) {
107: chunkSize = (int) Math.min(count - total,
108: DEFAULT_BUFFER_SIZE);
109: if (chunkSize == 0)
110: break;
111: }
112:
113: }
114: dest.flush();
115:
116: return total;
117: }
118:
119: public static int copy(File source, String inputCharset, Writer dest)
120: throws IOException {
121: InputStream fis = null;
122: try {
123: fis = new FileInputStream(source);
124: return copy(fis, dest, inputCharset);
125: } finally {
126: if (fis != null)
127: try {
128: fis.close();
129: } catch (Exception e) {
130: }
131: }
132: }
133:
134: public static int copy(InputStream source, Writer dest,
135: String inputCharset) throws IOException {
136: InputStreamReader reader = new InputStreamReader(source,
137: inputCharset);
138: return copy(reader, dest);
139: }
140:
141: public static int copy(String source, Writer dest)
142: throws IOException {
143: dest.write(source);
144: dest.flush();
145: return source.length();
146: }
147:
148: public static int copy(Reader source, Writer dest)
149: throws IOException {
150: char[] buffer = new char[4096];
151: int count = 0;
152: int n = 0;
153: try {
154: while (-1 != (n = source.read(buffer))) {
155: dest.write(buffer, 0, n);
156: count += n;
157: }
158: } catch (Exception e) {
159: // an "sun.io.MalformedInputException: Missing byte-order mark" - exception may occur here
160: throw new IOException(e.getMessage());
161: }
162: return count;
163: }
164:
165: public static void copy(InputStream source, File dest)
166: throws IOException {
167: copy(source, dest, -1);
168: }
169:
170: /**
171: * Copies an InputStream to a File.
172: * @param source InputStream
173: * @param dest File
174: * @param the amount of bytes to copy
175: * @see #copy(InputStream source, OutputStream dest)
176: * @see #copyRange(File source, OutputStream dest, int start)
177: * @see #copy(File source, OutputStream dest)
178: * @see #copy(File source, File dest)
179: */
180: public static void copy(InputStream source, File dest, long count)
181: throws IOException {
182: FileOutputStream fos = null;
183: try {
184: fos = new FileOutputStream(dest);
185: copy(source, fos, count);
186: } finally {
187: if (fos != null)
188: try {
189: fos.close();
190: } catch (Exception e) {
191: }
192: }
193: }
194:
195: /**
196: * Copies a part of a File to an OutputStream.
197: * @param source File
198: * @param dest OutputStream
199: * @param start Number of bytes to skip from the beginning of the File
200: * @see #copy(InputStream source, OutputStream dest)
201: * @see #copy(InputStream source, File dest)
202: * @see #copy(File source, OutputStream dest)
203: * @see #copy(File source, File dest)
204: */
205: public static void copyRange(File source, OutputStream dest,
206: int start) throws IOException {
207: InputStream fis = null;
208: try {
209: fis = new FileInputStream(source);
210: long skipped = fis.skip(start);
211: if (skipped != start)
212: throw new IllegalStateException("Unable to skip '"
213: + start + "' bytes. Only '" + skipped
214: + "' bytes skipped.");
215: copy(fis, dest, -1);
216: } finally {
217: if (fis != null)
218: try {
219: fis.close();
220: } catch (Exception e) {
221: }
222: }
223: }
224:
225: /**
226: * Copies a File to an OutputStream.
227: * @param source File
228: * @param dest OutputStream
229: * @see #copy(InputStream source, OutputStream dest)
230: * @see #copy(InputStream source, File dest)
231: * @see #copyRange(File source, OutputStream dest, int start)
232: * @see #copy(File source, File dest)
233: */
234: public static void copy(File source, OutputStream dest)
235: throws IOException {
236: InputStream fis = null;
237: try {
238: fis = new FileInputStream(source);
239: copy(fis, dest, -1);
240: } finally {
241: if (fis != null)
242: try {
243: fis.close();
244: } catch (Exception e) {
245: }
246: }
247: }
248:
249: public static void copy(File source, File dest) throws IOException {
250: copy(source, dest, -1);
251: }
252:
253: /**
254: * Copies a File to a File.
255: * @param source File
256: * @param dest File
257: * @param count the amount of bytes to copy
258: * @see #copy(InputStream source, OutputStream dest)
259: * @see #copy(InputStream source, File dest)
260: * @see #copyRange(File source, OutputStream dest, int start)
261: * @see #copy(File source, OutputStream dest)
262: */
263: public static void copy(File source, File dest, long count)
264: throws IOException {
265: FileInputStream fis = null;
266: FileOutputStream fos = null;
267: try {
268: fis = new FileInputStream(source);
269: fos = new FileOutputStream(dest);
270: copy(fis, fos, count);
271: } finally {
272: if (fis != null)
273: try {
274: fis.close();
275: } catch (Exception e) {
276: }
277: if (fos != null)
278: try {
279: fos.close();
280: } catch (Exception e) {
281: }
282: }
283: }
284:
285: public static byte[] read(InputStream source) throws IOException {
286: return read(source, -1);
287: }
288:
289: public static byte[] read(InputStream source, long count)
290: throws IOException {
291: ByteArrayOutputStream baos = (count > 0) ? new ByteArrayOutputStream(
292: (int) count)
293: : new ByteArrayOutputStream();
294: copy(source, baos, count);
295: baos.close();
296:
297: // convert Stream into array
298: return baos.toByteArray();
299: }
300:
301: public static byte[] read(File source) throws IOException {
302: byte[] buffer = new byte[(int) source.length()];
303: InputStream fis = null;
304: try {
305: fis = new FileInputStream(source);
306: int p = 0, c;
307: while ((c = fis.read(buffer, p, buffer.length - p)) > 0)
308: p += c;
309: } finally {
310: if (fis != null)
311: try {
312: fis.close();
313: } catch (Exception e) {
314: }
315: }
316: return buffer;
317: }
318:
319: public static byte[] readAndZip(File source) throws IOException {
320: ByteArrayOutputStream byteOut = null;
321: GZIPOutputStream zipOut = null;
322: try {
323: byteOut = new ByteArrayOutputStream(
324: (int) (source.length() / 2));
325: zipOut = new GZIPOutputStream(byteOut);
326: copy(source, zipOut);
327: zipOut.close();
328: return byteOut.toByteArray();
329: } finally {
330: if (zipOut != null)
331: try {
332: zipOut.close();
333: } catch (Exception e) {
334: }
335: if (byteOut != null)
336: try {
337: byteOut.close();
338: } catch (Exception e) {
339: }
340: }
341: }
342:
343: public static void writeAndGZip(byte[] source, File dest)
344: throws IOException {
345: FileOutputStream fos = null;
346: try {
347: fos = new FileOutputStream(dest);
348: writeAndGZip(source, fos);
349: } finally {
350: if (fos != null)
351: try {
352: fos.close();
353: } catch (Exception e) {
354: }
355: }
356: }
357:
358: public static void writeAndGZip(byte[] source, OutputStream dest)
359: throws IOException {
360: GZIPOutputStream zipOut = null;
361: try {
362: zipOut = new GZIPOutputStream(dest);
363: write(source, zipOut);
364: zipOut.close();
365: } finally {
366: if (zipOut != null)
367: try {
368: zipOut.close();
369: } catch (Exception e) {
370: }
371: }
372: }
373:
374: public static void write(String source, Writer dest)
375: throws IOException {
376: copy(source, dest);
377: }
378:
379: public static void write(byte[] source, OutputStream dest)
380: throws IOException {
381: copy(new ByteArrayInputStream(source), dest, -1);
382: }
383:
384: public static void write(byte[] source, File dest)
385: throws IOException {
386: copy(new ByteArrayInputStream(source), dest);
387: }
388:
389: /**
390: * This function determines if a byte array is gzip compressed and uncompress it
391: * @param source properly gzip compressed byte array
392: * @return uncompressed byte array
393: * @throws IOException
394: */
395: public static byte[] uncompressGZipArray(byte[] source)
396: throws IOException {
397: if (source == null)
398: return null;
399:
400: // support of gzipped data (requested by roland)
401: if ((source.length > 1)
402: && (((source[1] << 8) | source[0]) == GZIPInputStream.GZIP_MAGIC)) {
403: try {
404: ByteArrayInputStream byteInput = new ByteArrayInputStream(
405: source);
406: ByteArrayOutputStream byteOutput = new ByteArrayOutputStream();
407: GZIPInputStream zippedContent = new GZIPInputStream(
408: byteInput);
409: byte[] data = new byte[1024];
410: int read = 0;
411:
412: // reading gzip file and store it uncompressed
413: while ((read = zippedContent.read(data, 0, 1024)) != -1) {
414: byteOutput.write(data, 0, read);
415: }
416: zippedContent.close();
417: byteOutput.close();
418:
419: source = byteOutput.toByteArray();
420: } catch (Exception e) {
421: if (!e.getMessage().equals("Not in GZIP format")) {
422: throw new IOException(e.getMessage());
423: }
424: }
425: }
426:
427: return source;
428: }
429:
430: public static HashSet<String> loadList(File file) {
431: HashSet<String> set = new HashSet<String>();
432: BufferedReader br = null;
433: try {
434: br = new BufferedReader(new InputStreamReader(
435: new FileInputStream(file)));
436: String line;
437: while ((line = br.readLine()) != null) {
438: line = line.trim();
439: if ((line.length() > 0) && (!(line.startsWith("#"))))
440: set.add(line.trim().toLowerCase());
441: }
442: br.close();
443: } catch (IOException e) {
444: } finally {
445: if (br != null)
446: try {
447: br.close();
448: } catch (Exception e) {
449: }
450: }
451: return set;
452: }
453:
454: public static Map<String, String> loadHashMap(File f) {
455: // load props
456: try {
457: byte[] b = read(f);
458: return nxTools.table(nxTools.strings(b));
459: } catch (IOException e2) {
460: System.err.println("ERROR: " + f.toString()
461: + " not found in settings path");
462: return null;
463: }
464: }
465:
466: public static void saveMap(File file, Map<String, String> props,
467: String comment) throws IOException {
468: PrintWriter pw = null;
469: File tf = new File(file.toString() + "."
470: + (System.currentTimeMillis() % 1000));
471: pw = new PrintWriter(new BufferedOutputStream(
472: new FileOutputStream(tf)));
473: pw.println("# " + comment);
474: Iterator<Map.Entry<String, String>> i = props.entrySet()
475: .iterator();
476: String key, value;
477: Map.Entry<String, String> entry;
478: while (i.hasNext()) {
479: entry = i.next();
480: key = entry.getKey();
481: value = entry.getValue().replaceAll("\n", "\\\\n");
482: pw.println(key + "=" + value);
483: }
484: pw.println("# EOF");
485: pw.close();
486: file.delete();
487: tf.renameTo(file);
488: }
489:
490: public static Set<String> loadSet(File file, int chunksize,
491: boolean tree) throws IOException {
492: Set<String> set = (tree) ? (Set<String>) new TreeSet<String>()
493: : (Set<String>) new HashSet<String>();
494: byte[] b = read(file);
495: for (int i = 0; (i + chunksize) <= b.length; i++) {
496: set.add(new String(b, i, chunksize));
497: }
498: return set;
499: }
500:
501: public static Set<String> loadSet(File file, String sep,
502: boolean tree) throws IOException {
503: Set<String> set = (tree) ? (Set<String>) new TreeSet<String>()
504: : (Set<String>) new HashSet<String>();
505: byte[] b = read(file);
506: StringTokenizer st = new StringTokenizer(
507: new String(b, "UTF-8"), sep);
508: while (st.hasMoreTokens()) {
509: set.add(st.nextToken());
510: }
511: return set;
512: }
513:
514: public static void saveSet(File file, String format,
515: Set<String> set, String sep) throws IOException {
516: File tf = new File(file.toString() + ".tmp"
517: + (System.currentTimeMillis() % 1000));
518: OutputStream os = null;
519: if ((format == null) || (format.equals("plain"))) {
520: os = new BufferedOutputStream(new FileOutputStream(tf));
521: } else if (format.equals("gzip")) {
522: os = new GZIPOutputStream(new FileOutputStream(tf));
523: } else if (format.equals("zip")) {
524: ZipOutputStream zos = new ZipOutputStream(
525: new FileOutputStream(file));
526: String name = file.getName();
527: if (name.endsWith(".zip"))
528: name = name.substring(0, name.length() - 4);
529: zos.putNextEntry(new ZipEntry(name + ".txt"));
530: os = zos;
531: }
532: for (Iterator<String> i = set.iterator(); i.hasNext();) {
533: os.write((i.next().toString()).getBytes());
534: if (sep != null)
535: os.write(sep.getBytes());
536: }
537: os.close();
538: file.delete();
539: tf.renameTo(file);
540: }
541:
542: public static void saveSet(File file, String format,
543: kelondroRowSet set, String sep) throws IOException {
544: File tf = new File(file.toString() + ".tmp"
545: + (System.currentTimeMillis() % 1000));
546: OutputStream os = null;
547: if ((format == null) || (format.equals("plain"))) {
548: os = new BufferedOutputStream(new FileOutputStream(tf));
549: } else if (format.equals("gzip")) {
550: os = new GZIPOutputStream(new FileOutputStream(tf));
551: } else if (format.equals("zip")) {
552: ZipOutputStream zos = new ZipOutputStream(
553: new FileOutputStream(file));
554: String name = file.getName();
555: if (name.endsWith(".zip"))
556: name = name.substring(0, name.length() - 4);
557: zos.putNextEntry(new ZipEntry(name + ".txt"));
558: os = zos;
559: }
560: Iterator<kelondroRow.Entry> i = set.rows();
561: String key;
562: if (i.hasNext()) {
563: key = new String(i.next().getColBytes(0));
564: os.write(key.getBytes());
565: }
566: while (i.hasNext()) {
567: key = new String(((kelondroRow.Entry) i.next())
568: .getColBytes(0));
569: if (sep != null)
570: os.write(sep.getBytes());
571: os.write(key.getBytes());
572: }
573: os.close();
574: file.delete();
575: tf.renameTo(file);
576: }
577:
578: /**
579: * Moves all files from a directory to another.
580: * @param from_dir Directory which contents will be moved.
581: * @param to_dir Directory to move into. It must exist already.
582: */
583: public static void moveAll(File from_dir, File to_dir) {
584: if (!(from_dir.isDirectory()))
585: return;
586: if (!(to_dir.isDirectory()))
587: return;
588: String[] list = from_dir.list();
589: for (int i = 0; i < list.length; i++)
590: (new File(from_dir, list[i])).renameTo(new File(to_dir,
591: list[i]));
592: }
593:
594: public static void main(String[] args) {
595: try {
596: writeAndGZip("ein zwei drei, Zauberei".getBytes(),
597: new File("zauberei.txt.gz"));
598: } catch (IOException e) {
599: e.printStackTrace();
600: }
601: }
602: }
|