मुझे जावा का उपयोग करके लाइन द्वारा लगभग 5-6 जीबी की एक बड़ी पाठ फ़ाइल पढ़ने की आवश्यकता है।
मैं इसे जल्दी कैसे कर सकता हूं?
मुझे जावा का उपयोग करके लाइन द्वारा लगभग 5-6 जीबी की एक बड़ी पाठ फ़ाइल पढ़ने की आवश्यकता है।
मैं इसे जल्दी कैसे कर सकता हूं?
जवाबों:
एक सामान्य पैटर्न का उपयोग करना है
try (BufferedReader br = new BufferedReader(new FileReader(file))) {
String line;
while ((line = br.readLine()) != null) {
// process the line.
}
}
यदि आप मानते हैं कि कोई वर्ण एन्कोडिंग नहीं है, तो आप डेटा को तेजी से पढ़ सकते हैं। जैसे ASCII-7 लेकिन इससे बहुत फर्क नहीं पड़ेगा। यह अत्यधिक संभावना है कि आप डेटा के साथ क्या करते हैं, इसमें अधिक समय लगेगा।
EDIT: एक कम सामान्य पैटर्न का उपयोग करने के लिए जो line
लीक होने की गुंजाइश से बचा जाता है ।
try(BufferedReader br = new BufferedReader(new FileReader(file))) {
for(String line; (line = br.readLine()) != null; ) {
// process the line.
}
// line is not visible here.
}
अद्यतन: जावा 8 में आप कर सकते हैं
try (Stream<String> stream = Files.lines(Paths.get(fileName))) {
stream.forEach(System.out::println);
}
नोट: आपको यह सुनिश्चित करने के लिए कि # पर विधि को कॉल किया गया है, को सुनिश्चित करने के लिए एक कोशिश के साथ संसाधन ब्लॉक में स्ट्रीम रखना होगा, अन्यथा अंतर्निहित फ़ाइल हैंडल कभी भी बंद नहीं होता है जब तक कि जीसी इसे बहुत बाद में नहीं करता है।
for(String line = br.readLine(); line != null; line = br.readLine())
Btw क्यों नहीं , जावा 8 में आप वह कर सकते हैं try( Stream<String> lines = Files.lines(...) ){ for( String line : (Iterable<String>) lines::iterator ) { ... } }
जो नफरत नहीं करना मुश्किल है।
इस ब्लॉग को देखें:
बफर आकार निर्दिष्ट किया जा सकता है, या डिफ़ॉल्ट आकार का उपयोग किया जा सकता है। अधिकांश उद्देश्यों के लिए डिफ़ॉल्ट काफी बड़ा है।
// Open the file
FileInputStream fstream = new FileInputStream("textfile.txt");
BufferedReader br = new BufferedReader(new InputStreamReader(fstream));
String strLine;
//Read File Line By Line
while ((strLine = br.readLine()) != null) {
// Print the content on the console
System.out.println (strLine);
}
//Close the input stream
fstream.close();
DataInputStream
, और गलत धारा बंद है। जावा ट्यूटोरियल के साथ कुछ भी गलत नहीं है, और इस तरह से मनमाने तीसरे पक्ष के इंटरनेट बकवास का हवाला देने की आवश्यकता नहीं है।
एक बार जावा 8 बाहर हो जाने के बाद (मार्च 2014) आप धाराओं का उपयोग कर पाएंगे:
try (Stream<String> lines = Files.lines(Paths.get(filename), Charset.defaultCharset())) {
lines.forEachOrdered(line -> process(line));
}
फ़ाइल की सभी पंक्तियों को प्रिंट करना:
try (Stream<String> lines = Files.lines(file, Charset.defaultCharset())) {
lines.forEachOrdered(System.out::println);
}
StandardCharsets.UTF_8
, Stream<String>
संक्षिप्तता के लिए उपयोग करें , और उपयोग करने से बचें forEach()
और खासकर forEachOrdered()
जब तक कि कोई कारण न हो।
forEach(this::process)
, लेकिन यह बदसूरत हो जाता है अगर आप कोड के ब्लॉक को लैम्ब्डा के रूप में लिखते हैं forEach()
।
forEachOrdered
इन-ऑर्डर निष्पादित करने के लिए आवश्यक है। ध्यान रखें कि आप उस स्थिति में धारा को समानांतर करने में सक्षम नहीं होंगे, हालांकि मैंने पाया है कि जब तक फ़ाइल में हजारों लाइनें न हों, तब तक समानांतरकरण चालू नहीं होता है।
यहां प्री-जावा 7 के लिए फुल एरर हैंडलिंग और सपोर्टिंग चारसेट स्पेसिफिकेशन के साथ एक सैंपल दिया गया है। जावा 7 के साथ आप ट्राई-विथ रिसोर्सेज सिंटैक्स का उपयोग कर सकते हैं, जो कोड क्लीनर बनाता है।
यदि आप केवल डिफ़ॉल्ट चारसेट चाहते हैं तो आप InputStream को छोड़ सकते हैं और FileReader का उपयोग कर सकते हैं।
InputStream ins = null; // raw byte-stream
Reader r = null; // cooked reader
BufferedReader br = null; // buffered for readLine()
try {
String s;
ins = new FileInputStream("textfile.txt");
r = new InputStreamReader(ins, "UTF-8"); // leave charset out for default
br = new BufferedReader(r);
while ((s = br.readLine()) != null) {
System.out.println(s);
}
}
catch (Exception e)
{
System.err.println(e.getMessage()); // handle exception
}
finally {
if (br != null) { try { br.close(); } catch(Throwable t) { /* ensure close happens */ } }
if (r != null) { try { r.close(); } catch(Throwable t) { /* ensure close happens */ } }
if (ins != null) { try { ins.close(); } catch(Throwable t) { /* ensure close happens */ } }
}
यहां ग्रूवी संस्करण है, पूरी त्रुटि से निपटने के साथ:
File f = new File("textfile.txt");
f.withReader("UTF-8") { br ->
br.eachLine { line ->
println line;
}
}
ByteArrayInputStream
एक स्ट्रिंग द्वारा खिलाया एक बड़े पाठ फ़ाइल को पढ़ने के साथ क्या करना है शाब्दिक?
जावा 8 में, आप कर सकते हैं:
try (Stream<String> lines = Files.lines (file, StandardCharsets.UTF_8))
{
for (String line : (Iterable<String>) lines::iterator)
{
;
}
}
कुछ नोट: धारा Files.lines
(अधिकांश धाराओं के विपरीत) लौटा दी जानी चाहिए। यहाँ उल्लिखित कारणों से मैं उपयोग करने से बचता हूँ forEach()
। अजीब कोड (Iterable<String>) lines::iterator
एक स्ट्रीम को एक Iterable में डाल देता है।
Iterable
इस कोड को लागू नहीं करने से निश्चित रूप से उपयोगी हालांकि बदसूरत है। इसे काम करने के लिए एक कास्ट (यानी (Iterable<String>)
) की जरूरत है ।
for(String line : (Iterable<String>) lines.skip(1)::iterator)
Stream
सुविधाओं का उपयोग Files.newBufferedReader
करने का इरादा नहीं कर रहे हैं , तो इसके बजाय Files.lines
बार-बार कॉल करने का उपयोग करें readLine()
जब तक कि null
निर्माण का उपयोग करने के बजाय (Iterable<String>) lines::iterator
बहुत सरल प्रतीत न हो ...
आप क्या कर सकते हैं स्कैनर का उपयोग करके पूरे पाठ को स्कैन करें और पंक्ति द्वारा पाठ पंक्ति के माध्यम से जाएं। बेशक आपको निम्नलिखित आयात करना चाहिए:
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public static void readText throws FileNotFoundException {
Scanner scan = new Scanner(new File("samplefilename.txt"));
while(scan.hasNextLine()){
String line = scan.nextLine();
//Here you can manipulate the string the way you want
}
}
स्कैनर मूल रूप से सभी पाठ को स्कैन करता है। जबकि पूरे पाठ को पार करने के लिए लूप का उपयोग किया जाता है।
.hasNextLine()
समारोह एक बूलियन यह सच रिटर्न अगर वहाँ पाठ में अभी भी और अधिक लाइनें हैं है। .nextLine()
समारोह आप एक स्ट्रिंग है जिसे आप जिस तरह से आप चाहते हैं का उपयोग कर सकते के रूप में एक पूरी लाइन देता है। System.out.println(line)
पाठ मुद्रित करने का प्रयास करें।
साइड नोट: .txt फाइल टाइप टेक्स्ट है।
BufferedReader.readLine()
, और उसने सबसे अच्छा प्रदर्शन करने की विधि पूछी।
FileReader आपको एन्कोडिंग निर्दिष्ट करने की अनुमति नहीं देगा, InputStreamReader
यदि आपको इसे निर्दिष्ट करने की आवश्यकता है , तो इसका उपयोग करें:
try {
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(filePath), "Cp1252"));
String line;
while ((line = br.readLine()) != null) {
// process the line.
}
br.close();
} catch (IOException e) {
e.printStackTrace();
}
यदि आपने इस फ़ाइल को Windows से आयात किया है, तो इसमें ANSI एन्कोडिंग (Cp1252) हो सकती है, इसलिए आपको एन्कोडिंग निर्दिष्ट करना होगा।
मैंने जावा में एक फ़ाइल को पढ़ने के लिए 10 अलग-अलग तरीकों का दस्तावेजीकरण और परीक्षण किया और फिर उन्हें 1KB से 1GB तक की परीक्षण फ़ाइलों में पढ़ाकर एक-दूसरे के खिलाफ चलाया। यहां 1GB परीक्षण फ़ाइल पढ़ने के लिए सबसे तेज़ 3 फ़ाइल पढ़ने के तरीके हैं।
ध्यान दें कि प्रदर्शन परीक्षण चलाते समय मैंने कंसोल को कुछ भी आउटपुट नहीं किया था क्योंकि यह वास्तव में परीक्षण को धीमा कर देगा। मैं सिर्फ कच्चे पढ़ने की गति का परीक्षण करना चाहता था।
1) java.nio.file.Files.readAllBytes ()
जावा 7, 8, 9 में परीक्षण किया गया। यह कुल मिलाकर सबसे तेज़ तरीका था। 1GB फ़ाइल पढ़ना केवल 1 सेकंड के नीचे लगातार था।
import java.io..File;
import java.io.IOException;
import java.nio.file.Files;
public class ReadFile_Files_ReadAllBytes {
public static void main(String [] pArgs) throws IOException {
String fileName = "c:\\temp\\sample-1GB.txt";
File file = new File(fileName);
byte [] fileBytes = Files.readAllBytes(file.toPath());
char singleChar;
for(byte b : fileBytes) {
singleChar = (char) b;
System.out.print(singleChar);
}
}
}
2) java.nio.file.Files.lines ()
यह जावा 8 और 9 में सफलतापूर्वक परीक्षण किया गया था लेकिन यह लैम्ब्डा अभिव्यक्ति के लिए समर्थन की कमी के कारण जावा 7 में काम नहीं करेगा। 1GB फ़ाइल में पढ़ने में लगभग 3.5 सेकंड का समय लगता है जो इसे बड़ी फ़ाइलों को पढ़ने के बाद दूसरे स्थान पर रखता है।
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.stream.Stream;
public class ReadFile_Files_Lines {
public static void main(String[] pArgs) throws IOException {
String fileName = "c:\\temp\\sample-1GB.txt";
File file = new File(fileName);
try (Stream linesStream = Files.lines(file.toPath())) {
linesStream.forEach(line -> {
System.out.println(line);
});
}
}
}
3) बफ़रडेडर
जावा 7, 8, 9 में काम करने के लिए परीक्षण किया गया। 1GB परीक्षण फ़ाइल में पढ़ने के लिए लगभग 4.5 सेकंड लगते हैं।
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class ReadFile_BufferedReader_ReadLine {
public static void main(String [] args) throws IOException {
String fileName = "c:\\temp\\sample-1GB.txt";
FileReader fileReader = new FileReader(fileName);
try (BufferedReader bufferedReader = new BufferedReader(fileReader)) {
String line;
while((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
}
}
आप यहां सभी 10 फ़ाइल पढ़ने के तरीकों के लिए पूरी रैंकिंग पा सकते हैं ।
System.out.print/println()
यहाँ ज्यादातर समय कर रहे हैं; आप यह भी मान रहे हैं कि फ़ाइल आपके पहले दो मामलों में मेमोरी में फिट हो जाएगी।
जावा 7 में:
String folderPath = "C:/folderOfMyFile";
Path path = Paths.get(folderPath, "myFileName.csv"); //or any text file eg.: txt, bat, etc
Charset charset = Charset.forName("UTF-8");
try (BufferedReader reader = Files.newBufferedReader(path , charset)) {
while ((line = reader.readLine()) != null ) {
//separate all csv fields into string array
String[] lineVariables = line.split(",");
}
} catch (IOException e) {
System.err.println(e);
}
StandardCharsets.UTF_8
चेक किए गए अपवाद से बचने के लिए उपयोग करेंCharset.forName("UTF-8")
जावा 8 में, उपयोग करने का एक विकल्प भी है Files.lines()
। यदि आपका इनपुट स्रोत एक फ़ाइल नहीं है, लेकिन एक Reader
या अधिक की तरह कुछ अमूर्त है InputStream
, तो आप एस विधि के माध्यम से लाइनों को स्ट्रीम कर सकते हैं ।BufferedReader
lines()
उदाहरण के लिए:
try (BufferedReader reader = new BufferedReader(...)) {
reader.lines().forEach(line -> processLine(line));
}
processLine()
द्वारा पढ़ी गई प्रत्येक इनपुट लाइन के लिए कॉल करेगा BufferedReader
।
जावा 8 के साथ एक फ़ाइल पढ़ने के लिए
package com.java.java8;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.stream.Stream;
/**
* The Class ReadLargeFile.
*
* @author Ankit Sood Apr 20, 2017
*/
public class ReadLargeFile {
/**
* The main method.
*
* @param args
* the arguments
*/
public static void main(String[] args) {
try {
Stream<String> stream = Files.lines(Paths.get("C:\\Users\\System\\Desktop\\demoData.txt"));
stream.forEach(System.out::println);
}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
आप स्कैनर वर्ग का उपयोग कर सकते हैं
Scanner sc=new Scanner(file);
sc.nextLine();
Scanner
ठीक है, लेकिन इस उत्तर में इसे ठीक से उपयोग करने के लिए पूर्ण कोड शामिल नहीं है।
BufferedReader.readLine()
निश्चित रूप से उपवास के रूप में कई बार है। अगर आपको लगता है तो कृपया अपने कारण प्रदान करें।
आपको readLine()
विधि का उपयोग करने की आवश्यकता है class BufferedReader
। उस वर्ग से एक नई वस्तु बनाएं और उस पर इस विधि को संचालित करें और इसे एक स्ट्रिंग में सहेजें।
इसे प्राप्त करने का स्पष्ट तरीका,
उदाहरण के लिए:
यदि आपके पास dataFile.txt
अपनी वर्तमान निर्देशिका है
import java.io.*;
import java.util.Scanner;
import java.io.FileNotFoundException;
public class readByLine
{
public readByLine() throws FileNotFoundException
{
Scanner linReader = new Scanner(new File("dataFile.txt"));
while (linReader.hasNext())
{
String line = linReader.nextLine();
System.out.println(line);
}
linReader.close();
}
public static void main(String args[]) throws FileNotFoundException
{
new readByLine();
}
}
try (Stream<String> stream = Files.lines(Paths.get(fileName))) {
stream.forEach(System.out::println);
}
System.getProperty("os.name").equals("Linux")
==
!
BufferedReader br;
FileInputStream fin;
try {
fin = new FileInputStream(fileName);
br = new BufferedReader(new InputStreamReader(fin));
/*Path pathToFile = Paths.get(fileName);
br = Files.newBufferedReader(pathToFile,StandardCharsets.US_ASCII);*/
String line = br.readLine();
while (line != null) {
String[] attributes = line.split(",");
Movie movie = createMovie(attributes);
movies.add(movie);
line = br.readLine();
}
fin.close();
br.close();
} catch (FileNotFoundException e) {
System.out.println("Your Message");
} catch (IOException e) {
System.out.println("Your Message");
}
इससे मेरा काम बनता है। आशा है कि यह आपकी भी मदद करेगा।
आप इसे और अधिक सटीक रूप से करने के लिए धाराओं का उपयोग कर सकते हैं:
Files.lines(Paths.get("input.txt")).forEach(s -> stringBuffer.append(s);
मैं आमतौर पर पढ़ने की दिनचर्या को सीधा करता हूं:
void readResource(InputStream source) throws IOException {
BufferedReader stream = null;
try {
stream = new BufferedReader(new InputStreamReader(source));
while (true) {
String line = stream.readLine();
if(line == null) {
break;
}
//process line
System.out.println(line)
}
} finally {
closeQuiet(stream);
}
}
static void closeQuiet(Closeable closeable) {
if (closeable != null) {
try {
closeable.close();
} catch (IOException ignore) {
}
}
}
आप इस कोड का उपयोग कर सकते हैं:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
public class ReadTextFile {
public static void main(String[] args) throws IOException {
try {
File f = new File("src/com/data.txt");
BufferedReader b = new BufferedReader(new FileReader(f));
String readLine = "";
System.out.println("Reading file using Buffered Reader");
while ((readLine = b.readLine()) != null) {
System.out.println(readLine);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Org.apache.commons.io पैकेज का उपयोग करके , इसने अधिक प्रदर्शन दिया, विशेषकर विरासत कोड में जो जावा 6 और नीचे का उपयोग करता है।
जावा 7 में कम अपवादों और अधिक उपयोगी विधियों के साथ बेहतर एपीआई है:
LineIterator lineIterator = null;
try {
lineIterator = FileUtils.lineIterator(new File("/home/username/m.log"), "windows-1256"); // The second parameter is optionnal
while (lineIterator.hasNext()) {
String currentLine = lineIterator.next();
// Some operation
}
}
finally {
LineIterator.closeQuietly(lineIterator);
}
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
आप Apache Commons IO का भी उपयोग कर सकते हैं :
File file = new File("/home/user/file.txt");
try {
List<String> lines = FileUtils.readLines(file);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
FileUtils.readLines(file)
एक पदावनत विधि है। इसके अतिरिक्त, विधि आह्वान करती है IOUtils.readLines
, जो एक बफ़रड्रेडर और एरेलेलिस्ट का उपयोग करती है । यह एक लाइन-बाय-लाइन विधि नहीं है, और निश्चित रूप से ऐसा नहीं है जो कई जीबी पढ़ने के लिए व्यावहारिक होगा।