There is something wrong with GZIPInputStream or GZIPOutputStream. Just please read the following code (or run it and see what happens):
def main(a: Array[String]) {
val name = "test.dat"
new GZIPOutputStream(new FileOutputStream(name)).write(10)
println(new GZIPInputStream(new FileInputStream(name)).read())
}
It creates a file test.dat, writes a single byte 10 formatting by GZIP, and read the byte in the same file with the same format.
And this is what I got running it:
Exception in thread "main" java.io.EOFException: Unexpected end of ZLIB input stream
at java.util.zip.InflaterInputStream.fill(Unknown Source)
at java.util.zip.InflaterInputStream.read(Unknown Source)
at java.util.zip.GZIPInputStream.read(Unknown Source)
at java.util.zip.InflaterInputStream.read(Unknown Source)
at nbt.Test$.main(Test.scala:13)
at nbt.Test.main(Test.scala)
The reading line seems going the wrong way for some reason.
I googled the error Unexpected end of ZLIB input stream and found some bug reports to Oracle, which were issued around 2007-2010. So I guess the bug still remains in some way, but I'm not sure if my code is right, so let me post this here and listen to your advice. Thank you!
You have to call close() on the GZIPOutputStream before you attempt to read it. The final bytes of the file will only be written when the stream object is actually closed.
(This is irrespective of any explicit buffering in the output stack. The stream only knows to compress and write the last bytes when you tell it to close. A flush() won't help ... though calling finish() instead of close() should work. Look at the javadocs.)
Here's the correct code (in Java);
package test;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
public class GZipTest {
public static void main(String[] args) throws
FileNotFoundException, IOException {
String name = "/tmp/test";
GZIPOutputStream gz = new GZIPOutputStream(new FileOutputStream(name));
gz.write(10);
gz.close(); // Remove this to reproduce the reported bug
System.out.println(new GZIPInputStream(new FileInputStream(name)).read());
}
}
(I've not implemented resource management or exception handling / reporting properly as they are not relevant to the purpose of this code. Don't treat this as an example of "good code".)
Related
the code that i used :
package play;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
public class Play {
InputStream music;
public Play() {
URL url=getClass().getResource("/music/Whitewoods - College Kill Dream.mp3");
System.out.println(url.toString());
try {
FileInputStream fileInputStream=new FileInputStream(new File(url.toString()));
fileInputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String args[]) {
new Play();
}
}
the line below int he above code :
System.out.println(url.toString());
prints :
file:/C:/Users/eclipse-workspace/audioboard/bin/music/Whitewoods%20-%20College%20Kill%20Dream.mp3
if i copy this directly and put it in the chrome's url putting box . the file opens but the line :
FileInputStream fileInputStream=new FileInputStream(new File(url.toString()));
gives file not found error.
error stack:
java.io.FileNotFoundException: file:\C:\Users\eclipse-workspace\audioboard\bin\music\Whitewoods%20-%20College%20Kill%20Dream.mp3 (The filename, directory name, or volume label syntax is incorrect)
at java.base/java.io.FileInputStream.open0(Native Method)
at java.base/java.io.FileInputStream.open(FileInputStream.java:213)
at java.base/java.io.FileInputStream.<init>(FileInputStream.java:155)
at play.Play.<init>(Play.java:17)
at play.Play.main(Play.java:26)
thankyou for the help.
You can use the File constructor File(URI uri) transforming your URL url to URI and passing it as an argument for the File constructor like below:
File file = new File(url.toURI());
The file: bit makes what you see not actually a file path, but a URL.
URL has the toFile() method which is closer to what you want, but still isn't what you're actually looking for, which is getResourceAsStream:
The appropriate way to call getResource/getResourceAsStream, is Play.class.getResource, not getClass().getResource. A minor nit; the getClass() variant is non-idiomatic, and strictly worse/less readable: If Play is ever subclassed, it breaks, whereas Play.class.getResource would not. Even if it isn't relevant, better to use the style that is more idiomatic and the right answer is strictly more scenarios.
Generally, if you convert the resource you get into a file you've messed up; the point of getResource is to give you resources from the same place your classes are found, and they need not be files. They could be entries in a jar (which aren't, themselves, files, and cannot be accessed directly either as a java.io.File or as a java.nio.path.Path), pulled in over the network, generated on the fly - anything goes, that's the point of the abstraction. In this case, you're taking your file and immediately turning that into an InputStream. Don't do that - the getResource abstraction can do this.
Like all resources, you can't just open an inputstream like this. You need to ensure it is closed as well, regardless of what happens. Use try-with-resources to ensure this.
Putting it all together:
String songName = "Whitewoods - College Kill Dream.mp3";
try (var in = Play.class.getResourceAsStream("/music/" + songName)) {
// .... do something with 'in' here. It is an InputStream.
}
No need to close it; the try construct will take care of it for you. Doesn't matter how code 'exits' those braces (by running to the end of it, via return or some other control flow, or via an exception) - that inputstream will be closed.
To get a full idea, the project consists of a webpage with a download button that, when clicked, downloads a text file to the users computer. The webpage uses Javascript and PHP, which will call a Java AWS-Lambda function. The java grabs text from a database.
Originally, I had it working locally as so:
StreamFactory sf = StreamFactory.newInstance();
sf.loadResource("mapping.xml");
File file = new File("C:\\test.txt");
BeanWriter bw = sf.createWriter("export", file);
// beans written bellow
...
bw.write(recordName, bean);
However, due to the nature of using Lambda functions, I can't as easily save to the server as I could save to my local (would require SSH-ing in programatically, etc). In addition, my senior requested that I make my project not have to save files to the server, so we don't have to manage deleting them later.
I've now been attempting to do it like this:
StreamFactory sf = StreamFactory.newInstance();
sf.loadResource("mapping.xml");
OutputStreamWriter output;
BeanWriter bw = sf.createWriter("export", output);
// beans written bellow
...
bw.write(recordName, bean);
I've read that createWriter can use a writer instead of a file, but I don't understand how that could be utilized within the javascript side to download as a file. Currently, the code on that end is simple and looks like this:
Download
This project is not using servlets. My senior is adament about using AWS-Lambda and writing to a stream. It needs to use BeanIO. Most of the similar questions I've seen do not have these as challenges, so this question shouldn't be closed for being a duplicate.
I have no knowledge about AWS-Lambda, but googling got me to Leveraging Predefined Interfaces for Creating Handler (Java), specifically Example 2: Creating Handler with Stream Input/Output (Leverage the RequestStreamHandler Interface). From the article you could then use the Outputstream provided by the interface to write your response back to the user.
This would HOPEFULLY trigger something similar to a file download request and then the browser could either display the result or ask the user to save the response as a file on their computer.
Combining that with your code:
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
import org.beanio.BeanWriter;
import org.beanio.StreamFactory;
import com.amazonaws.services.lambda.runtime.RequestStreamHandler;
import com.amazonaws.services.lambda.runtime.Context;
public class HelloBeanIO implements RequestStreamHandler {
public void handleRequest(InputStream inputStream,
OutputStream outputStream,
Context context)
throws IOException {
StreamFactory sf = StreamFactory.newInstance();
sf.loadResource("mapping.xml");
// wrap the supplied OutputStream in a OutputStreamWriter
// and set the encoding you prefer
OutputStreamWriter writer = new OutputStreamWriter(outputStream,
StandardCharsets.UTF_8);
BeanWriter bw = sf.createWriter("export", writer);
// beans written bellow
...
bw.write(recordName, bean);
}
}
The important part is that you wrap the OutputStream passed into the method with a OutputStreamWriter.
There are most likely more things to do to get it working properly, somehow maybe setting the correct mime type for the response could change the behaviour of how the browser handles the response.
There is something wrong with GZIPInputStream or GZIPOutputStream. Just please read the following code (or run it and see what happens):
def main(a: Array[String]) {
val name = "test.dat"
new GZIPOutputStream(new FileOutputStream(name)).write(10)
println(new GZIPInputStream(new FileInputStream(name)).read())
}
It creates a file test.dat, writes a single byte 10 formatting by GZIP, and read the byte in the same file with the same format.
And this is what I got running it:
Exception in thread "main" java.io.EOFException: Unexpected end of ZLIB input stream
at java.util.zip.InflaterInputStream.fill(Unknown Source)
at java.util.zip.InflaterInputStream.read(Unknown Source)
at java.util.zip.GZIPInputStream.read(Unknown Source)
at java.util.zip.InflaterInputStream.read(Unknown Source)
at nbt.Test$.main(Test.scala:13)
at nbt.Test.main(Test.scala)
The reading line seems going the wrong way for some reason.
I googled the error Unexpected end of ZLIB input stream and found some bug reports to Oracle, which were issued around 2007-2010. So I guess the bug still remains in some way, but I'm not sure if my code is right, so let me post this here and listen to your advice. Thank you!
You have to call close() on the GZIPOutputStream before you attempt to read it. The final bytes of the file will only be written when the stream object is actually closed.
(This is irrespective of any explicit buffering in the output stack. The stream only knows to compress and write the last bytes when you tell it to close. A flush() won't help ... though calling finish() instead of close() should work. Look at the javadocs.)
Here's the correct code (in Java);
package test;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
public class GZipTest {
public static void main(String[] args) throws
FileNotFoundException, IOException {
String name = "/tmp/test";
GZIPOutputStream gz = new GZIPOutputStream(new FileOutputStream(name));
gz.write(10);
gz.close(); // Remove this to reproduce the reported bug
System.out.println(new GZIPInputStream(new FileInputStream(name)).read());
}
}
(I've not implemented resource management or exception handling / reporting properly as they are not relevant to the purpose of this code. Don't treat this as an example of "good code".)
This question already has answers here:
Non-blocking (NIO) reading of lines
(9 answers)
Unable to get and output .txt
(1 answer)
Closed 5 years ago.
I tried to read a txt file (with texts inside) in every lines .Then I will process the lines later .
Here is my work.
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.stream.Stream;
public class Fypio {
public static void main(String args[]) {
String fileName = "e://input.txt";
//read file into stream, try-with-resources
try (Stream<String> stream = Files.lines(Paths.get(fileName))) {
stream.forEach(System.out::println);
} catch (IOException e) {
e.printStackTrace();
}
}
}
However, I get the following error. I am definitely sure that the directory is correct though.
Error:
Exception in thread "main" java.io.UncheckedIOException: java.nio.charset.MalformedInputException: Input length = 1
at java.io.BufferedReader$1.hasNext(BufferedReader.java:574)
at java.util.Iterator.forEachRemaining(Iterator.java:115)
at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:580)
at fypio.Fypio.main(Fypio.java:21)
Caused by: java.nio.charset.MalformedInputException: Input length = 1
at java.nio.charset.CoderResult.throwException(CoderResult.java:281)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:339)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.BufferedReader.fill(BufferedReader.java:161)
at java.io.BufferedReader.readLine(BufferedReader.java:324)
at java.io.BufferedReader.readLine(BufferedReader.java:389)
at java.io.BufferedReader$1.hasNext(BufferedReader.java:571)
... 4 more
#Or any sample codes can be provided to read txt file by line ?
Update my txt files should be encoded with ANSI
MalformedInputException means your text file is not in the charset (encoding) you requested.
Although your code does not explicitly specify a charset, the Files.lines method always uses UTF-8:
Read all lines from a file as a Stream. Bytes from the file are decoded into characters using the UTF-8 charset.
Since your text file is not a UTF-8 text file, you’ll need to specify its charset in your code. If you aren’t sure, the file probably uses the system’s default charset:
try (Stream<String> stream = Files.lines(Paths.get(fileName), Charset.defaultCharset())) {
Update:
You have stated in a comment that your text file is “ANSI,” which is the (technically incorrect) name Windows uses for its one-byte charsets. On a US version of Windows, you’d probably want to use:
try (Stream<String> stream = Files.lines(Paths.get(fileName), Charset.forName("windows-1252"))) {
Why the program search the file:
File FILE_PATH = new File("C:\\Users\\home\\Desktop\\DbWord.txt");
System.out.println(FILE_PATH.exists());
System.out.println(FILE_PATH.getAbsoluteFile());
FileInputStream fIn = new FileInputStream(FILE_PATH);
Scanner reader = new Scanner(fIn);
at: C:\Users\home\Documents\NetBeansProjects\MyDatabase\C:\Users\home\Desktop\DbWord.txt
How can i counteract the default location?
If something in this post not good, please tell me and no negative vote.
Thanks!
why negative votes??????????????? whats your problems??????????
Please double check your error details. You might have seen something like the below error. Actually the program is not searching for the file "C:\Users\home\Documents\NetBeansProjects\MyDatabase\C:\Users\home\Desktop\DbWord.txt", it is trying to locate the file "C:\Users\home\Desktop\DbWord.txt" which does not exists in your machine. You are seeing "C:\Users\home\Documents\NetBeansProjects\MyDatabase\C:\Users\home\Desktop\DbWord.txt" along with the error because you have already used System.out.println(FILE_PATH.getAbsoluteFile()); statement in your code.
false
Exception in thread "main" java.io.FileNotFoundException: C:\Users\home\Desktop\DbWord.txt (The filename, directory name, or volume label syntax is incorrect)
at java.io.FileInputStream.open0(Native Method)
at java.io.FileInputStream.open(FileInputStream.java:195)
at java.io.FileInputStream.<init>(FileInputStream.java:138)
C:\Users\home\Documents\NetBeansProjects\MyDatabase\C:\Users\home\Desktop\DbWord.txt
at com.stackoverflow.answer.SimpleFileHelper.main(SimpleFileHelper.java:17)
Hope you are clear now.
There are three main chances where a FileNotFoundException may be thrown.
The named file does not exist.
The named file is actually a directory not file.
The named file cannot be opened for reading due to some reason.
The first two reasons are unlikely based on your description, please check the third point using file.canRead() method.
If the test above returns true, I would suspect the following:
You might have forgotten to explicitly throw or catch the potential exception (i.e., FileNotFoundExcetion). If you work in an IDE, you should have got some complaint from the compiler. But I suspect you didn't run your code in such an IDE.
Try the following code and see if the exception would be gone:
package com.stackoverflow.answer;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class SimpleFileHelper {
public static void main(String[] args) throws FileNotFoundException {
File FILE_PATH = new File("C:/Users/home/Desktop/DbWord.txt");
System.out.println(FILE_PATH.exists());
System.out.println(FILE_PATH.getAbsoluteFile());
FileInputStream fIn = new FileInputStream(FILE_PATH);
Scanner reader = new Scanner(fIn);
}
}