Se necesitaba un gran lote de datos hace algún tiempo. DBA proporcionó archivos CVS, pero cada archivo CVS tiene un tamaño de varios GB, por lo que se carga directamente. La base de datos es muy lenta y causará memoria insuficiente. Para realizar esta función, se escribió un programa para dividir rápidamente los archivos.
importar org.apache.log4j.logmanager; import org.apache.log4j.logger; import java.io.*; import java.util.*; import java.util.concurrent.*; Public Class Files PlitUtil {private final static logger log = logManager.getLogger (filesplitUtil.class); Private static final Long OriginFilesize = 1024 * 1024 * 100; // 100m Private static final int blockfilesize = 1024 * 1024 * 64; // Para evitar que los chinos sean confusos, debe tomar 2 a la n potencia/ ** * separador de archivos CVS */ privado estático final de bar cvsseparator = '^'; public static void main (string args []) {long start = system.currentTimemillis (); intente {String filename = "d: //csvtest//aa.csv"; Archivo SourceFile = nuevo archivo (nombre de archivo); if (fuenteFile.Length ()> = OriginFilesize) {String CVSFileName = FileName.ReplaceAll ("////", "/"); FileSplitUtil Files PlitUtil = new Files PlitUtil (); List <String> Parts = FileSplitUtil.SplitBySize (CVSFileName, blockFilesize); for (parte de cadena: piezas) {system.out.println ("El nombre de la partida es:"+parte); }} System.out.println ("Longitud total del archivo" + SourceFile.length () + ", tiempo para dividir el archivo:" + (System.CurrentTimemillis () - Start) + "Ms."); } catch (excepción e) {log.info (e.getStackTrace ()); }} / *** File dividido** @param nombre de archivo El nombre de archivo completo que se dividirá* @param bytesize dividido por cuántos bytes* @return lista de nombres de archivo divididos* / lista pública <string> splitBySize (string fileName, int bytesize) lanza IoException, interrumpedException {list> Parts = New ARRAYLIST <String> (); Archivo archivo = nuevo archivo (nombre de archivo); int count = (int) Math.ceil (file.length () / (doble) bytesize); int countlen = (count + "") .length (); RandomAccessFile RAF = new RandomAccessFile (nombre de archivo, "r"); Long Totallen = raf.length (); CountdownLatch Latch = new CountdownLatch (Count); for (int i = 0; i <count; i ++) {string partfileName = file.getPath ()+"." + LeftPad ((i + 1) + "", cutlen, '0') + ".cvs"; int readSize = bytesize; startPos largo = (largo) i * bytesize; long nextPos = (largo) (i+1) * bytesize; if (nextPos> totallen) {readSize = (int) (Totallen-startPos); } new SplitRunnable (ReadSize, StartPos, PartFileName, File, Latch) .run (); Parts.Add (PartFileName); } latch.await (); // Esperando que se escriban todos los archivos // las líneas se pueden cortar durante el corte, y todos los archivos divididos pueden procesarse, Mergew (Parts); piezas de devolución; } / ** * Procesamiento de segmento runnable * * @author Supeidong * / private class splitRunnable implements runnable {int bytesize; Cadena PartFileName; Archivo OriginFile; Largo startPos; CountdownLatch Latch; public splitRunnable (int bytesize, long startPos, string partfileName, archivo originfile, countdownLatch latch) {this.startpos = startPos; this.bytesize = bytesize; this.PartFileName = PartFileName; this.originFile = OriginFile; this.latch = Latch; } public void run () {randomAccessFile rfile; OutputStream OS; intente {rfile = new RandomAccessFile (OriginFile, "R"); byte [] b = nuevo byte [bytesize]; rfile.seek (startpos); // mover el puntero al comienzo de cada "segmento" int s = rfile.read (b); OS = nuevo FileOutputStream (PartFileName); OS.Write (b, 0, s); OS.Flush (); os.close (); Latch.CountDown (); } catch (ioException e) {log.error (e.getMessage ()); Latch.CountDown (); }}} / ** * Merge Cut Lines * * @param Parts * / private void mergerow (list <string> Parts) {list <tartFile> PartsFiles = new ArrayList <PartFile> (); Pruebe {// ensamble el objeto de tabla dividida para (int i = 0; i <parts.size (); i ++) {string partfileName = parts.get (i); Archivo SplitFileTemp = nuevo archivo (PartFileName); if (splitFileTemp.Exists ()) {PartFile PartFile = new PartFile (); BufferedReader Reader = new BufferedReader (new InputStreamReader (new FileInputStream (SplitFiletEmp), "GBK")); String FirStrow = Reader.ReadLine (); Cadena SecondRow = Reader.ReadLine (); Cadena endRow = readLastline (PartFileName); PartFile.SetPartFileName (PartFileName); PartFile.SetFirStrow (FirStrow); PartFile.SetEndrow (Endrow); if (i> = 1) {String PreparartFile = Parts.get (i - 1); String preendrow = readLastline (preparartfile); PartFile.SetFirStisfull (getCharCount (FirStrow+PREENDROW)> GetCharCount (SecondRow)); } PartFiles.Add (PartFile); lector.close (); }} // Escriba las líneas que deben fusionarse para (int i = 0; i <partfiles.size () - 1; i ++) {PartFile PartFile = PartFiles.get (i); PartFile PartFileNext = PartFiles.get (i + 1); StringBuilder sb = new StringBuilder (); if (partfileNext.getFirStisFull ()) {sb.append ("/r/n"); sb.append (PartFileNext.getFirStrow ()); } else {sb.append (PartFileNext.getFirStrow ()); } WriteLastline (partfile.getPartFileName (), sb.ToString ()); }} capt (excepción e) {log.error (e.getMessage ()); }} / ** * Obtenga el número de veces que aparece un personaje * @param s * @return * / private int getCharCount (String s) {int count = 0; for (int i = 0; i <s.length (); i ++) {if (s.charat (i) == cvsseparator) {count ++; }} return Count; } / ** * Use BufferedInputStream para leer el número de líneas de archivo * * @param FileName * @return * / public int getFilerow (String fileName) lanza ioexception {inputStream IS = new BufferedInputStream (nuevo FileInputStream (FileName)); byte [] c = nuevo byte [1024]; int count = 0; int readchars = 0; while ((readchars = is.read (c))! = -1) {for (int i = 0; i <readchars; ++ i) {if (c [i] == '/n') ++ Count; }} is.close (); recuento de retorno; } / ** * Lea la última línea de datos * @param FileName * @return * @throws ioexception * / private string readLastline (string filename) lanza ioexception {// use randomAccessFile, encuentre la última línea de datos desde detrás de RandomAccessFile Raf = New RandomAcessfile (FileName, "r"); long len = raf.length (); Cadena lastline = ""; if (len! = 0l) {long pos = len - 1; while (pos> 0) {pos--; raf.seek (pos); if (raf.readbyte () == '/n') {lastline = raf.readline (); lastline = new String (lastline.getBytes ("8859_1"), "gbk"); romper; }}}} raf.close (); regresar Última línea; } / ** * Modifique la última línea de datos * @param FileName * @param LastString * @return * @throws ioException * / private void writeLastline (string fileName, string laststring) {try {// Abra una secuencia de archivos de acceso aleatorio y lea y escriba según el método de lectura y redacción aleatorial aleatorsfile = new RandomAsfile (new RandomAsfile (FileName, ",", ");" ");", "); // Longitud del archivo, número de bytes largos fileLength = randomFile.length (); // Mueve el puntero del archivo de escritura al final del archivo. RandomFile.seek (Filelength); // GBK debe agregarse aquí, de lo contrario, confusión RandomFile.Write (laststring.getBytes ("GBK")); randomFile.close (); } catch (ioException e) {log.error (e.getMessage ()); }} / ** * Left Fill * * @param str * @param longitud * @param ch * @return * / public static string LeftPad (string str, int long, int ch) {if (str.length ()> = longitud) {return str; } char [] chs = nuevo char [longitud]; Matrices. Completar (CHS, CH); char [] src = str.toCarArray (); System.ArrayCopy (Src, 0, CHS, Longitud - Src.Length, Src.Length); devolver una nueva cadena (CHS); } / *** Fusionar File Line Interna Clase* / class PartFile {private String PartFileName; cadena privada Firstrow; cadena privada Endrow; booleano privado primero; public String getPartFileName () {return PartFileName; } public void setPartFileName (String PartFileName) {this.PartFileName = PartFileName; } public String getFirStrow () {return firstrow; } public void setFirStrow (String FirStrow) {this.firStrow = FirStrow; } public String getEndRow () {return endRow; } public void setEdrow (String EndRow) {this.endrow = endrow; } public boolean getFirstisfulL () {return firstisfull; } public void setFirstisfull (boolean firstisfull) {this.firstisfull = firstisfull; }}}Lo anterior se trata de este artículo, espero que sea útil para todos aprender la programación de Java.